blob: 7b12358c997faef4757803e12d973a230875553b [file] [log] [blame]
Neels Hofmeyr00c06972017-01-31 01:19:27 +01001/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
2 * All Rights Reserved
3 *
4 * Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <stdio.h>
22#include <string.h>
Neels Hofmeyr6b883f72017-01-31 16:40:28 +010023#include <inttypes.h>
Neels Hofmeyr00c06972017-01-31 01:19:27 +010024
25#include <osmocom/core/application.h>
26#include <osmocom/core/utils.h>
27#include <osmocom/core/logging.h>
28
Neels Hofmeyr8cde6622017-01-31 02:10:40 +010029#include <osmocom/crypt/auth.h>
Neels Hofmeyr00c06972017-01-31 01:19:27 +010030
Neels Hofmeyr8cde6622017-01-31 02:10:40 +010031#include "logging.h"
32#include "auc.h"
33
34#define comment_start() fprintf(stderr, "\n===== %s\n", __func__);
Neels Hofmeyr00c06972017-01-31 01:19:27 +010035#define comment_end() fprintf(stderr, "===== %s: SUCCESS\n\n", __func__);
36
Neels Hofmeyr8cde6622017-01-31 02:10:40 +010037#define VERBOSE_ASSERT(val, expect_op, fmt) \
38 do { \
39 fprintf(stderr, #val " == " fmt "\n", (val)); \
40 OSMO_ASSERT((val) expect_op); \
41 } while (0);
42
Neels Hofmeyr6b883f72017-01-31 16:40:28 +010043char *vec_str(const struct osmo_auth_vector *vec)
Neels Hofmeyr8cde6622017-01-31 02:10:40 +010044{
45 static char buf[1024];
46 char *pos = buf;
47 char *end = buf + sizeof(buf);
48
49#define append(what) \
50 if (pos >= end) \
51 return buf; \
52 pos += snprintf(pos, sizeof(buf) - (pos - buf), \
53 " " #what ": %s\n", \
54 osmo_hexdump_nospc((void*)&vec->what, sizeof(vec->what)))
55
56 append(rand);
57 append(autn);
58 append(ck);
59 append(ik);
60 append(res);
61 append(res_len);
62 append(kc);
63 append(sres);
64 append(auth_types);
65#undef append
66
67 return buf;
68}
69
70#define VEC_IS(vec, expect) do { \
Neels Hofmeyr6b883f72017-01-31 16:40:28 +010071 char *_is = vec_str(vec); \
Neels Hofmeyr8cde6622017-01-31 02:10:40 +010072 if (strcmp(_is, expect)) { \
73 fprintf(stderr, "MISMATCH! expected ==\n%s\n", \
74 expect); \
75 char *a = _is; \
76 char *b = expect; \
77 for (; *a && *b; a++, b++) { \
78 if (*a != *b) { \
79 while (a > _is && *(a-1) != '\n') a--; \
80 fprintf(stderr, "mismatch at %d:\n" \
Neels Hofmeyr6b883f72017-01-31 16:40:28 +010081 "%s", (int)(a - _is), a); \
Neels Hofmeyr8cde6622017-01-31 02:10:40 +010082 break; \
83 } \
84 } \
85 OSMO_ASSERT(false); \
Neels Hofmeyr8d97d342017-02-21 22:46:35 +010086 } else \
87 fprintf(stderr, "vector matches expectations\n"); \
Neels Hofmeyr8cde6622017-01-31 02:10:40 +010088 } while (0)
89
Neels Hofmeyr00c06972017-01-31 01:19:27 +010090uint8_t fake_rand[16] = { 0 };
Neels Hofmeyr3aa3c102017-02-21 22:48:35 +010091bool fake_rand_fixed = true;
92
93void next_rand(const char *hexstr, bool fixed)
94{
95 osmo_hexparse(hexstr, fake_rand, sizeof(fake_rand));
96 fake_rand_fixed = fixed;
97}
Neels Hofmeyr00c06972017-01-31 01:19:27 +010098
99int rand_get(uint8_t *rand, unsigned int len)
100{
Neels Hofmeyr3aa3c102017-02-21 22:48:35 +0100101 int i;
Neels Hofmeyr00c06972017-01-31 01:19:27 +0100102 OSMO_ASSERT(len <= sizeof(fake_rand));
103 memcpy(rand, fake_rand, len);
Neels Hofmeyr3aa3c102017-02-21 22:48:35 +0100104 if (!fake_rand_fixed) {
105 for (i = 0; i < len; i++)
106 fake_rand[i] += 0x11;
107 }
Neels Hofmeyr00c06972017-01-31 01:19:27 +0100108 return len;
109}
110
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100111static void test_gen_vectors_2g_only(void)
112{
113 struct osmo_sub_auth_data aud2g;
114 struct osmo_sub_auth_data aud3g;
115 struct osmo_auth_vector vec;
116 int rc;
117
118 comment_start();
119
120 aud2g = (struct osmo_sub_auth_data){
121 .type = OSMO_AUTH_TYPE_GSM,
122 .algo = OSMO_AUTH_ALG_COMP128v1,
123 };
124
125 osmo_hexparse("EB215756028D60E3275E613320AEC880",
126 aud2g.u.gsm.ki, sizeof(aud2g.u.gsm.ki));
127
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100128 aud3g = (struct osmo_sub_auth_data){ 0 };
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100129
Neels Hofmeyr3aa3c102017-02-21 22:48:35 +0100130 next_rand("39fa2f4e3d523d8619a73b4f65c3e14d", true);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100131
132 vec = (struct osmo_auth_vector){ {0} };
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100133 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 0, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100134 rc = auc_compute_vectors(&vec, 1, &aud2g, &aud3g, NULL, NULL);
135 VERBOSE_ASSERT(rc, == 1, "%d");
136
137 VEC_IS(&vec,
138 " rand: 39fa2f4e3d523d8619a73b4f65c3e14d\n"
139 " autn: 00000000000000000000000000000000\n"
140 " ck: 00000000000000000000000000000000\n"
141 " ik: 00000000000000000000000000000000\n"
142 " res: 00000000000000000000000000000000\n"
143 " res_len: 00\n"
144 " kc: 241a5b16aeb8e400\n"
145 " sres: 429d5b27\n"
146 " auth_types: 01000000\n"
147 );
148
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100149 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 0, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100150
151 /* even though vec is not zero-initialized, it should produce the same
152 * result (regardless of the umts sequence nr) */
153 aud3g.u.umts.sqn = 123;
154 rc = auc_compute_vectors(&vec, 1, &aud2g, &aud3g, NULL, NULL);
155 VERBOSE_ASSERT(rc, == 1, "%d");
156
157 VEC_IS(&vec,
158 " rand: 39fa2f4e3d523d8619a73b4f65c3e14d\n"
159 " autn: 00000000000000000000000000000000\n"
160 " ck: 00000000000000000000000000000000\n"
161 " ik: 00000000000000000000000000000000\n"
162 " res: 00000000000000000000000000000000\n"
163 " res_len: 00\n"
164 " kc: 241a5b16aeb8e400\n"
165 " sres: 429d5b27\n"
166 " auth_types: 01000000\n"
167 );
168
169 comment_end();
170}
171
172static void test_gen_vectors_2g_plus_3g(void)
173{
174 struct osmo_sub_auth_data aud2g;
175 struct osmo_sub_auth_data aud3g;
176 struct osmo_auth_vector vec;
177 int rc;
178
179 comment_start();
180
181 aud2g = (struct osmo_sub_auth_data){
182 .type = OSMO_AUTH_TYPE_GSM,
183 .algo = OSMO_AUTH_ALG_COMP128v1,
184 };
185
186 osmo_hexparse("EB215756028D60E3275E613320AEC880",
187 aud2g.u.gsm.ki, sizeof(aud2g.u.gsm.ki));
188
189 aud3g = (struct osmo_sub_auth_data){
190 .type = OSMO_AUTH_TYPE_UMTS,
191 .algo = OSMO_AUTH_ALG_MILENAGE,
192 };
193
194 osmo_hexparse("EB215756028D60E3275E613320AEC880",
195 aud3g.u.umts.k, sizeof(aud3g.u.umts.k));
196 osmo_hexparse("FB2A3D1B360F599ABAB99DB8669F8308",
197 aud3g.u.umts.opc, sizeof(aud3g.u.umts.opc));
Neels Hofmeyr3aa3c102017-02-21 22:48:35 +0100198 next_rand("39fa2f4e3d523d8619a73b4f65c3e14d", true);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100199
200 vec = (struct osmo_auth_vector){ {0} };
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100201 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 0, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100202 rc = auc_compute_vectors(&vec, 1, &aud2g, &aud3g, NULL, NULL);
203 VERBOSE_ASSERT(rc, == 1, "%d");
204
205 VEC_IS(&vec,
206 " rand: 39fa2f4e3d523d8619a73b4f65c3e14d\n"
207 " autn: 8704f5ba55f30000d2ee44b22c8ea919\n"
208 " ck: f64735036e5871319c679f4742a75ea1\n"
209 " ik: 27497388b6cb044648f396aa155b95ef\n"
210 " res: e229c19e791f2e410000000000000000\n"
211 " res_len: 08\n"
212 " kc: 241a5b16aeb8e400\n"
213 " sres: 429d5b27\n"
214 " auth_types: 03000000\n"
215 );
216
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100217 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 1, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100218
219 /* even though vec is not zero-initialized, it should produce the same
220 * result with the same sequence nr */
221 aud3g.u.umts.sqn = 0;
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100222 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 0, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100223 rc = auc_compute_vectors(&vec, 1, &aud2g, &aud3g, NULL, NULL);
224 VERBOSE_ASSERT(rc, == 1, "%d");
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100225 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 1, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100226
227 VEC_IS(&vec,
228 " rand: 39fa2f4e3d523d8619a73b4f65c3e14d\n"
229 " autn: 8704f5ba55f30000d2ee44b22c8ea919\n"
230 " ck: f64735036e5871319c679f4742a75ea1\n"
231 " ik: 27497388b6cb044648f396aa155b95ef\n"
232 " res: e229c19e791f2e410000000000000000\n"
233 " res_len: 08\n"
234 " kc: 241a5b16aeb8e400\n"
235 " sres: 429d5b27\n"
236 " auth_types: 03000000\n"
237 );
238
239 comment_end();
240}
241
Neels Hofmeyr428c9472017-02-21 22:50:59 +0100242void _test_gen_vectors_3g_only__expect_vecs(struct osmo_auth_vector vecs[3])
243{
244 fprintf(stderr, "[0]: ");
245 VEC_IS(&vecs[0],
246 " rand: 897210a0f7de278f0b8213098e098a3f\n"
247 " autn: c6b9790dad4b00000cf322869ea6a481\n"
248 " ck: e9922bd036718ed9e40bd1d02c3b81a5\n"
249 " ik: f19c20ca863137f8892326d959ec5e01\n"
250 " res: 9af5a557902d2db80000000000000000\n"
251 " res_len: 08\n"
252 " kc: 7526fc13c5976685\n"
253 " sres: 0ad888ef\n"
254 " auth_types: 03000000\n"
255 );
256 fprintf(stderr, "[1]: ");
257 VEC_IS(&vecs[1],
258 " rand: 9a8321b108ef38a01c93241a9f1a9b50\n"
259 " autn: 79a5113eb0910000be6020540503ffc5\n"
260 " ck: 3686f05df057d1899c66ae4eb18cf941\n"
261 " ik: 79f21ed53bcb47787de57d136ff803a5\n"
262 " res: 43023475cb29292c0000000000000000\n"
263 " res_len: 08\n"
264 " kc: aef73dd515e86c15\n"
265 " sres: 882b1d59\n"
266 " auth_types: 03000000\n"
267 );
268 fprintf(stderr, "[2]: ");
269 VEC_IS(&vecs[2],
270 " rand: ab9432c2190049b12da4352bb02bac61\n"
271 " autn: 24b018d46c3b00009c7e1b47f3a19b2b\n"
272 " ck: d86c3191a36fc0602e48202ef2080964\n"
273 " ik: 648dab72016181406243420649e63dc9\n"
274 " res: 010cab11cc63a6e40000000000000000\n"
275 " res_len: 08\n"
276 " kc: f0eaf8cb19e0758d\n"
277 " sres: cd6f0df5\n"
278 " auth_types: 03000000\n"
279 );
280}
281
Neels Hofmeyr00c06972017-01-31 01:19:27 +0100282static void test_gen_vectors_3g_only(void)
283{
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100284 struct osmo_sub_auth_data aud2g;
285 struct osmo_sub_auth_data aud3g;
286 struct osmo_auth_vector vec;
Neels Hofmeyr428c9472017-02-21 22:50:59 +0100287 struct osmo_auth_vector vecs[3];
Neels Hofmeyrec9036b2017-02-21 21:56:11 +0100288 uint8_t auts[14];
289 uint8_t rand_auts[16];
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100290 int rc;
291
Neels Hofmeyr00c06972017-01-31 01:19:27 +0100292 comment_start();
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100293
294 aud2g = (struct osmo_sub_auth_data){ 0 };
295
296 aud3g = (struct osmo_sub_auth_data){
297 .type = OSMO_AUTH_TYPE_UMTS,
298 .algo = OSMO_AUTH_ALG_MILENAGE,
299 };
300
301 osmo_hexparse("EB215756028D60E3275E613320AEC880",
302 aud3g.u.umts.k, sizeof(aud3g.u.umts.k));
303 osmo_hexparse("FB2A3D1B360F599ABAB99DB8669F8308",
304 aud3g.u.umts.opc, sizeof(aud3g.u.umts.opc));
Neels Hofmeyr3aa3c102017-02-21 22:48:35 +0100305 next_rand("39fa2f4e3d523d8619a73b4f65c3e14d", true);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100306
307 vec = (struct osmo_auth_vector){ {0} };
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100308 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 0, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100309 rc = auc_compute_vectors(&vec, 1, &aud2g, &aud3g, NULL, NULL);
310 VERBOSE_ASSERT(rc, == 1, "%d");
311
312 VEC_IS(&vec,
313 " rand: 39fa2f4e3d523d8619a73b4f65c3e14d\n"
314 " autn: 8704f5ba55f30000d2ee44b22c8ea919\n"
315 " ck: f64735036e5871319c679f4742a75ea1\n"
316 " ik: 27497388b6cb044648f396aa155b95ef\n"
317 " res: e229c19e791f2e410000000000000000\n"
318 " res_len: 08\n"
319 " kc: 059a4f668f6fbe39\n"
320 " sres: 9b36efdf\n"
321 " auth_types: 03000000\n"
322 );
323
324 /* Note: 3GPP TS 33.102 6.8.1.2: c3 function to get GSM auth is
325 * KC[0..7] == CK[0..7] ^ CK[8..15] ^ IK[0..7] ^ IK[8..15]
326 * In [16]: hex( 0xf64735036e587131
327 * ^ 0x9c679f4742a75ea1
328 * ^ 0x27497388b6cb0446
329 * ^ 0x48f396aa155b95ef)
330 * Out[16]: '0x59a4f668f6fbe39L'
331 * hence expecting kc: 059a4f668f6fbe39
332 */
333
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100334 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 1, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100335
336 /* even though vec is not zero-initialized, it should produce the same
337 * result with the same sequence nr */
338 aud3g.u.umts.sqn = 0;
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100339 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 0, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100340 rc = auc_compute_vectors(&vec, 1, &aud2g, &aud3g, NULL, NULL);
341 VERBOSE_ASSERT(rc, == 1, "%d");
Neels Hofmeyr6b883f72017-01-31 16:40:28 +0100342 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 1, "%"PRIu64);
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100343
344 VEC_IS(&vec,
345 " rand: 39fa2f4e3d523d8619a73b4f65c3e14d\n"
346 " autn: 8704f5ba55f30000d2ee44b22c8ea919\n"
347 " ck: f64735036e5871319c679f4742a75ea1\n"
348 " ik: 27497388b6cb044648f396aa155b95ef\n"
349 " res: e229c19e791f2e410000000000000000\n"
350 " res_len: 08\n"
351 " kc: 059a4f668f6fbe39\n"
352 " sres: 9b36efdf\n"
353 " auth_types: 03000000\n"
354 );
355
Neels Hofmeyrec9036b2017-02-21 21:56:11 +0100356
357 fprintf(stderr, "- test AUTS resync\n");
358 vec = (struct osmo_auth_vector){};
359 aud3g.u.umts.sqn = 0;
360 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 0, "%"PRIu64);
361
362 /* The AUTN sent was 8704f5ba55f30000d2ee44b22c8ea919
363 * with the first 6 bytes being SQN ^ AK.
364 * K = EB215756028D60E3275E613320AEC880
365 * OPC = FB2A3D1B360F599ABAB99DB8669F8308
366 * RAND = 39fa2f4e3d523d8619a73b4f65c3e14d
367 * --milenage-f5-->
368 * AK = 8704f5ba55f3
369 *
370 * The first six bytes are 8704f5ba55f3,
371 * and 8704f5ba55f3 ^ AK = 0.
372 * --> SQN = 0.
373 *
374 * Say the USIM doesn't like that, let's say it is at SQN 23.
375 * SQN_MS = 000000000017
376 *
377 * AUTS = Conc(SQN_MS) || MAC-S
378 * Conc(SQN_MS) = SQN_MS ⊕ f5*[K](RAND)
379 * MAC-S = f1*[K] (SQN MS || RAND || AMF)
380 *
381 * f5*--> Conc(SQN_MS) = 000000000017 ^ 979498b1f73a
382 * = 979498b1f72d
383 * AMF = 0000 (TS 33.102 v7.0.0, 6.3.3)
384 *
385 * MAC-S = f1*[K] (000000000017 || 39fa2f4e3d523d8619a73b4f65c3e14d || 0000)
386 * = 3e28c59fa2e72f9c
387 *
388 * AUTS = 979498b1f72d || 3e28c59fa2e72f9c
389 *
390 * verify valid AUTS resulting in SQN 23 with:
391 * osmo-auc-gen -3 -a milenage -k EB215756028D60E3275E613320AEC880 \
392 * -o FB2A3D1B360F599ABAB99DB8669F8308 \
393 * -r 39fa2f4e3d523d8619a73b4f65c3e14d \
394 * -A 979498b1f72d3e28c59fa2e72f9c
395 */
396
397 /* AUTS response by USIM */
398 osmo_hexparse("979498b1f72d3e28c59fa2e72f9c",
399 auts, sizeof(auts));
400 /* RAND sent to USIM, which AUTS was generated from */
401 osmo_hexparse("39fa2f4e3d523d8619a73b4f65c3e14d",
402 rand_auts, sizeof(rand_auts));
403 /* new RAND token for the next key */
Neels Hofmeyr3aa3c102017-02-21 22:48:35 +0100404 next_rand("897210a0f7de278f0b8213098e098a3f", true);
Neels Hofmeyrec9036b2017-02-21 21:56:11 +0100405 rc = auc_compute_vectors(&vec, 1, &aud2g, &aud3g, rand_auts, auts);
406 VERBOSE_ASSERT(rc, == 1, "%d");
407 /* The USIM's last sqn was 23, the calculated vector was 24, hence the
408 * next one stored should be 25. */
409 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 25, "%"PRIu64);
410
411 VEC_IS(&vec,
412 " rand: 897210a0f7de278f0b8213098e098a3f\n"
413 " autn: c6b9790dad4b00000cf322869ea6a481\n"
414 " ck: e9922bd036718ed9e40bd1d02c3b81a5\n"
415 " ik: f19c20ca863137f8892326d959ec5e01\n"
416 " res: 9af5a557902d2db80000000000000000\n"
417 " res_len: 08\n"
418 " kc: 7526fc13c5976685\n"
419 " sres: 0ad888ef\n"
420 " auth_types: 03000000\n"
421 );
422
Neels Hofmeyr428c9472017-02-21 22:50:59 +0100423
424 fprintf(stderr, "- verify N vectors with AUTS resync"
425 " == N vectors without AUTS\n"
426 "First just set rand and sqn = 24, and compute 3 vectors\n");
427 next_rand("897210a0f7de278f0b8213098e098a3f", false);
428 aud3g.u.umts.sqn = 24;
429 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 24, "%"PRIu64);
430
431 memset(vecs, 0, sizeof(vecs));
432 rc = auc_compute_vectors(vecs, 3, &aud2g, &aud3g, NULL, NULL);
433 VERBOSE_ASSERT(rc, == 3, "%d");
434 VERBOSE_ASSERT(aud3g.u.umts.sqn, == 27, "%"PRIu64);
435
436 _test_gen_vectors_3g_only__expect_vecs(vecs);
437
438 fprintf(stderr, "Now reach sqn = 24 with AUTS and expect the same\n");
439 /* AUTS response by USIM */
440 osmo_hexparse("979498b1f72d3e28c59fa2e72f9c",
441 auts, sizeof(auts));
442 /* RAND sent to USIM, which AUTS was generated from */
443 osmo_hexparse("39fa2f4e3d523d8619a73b4f65c3e14d",
444 rand_auts, sizeof(rand_auts));
445 next_rand("897210a0f7de278f0b8213098e098a3f", false);
446 rc = auc_compute_vectors(vecs, 3, &aud2g, &aud3g, rand_auts, auts);
447
Neels Hofmeyrb5b11e32017-02-22 01:42:43 +0100448 _test_gen_vectors_3g_only__expect_vecs(vecs);
Neels Hofmeyr428c9472017-02-21 22:50:59 +0100449
Neels Hofmeyr00c06972017-01-31 01:19:27 +0100450 comment_end();
451}
452
Neels Hofmeyr569d3222017-02-21 22:57:11 +0100453void test_gen_vectors_bad_args()
454{
455 struct osmo_auth_vector vec;
456 uint8_t auts[14];
457 uint8_t rand_auts[16];
458 int rc;
459 int i;
460
461 struct osmo_sub_auth_data aud2g = {
462 .type = OSMO_AUTH_TYPE_GSM,
463 .algo = OSMO_AUTH_ALG_COMP128v1,
464 };
465
466 struct osmo_sub_auth_data aud3g = {
467 .type = OSMO_AUTH_TYPE_UMTS,
468 .algo = OSMO_AUTH_ALG_MILENAGE,
469 };
470
471 struct osmo_sub_auth_data aud2g_noalg = {
472 .type = OSMO_AUTH_TYPE_GSM,
473 .algo = OSMO_AUTH_ALG_NONE,
474 };
475
476 struct osmo_sub_auth_data aud3g_noalg = {
477 .type = OSMO_AUTH_TYPE_UMTS,
478 .algo = OSMO_AUTH_ALG_NONE,
479 };
480
481 struct osmo_sub_auth_data aud_notype = {
482 .type = OSMO_AUTH_TYPE_NONE,
483 .algo = OSMO_AUTH_ALG_MILENAGE,
484 };
485
486 struct osmo_sub_auth_data no_aud = {
487 .type = OSMO_AUTH_TYPE_NONE,
488 .algo = OSMO_AUTH_ALG_NONE,
489 };
490
491 struct {
492 struct osmo_sub_auth_data *aud2g;
493 struct osmo_sub_auth_data *aud3g;
494 uint8_t *rand_auts;
495 uint8_t *auts;
496 const char *label;
497 } tests[] = {
498 { NULL, NULL, NULL, NULL, "no auth data (a)"},
499 { NULL, &aud3g_noalg, NULL, NULL, "no auth data (b)"},
500 { NULL, &aud_notype, NULL, NULL, "no auth data (c)"},
501 { NULL, &no_aud, NULL, NULL, "no auth data (d)"},
502 { &aud2g_noalg, NULL, NULL, NULL, "no auth data (e)"},
503 { &aud2g_noalg, &aud3g_noalg, NULL, NULL, "no auth data (f)"},
504 { &aud2g_noalg, &aud_notype, NULL, NULL, "no auth data (g)"},
505 { &aud2g_noalg, &no_aud, NULL, NULL, "no auth data (h)"},
506 { &aud_notype, NULL, NULL, NULL, "no auth data (i)"},
507 { &aud_notype, &aud3g_noalg, NULL, NULL, "no auth data (j)"},
508 { &aud_notype, &aud_notype, NULL, NULL, "no auth data (k)"},
509 { &aud_notype, &no_aud, NULL, NULL, "no auth data (l)"},
510 { &no_aud, NULL, NULL, NULL, "no auth data (m)"},
511 { &no_aud, &aud3g_noalg, NULL, NULL, "no auth data (n)"},
512 { &no_aud, &aud_notype, NULL, NULL, "no auth data (o)"},
513 { &no_aud, &no_aud, NULL, NULL, "no auth data (p)"},
514 { &aud3g, NULL, NULL, NULL, "wrong auth data type (a)"},
515 { &aud3g, &aud3g_noalg, NULL, NULL, "wrong auth data type (b)"},
516 { &aud3g, &aud_notype, NULL, NULL, "wrong auth data type (c)"},
517 { &aud3g, &no_aud, NULL, NULL, "wrong auth data type (d)"},
518 { NULL, &aud2g, NULL, NULL, "wrong auth data type (e)"},
519 { &aud3g_noalg, &aud2g, NULL, NULL, "wrong auth data type (f)"},
520 { &aud_notype, &aud2g, NULL, NULL, "wrong auth data type (g)"},
521 { &no_aud, &aud2g, NULL, NULL, "wrong auth data type (h)"},
522 { &aud3g, &aud2g, NULL, NULL, "wrong auth data type (i)"},
523 { &aud3g, &aud3g, NULL, NULL, "wrong auth data type (j)"},
524 { &aud2g, &aud2g, NULL, NULL, "wrong auth data type (k)"},
525 { &aud2g, NULL, rand_auts, auts, "AUTS for 2G-only (a)"},
526 { &aud2g, &aud3g_noalg, rand_auts, auts, "AUTS for 2G-only (b)"},
527 { &aud2g, &aud_notype, rand_auts, auts, "AUTS for 2G-only (c)"},
528 { &aud2g, &no_aud, rand_auts, auts, "AUTS for 2G-only (d)"},
529 { NULL, &aud3g, NULL, auts, "incomplete AUTS (a)"},
530 { NULL, &aud3g, rand_auts, NULL, "incomplete AUTS (b)"},
531 { &aud2g, &aud3g, NULL, auts, "incomplete AUTS (c)"},
532 { &aud2g, &aud3g, rand_auts, NULL, "incomplete AUTS (d)"},
533 };
534
535 comment_start();
536
537 for (i = 0; i < ARRAY_SIZE(tests); i++) {
538 fprintf(stderr, "\n- %s\n", tests[i].label);
539 rc = auc_compute_vectors(&vec, 1,
540 tests[i].aud2g,
541 tests[i].aud3g,
542 tests[i].rand_auts,
543 tests[i].auts);
544 VERBOSE_ASSERT(rc, < 0, "%d");
545 }
546
547 comment_end();
548}
549
Neels Hofmeyr00c06972017-01-31 01:19:27 +0100550int main()
551{
552 printf("auc_3g_test.c\n");
553 osmo_init_logging(&hlr_log_info);
554 log_set_print_filename(osmo_stderr_target, 0);
555 log_set_print_timestamp(osmo_stderr_target, 0);
556 log_set_use_color(osmo_stderr_target, 0);
557 log_set_print_category(osmo_stderr_target, 1);
558
Neels Hofmeyr8cde6622017-01-31 02:10:40 +0100559 test_gen_vectors_2g_only();
560 test_gen_vectors_2g_plus_3g();
Neels Hofmeyr00c06972017-01-31 01:19:27 +0100561 test_gen_vectors_3g_only();
Neels Hofmeyr569d3222017-02-21 22:57:11 +0100562 test_gen_vectors_bad_args();
Neels Hofmeyr00c06972017-01-31 01:19:27 +0100563
564 printf("Done\n");
565 return 0;
566}