Handle PRF failures in eap-aka-3gpp2
[strongswan.git] / src / libcharon / plugins / eap_aka_3gpp2 / eap_aka_3gpp2_functions.c
1 /*
2 * Copyright (C) 2008-2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "eap_aka_3gpp2_functions.h"
17
18 #include <gmp.h>
19 #include <limits.h>
20
21 #include <daemon.h>
22
23 typedef struct private_eap_aka_3gpp2_functions_t private_eap_aka_3gpp2_functions_t;
24
25 /**
26 * Private data of an eap_aka_3gpp2_functions_t object.
27 */
28 struct private_eap_aka_3gpp2_functions_t {
29
30 /**
31 * Public eap_aka_3gpp2_functions_t interface.
32 */
33 eap_aka_3gpp2_functions_t public;
34
35 /**
36 * Used keyed SHA1 function, as PRF
37 */
38 prf_t *prf;
39 };
40
41 #define AKA_PAYLOAD_LEN 64
42
43 #define F1 0x42
44 #define F1STAR 0x43
45 #define F2 0x44
46 #define F3 0x45
47 #define F4 0x46
48 #define F5 0x47
49 #define F5STAR 0x48
50
51 /** Family key, as proposed in S.S0055 */
52 static chunk_t fmk = chunk_from_chars(0x41, 0x48, 0x41, 0x47);
53
54 /**
55 * Binary represnation of the polynom T^160 + T^5 + T^3 + T^2 + 1
56 */
57 static u_int8_t g[] = {
58 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x2d
61 };
62
63 /**
64 * Predefined random bits from the RAND Corporation book
65 */
66 static u_int8_t a[] = {
67 0x9d, 0xe9, 0xc9, 0xc8, 0xef, 0xd5, 0x78, 0x11,
68 0x48, 0x23, 0x14, 0x01, 0x90, 0x1f, 0x2d, 0x49,
69 0x3f, 0x4c, 0x63, 0x65
70 };
71
72 /**
73 * Predefined random bits from the RAND Corporation book
74 */
75 static u_int8_t b[] = {
76 0x75, 0xef, 0xd1, 0x5c, 0x4b, 0x8f, 0x8f, 0x51,
77 0x4e, 0xf3, 0xbc, 0xc3, 0x79, 0x4a, 0x76, 0x5e,
78 0x7e, 0xec, 0x45, 0xe0
79 };
80
81 /**
82 * Multiplicate two mpz_t with bits interpreted as polynoms.
83 */
84 static void mpz_mul_poly(mpz_t r, mpz_t a, mpz_t b)
85 {
86 mpz_t bm, rm;
87 int current = 0, shifted = 0, shift;
88
89 mpz_init_set(bm, b);
90 mpz_init_set_ui(rm, 0);
91 /* scan through a, for each found bit: */
92 while ((current = mpz_scan1(a, current)) != ULONG_MAX)
93 {
94 /* XOR shifted b into r */
95 shift = current - shifted;
96 mpz_mul_2exp(bm, bm, shift);
97 shifted += shift;
98 mpz_xor(rm, rm, bm);
99 current++;
100 }
101
102 mpz_swap(r, rm);
103 mpz_clear(rm);
104 mpz_clear(bm);
105 }
106
107 /**
108 * Calculate the sum of a + b interpreted as polynoms.
109 */
110 static void mpz_add_poly(mpz_t res, mpz_t a, mpz_t b)
111 {
112 /* addition of polynominals is just the XOR */
113 mpz_xor(res, a, b);
114 }
115
116 /**
117 * Calculate the remainder of a/b interpreted as polynoms.
118 */
119 static void mpz_mod_poly(mpz_t r, mpz_t a, mpz_t b)
120 {
121 /* Example:
122 * a = 10001010
123 * b = 00000101
124 */
125 int a_bit, b_bit, diff;
126 mpz_t bm, am;
127
128 mpz_init_set(am, a);
129 mpz_init(bm);
130
131 a_bit = mpz_sizeinbase(a, 2);
132 b_bit = mpz_sizeinbase(b, 2);
133
134 /* don't do anything if b > a */
135 if (a_bit >= b_bit)
136 {
137 /* shift b left to align up most signaficant "1" to a:
138 * a = 10001010
139 * b = 10100000
140 */
141 mpz_mul_2exp(bm, b, a_bit - b_bit);
142 do
143 {
144 /* XOR b into a, this kills the most significant "1":
145 * a = 00101010
146 */
147 mpz_xor(am, am, bm);
148 /* find the next most significant "1" in a, and align up b:
149 * a = 00101010
150 * b = 00101000
151 */
152 diff = a_bit - mpz_sizeinbase(am, 2);
153 mpz_div_2exp(bm, bm, diff);
154 a_bit -= diff;
155 }
156 while (b_bit <= mpz_sizeinbase(bm, 2));
157 /* While b is not shifted to its original value */
158 }
159 /* after another iteration:
160 * a = 00000010
161 * which is the polynomial modulo
162 */
163
164 mpz_swap(r, am);
165 mpz_clear(am);
166 mpz_clear(bm);
167 }
168
169 /**
170 * Step 3 of the various fx() functions:
171 * XOR the key into the SHA1 IV
172 */
173 static bool step3(prf_t *prf, u_char k[AKA_K_LEN],
174 u_char payload[AKA_PAYLOAD_LEN], u_int8_t h[HASH_SIZE_SHA1])
175 {
176 /* use the keyed hasher to build the hash */
177 return prf->set_key(prf, chunk_create(k, AKA_K_LEN)) &&
178 prf->get_bytes(prf, chunk_create(payload, AKA_PAYLOAD_LEN), h);
179 }
180
181 /**
182 * Step 4 of the various fx() functions:
183 * Polynomial whiten calculations
184 */
185 static void step4(u_char x[HASH_SIZE_SHA1])
186 {
187 mpz_t xm, am, bm, gm;
188
189 mpz_init(xm);
190 mpz_init(am);
191 mpz_init(bm);
192 mpz_init(gm);
193
194 mpz_import(xm, HASH_SIZE_SHA1, 1, 1, 1, 0, x);
195 mpz_import(am, sizeof(a), 1, 1, 1, 0, a);
196 mpz_import(bm, sizeof(b), 1, 1, 1, 0, b);
197 mpz_import(gm, sizeof(g), 1, 1, 1, 0, g);
198
199 mpz_mul_poly(xm, am, xm);
200 mpz_add_poly(xm, bm, xm);
201 mpz_mod_poly(xm, xm, gm);
202
203 mpz_export(x, NULL, 1, HASH_SIZE_SHA1, 1, 0, xm);
204
205 mpz_clear(xm);
206 mpz_clear(am);
207 mpz_clear(bm);
208 mpz_clear(gm);
209 }
210
211 /**
212 * Calculation function for f2(), f3(), f4()
213 */
214 static bool fx(prf_t *prf, u_char f, u_char k[AKA_K_LEN],
215 u_char rand[AKA_RAND_LEN], u_char out[AKA_MAC_LEN])
216 {
217 u_char payload[AKA_PAYLOAD_LEN];
218 u_char h[HASH_SIZE_SHA1];
219 u_char i;
220
221 for (i = 0; i < 2; i++)
222 {
223 memset(payload, 0x5c, AKA_PAYLOAD_LEN);
224 payload[11] ^= f;
225 memxor(payload + 12, fmk.ptr, fmk.len);
226 memxor(payload + 24, rand, AKA_RAND_LEN);
227
228 payload[3] ^= i;
229 payload[19] ^= i;
230 payload[35] ^= i;
231 payload[51] ^= i;
232
233 if (!step3(prf, k, payload, h))
234 {
235 return FALSE;
236 }
237 step4(h);
238 memcpy(out + i * 8, h, 8);
239 }
240 return TRUE;
241 }
242
243 /**
244 * Calculation function of f1() and f1star()
245 */
246 static bool f1x(prf_t *prf, u_int8_t f, u_char k[AKA_K_LEN],
247 u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
248 u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN])
249 {
250 /* generate MAC = f1(FMK, SQN, RAND, AMF)
251 * K is loaded into hashers IV; FMK, RAND, SQN, AMF are XORed in a 512-bit
252 * payload which gets hashed
253 */
254 u_char payload[AKA_PAYLOAD_LEN];
255 u_char h[HASH_SIZE_SHA1];
256
257 memset(payload, 0x5c, AKA_PAYLOAD_LEN);
258 payload[11] ^= f;
259 memxor(payload + 12, fmk.ptr, fmk.len);
260 memxor(payload + 16, rand, AKA_RAND_LEN);
261 memxor(payload + 34, sqn, AKA_SQN_LEN);
262 memxor(payload + 42, amf, AKA_AMF_LEN);
263
264 if (!step3(prf, k, payload, h))
265 {
266 return FALSE;
267 }
268 step4(h);
269 memcpy(mac, h, AKA_MAC_LEN);
270 return TRUE;
271 }
272
273 /**
274 * Calculation function of f5() and f5star()
275 */
276 static bool f5x(prf_t *prf, u_char f, u_char k[AKA_K_LEN],
277 u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN])
278 {
279 u_char payload[AKA_PAYLOAD_LEN];
280 u_char h[HASH_SIZE_SHA1];
281
282 memset(payload, 0x5c, AKA_PAYLOAD_LEN);
283 payload[11] ^= f;
284 memxor(payload + 12, fmk.ptr, fmk.len);
285 memxor(payload + 16, rand, AKA_RAND_LEN);
286
287 if (!step3(prf, k, payload, h))
288 {
289 return FALSE;
290 }
291 step4(h);
292 memcpy(ak, h, AKA_AK_LEN);
293 return TRUE;
294 }
295
296 /**
297 * Calculate MAC from RAND, SQN, AMF using K
298 */
299 METHOD(eap_aka_3gpp2_functions_t, f1, bool,
300 private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
301 u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
302 u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN])
303 {
304 if (f1x(this->prf, F1, k, rand, sqn, amf, mac))
305 {
306 DBG3(DBG_IKE, "MAC %b", mac, AKA_MAC_LEN);
307 return TRUE;
308 }
309 return FALSE;
310 }
311
312 /**
313 * Calculate MACS from RAND, SQN, AMF using K
314 */
315 METHOD(eap_aka_3gpp2_functions_t, f1star, bool,
316 private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
317 u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
318 u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN])
319 {
320 if (f1x(this->prf, F1STAR, k, rand, sqn, amf, macs))
321 {
322 DBG3(DBG_IKE, "MACS %b", macs, AKA_MAC_LEN);
323 return TRUE;
324 }
325 return FALSE;
326 }
327
328 /**
329 * Calculate RES from RAND using K
330 */
331 METHOD(eap_aka_3gpp2_functions_t, f2, bool,
332 private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
333 u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX])
334 {
335 if (fx(this->prf, F2, k, rand, res))
336 {
337 DBG3(DBG_IKE, "RES %b", res, AKA_RES_MAX);
338 return TRUE;
339 }
340 return FALSE;
341 }
342
343 /**
344 * Calculate CK from RAND using K
345 */
346 METHOD(eap_aka_3gpp2_functions_t, f3, bool,
347 private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
348 u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN])
349 {
350 if (fx(this->prf, F3, k, rand, ck))
351 {
352 DBG3(DBG_IKE, "CK %b", ck, AKA_CK_LEN);
353 return TRUE;
354 }
355 return FALSE;
356 }
357
358 /**
359 * Calculate IK from RAND using K
360 */
361 METHOD(eap_aka_3gpp2_functions_t, f4, bool,
362 private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
363 u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN])
364 {
365 if (fx(this->prf, F4, k, rand, ik))
366 {
367 DBG3(DBG_IKE, "IK %b", ik, AKA_IK_LEN);
368 return TRUE;
369 }
370 return FALSE;
371 }
372
373 /**
374 * Calculate AK from a RAND using K
375 */
376 METHOD(eap_aka_3gpp2_functions_t, f5, bool,
377 private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
378 u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN])
379 {
380 if (f5x(this->prf, F5, k, rand, ak))
381 {
382 DBG3(DBG_IKE, "AK %b", ak, AKA_AK_LEN);
383 return TRUE;
384 }
385 return FALSE;
386 }
387
388 /**
389 * Calculate AKS from a RAND using K
390 */
391 METHOD(eap_aka_3gpp2_functions_t, f5star, bool,
392 private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
393 u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN])
394 {
395 if (f5x(this->prf, F5STAR, k, rand, aks))
396 {
397 DBG3(DBG_IKE, "AKS %b", aks, AKA_AK_LEN);
398 return TRUE;
399 }
400 return FALSE;
401 }
402
403 METHOD(eap_aka_3gpp2_functions_t, destroy, void,
404 private_eap_aka_3gpp2_functions_t *this)
405 {
406 this->prf->destroy(this->prf);
407 free(this);
408 }
409
410 /**
411 * See header
412 */
413 eap_aka_3gpp2_functions_t *eap_aka_3gpp2_functions_create()
414 {
415 private_eap_aka_3gpp2_functions_t *this;
416
417 INIT(this,
418 .public = {
419 .f1 = _f1,
420 .f1star = _f1star,
421 .f2 = _f2,
422 .f3 = _f3,
423 .f4 = _f4,
424 .f5 = _f5,
425 .f5star = _f5star,
426 .destroy = _destroy,
427 },
428 .prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1),
429 );
430 if (!this->prf)
431 {
432 DBG1(DBG_CFG, "%N not supported, unable to use 3GPP2 algorithm",
433 pseudo_random_function_names, PRF_KEYED_SHA1);
434 free(this);
435 return NULL;
436 }
437 return &this->public;
438 }
439