[4859] caused crash when handling the %config case
[strongswan.git] / src / charon / plugins / eap_aka / eap_aka.c
1 /*
2 * Copyright (C) 2006 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 * $Id$
16 */
17
18
19 /* The EAP-AKA method uses it's own simple parser for processing EAP-AKA
20 * payloads, as the IKEv2 parser is not suitable for that job. There are
21 * two simple methods for parsing payloads, read_header() and read_attribute().
22 * Every EAP-AKA payload consists of a header and a list of attributes. Those
23 * functions mentioned read the data and return the type of the found
24 * attribute/EAP-AKA-type. For generating a EAP-AKA message, we have a
25 * build_aka_payload(), which builds the whole message from a variable
26 * argument list containing its attributes.
27 * The processing of messages is split up in various functions:
28 * - peer_process() - General processing multiplexer for the peer
29 * - peer_process_challenge() - Specific AKA-Challenge processor
30 * - peer_process_notification() - Processing of AKA-Notification
31 * - server_process() - General processing multiplexer for the server
32 * - peer_process_challenge() - Processing of a received Challenge response
33 * - peer_process_synchronize() - Process a sequence number synchronization
34 * - server_initiate() - Initiation method for the server, calls
35 * - server_initiate_challenge() - Initiation of AKA-Challenge
36 */
37
38 #include <limits.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <sys/time.h>
42 #include <time.h>
43 #include <gmp.h>
44
45 #include "eap_aka.h"
46
47 #include <daemon.h>
48 #include <library.h>
49 #include <crypto/hashers/hasher.h>
50
51 /* Use test vectors specified in S.S0055
52 #define TEST_VECTORS */
53
54 #define RAND_LENGTH 16
55 #define RES_LENGTH 16
56 #define SQN_LENGTH 6
57 #define K_LENGTH 16
58 #define MAC_LENGTH 8
59 #define CK_LENGTH 16
60 #define IK_LENGTH 16
61 #define AK_LENGTH 6
62 #define AMF_LENGTH 2
63 #define FMK_LENGTH 4
64 #define AUTN_LENGTH (SQN_LENGTH + AMF_LENGTH + MAC_LENGTH)
65 #define AUTS_LENGTH (SQN_LENGTH + MAC_LENGTH)
66 #define PAYLOAD_LENGTH 64
67 #define MK_LENGTH 20
68 #define MSK_LENGTH 64
69 #define EMSK_LENGTH 64
70 #define KAUTH_LENGTH 16
71 #define KENCR_LENGTH 16
72 #define AT_MAC_LENGTH 16
73
74 #define F1 0x42
75 #define F1STAR 0x43
76 #define F2 0x44
77 #define F3 0x45
78 #define F4 0x46
79 #define F5 0x47
80 #define F5STAR 0x48
81
82 typedef enum aka_subtype_t aka_subtype_t;
83 typedef enum aka_attribute_t aka_attribute_t;
84
85 /**
86 * Subtypes of AKA messages
87 */
88 enum aka_subtype_t {
89 AKA_CHALLENGE = 1,
90 AKA_AUTHENTICATION_REJECT = 2,
91 AKA_SYNCHRONIZATION_FAILURE = 4,
92 AKA_IDENTITY = 5,
93 AKA_NOTIFICATION = 12,
94 AKA_REAUTHENTICATION = 13,
95 AKA_CLIENT_ERROR = 14,
96 };
97
98 /**
99 * Attribute types in AKA messages
100 */
101 enum aka_attribute_t {
102 /** defines the end of attribute list */
103 AT_END = -1,
104 AT_RAND = 1,
105 AT_AUTN = 2,
106 AT_RES = 3,
107 AT_AUTS = 4,
108 AT_PADDING = 6,
109 AT_NONCE_MT = 7,
110 AT_PERMANENT_ID_REQ = 10,
111 AT_MAC = 11,
112 AT_NOTIFICATION = 12,
113 AT_ANY_ID_REQ = 13,
114 AT_IDENTITY = 14,
115 AT_VERSION_LIST = 15,
116 AT_SELECTED_VERSION = 16,
117 AT_FULLAUTH_ID_REQ = 17,
118 AT_COUNTER = 19,
119 AT_COUNTER_TOO_SMALL = 20,
120 AT_NONCE_S = 21,
121 AT_CLIENT_ERROR_CODE = 22,
122 AT_IV = 129,
123 AT_ENCR_DATA = 130,
124 AT_NEXT_PSEUDONYM = 132,
125 AT_NEXT_REAUTH_ID = 133,
126 AT_CHECKCODE = 134,
127 AT_RESULT_IND = 135,
128 };
129
130 ENUM_BEGIN(aka_subtype_names, AKA_CHALLENGE, AKA_IDENTITY,
131 "AKA_CHALLENGE",
132 "AKA_AUTHENTICATION_REJECT",
133 "AKA_3",
134 "AKA_SYNCHRONIZATION_FAILURE",
135 "AKA_IDENTITY");
136 ENUM_NEXT(aka_subtype_names, AKA_NOTIFICATION, AKA_CLIENT_ERROR, AKA_IDENTITY,
137 "AKA_NOTIFICATION",
138 "AKA_REAUTHENTICATION",
139 "AKA_CLIENT_ERROR");
140 ENUM_END(aka_subtype_names, AKA_CLIENT_ERROR);
141
142
143 ENUM_BEGIN(aka_attribute_names, AT_END, AT_CLIENT_ERROR_CODE,
144 "AT_END",
145 "AT_0",
146 "AT_RAND",
147 "AT_AUTN",
148 "AT_RES",
149 "AT_AUTS",
150 "AT_5",
151 "AT_PADDING",
152 "AT_NONCE_MT",
153 "AT_8",
154 "AT_9",
155 "AT_PERMANENT_ID_REQ",
156 "AT_MAC",
157 "AT_NOTIFICATION",
158 "AT_ANY_ID_REQ",
159 "AT_IDENTITY",
160 "AT_VERSION_LIST",
161 "AT_SELECTED_VERSION",
162 "AT_FULLAUTH_ID_REQ",
163 "AT_18",
164 "AT_COUNTER",
165 "AT_COUNTER_TOO_SMALL",
166 "AT_NONCE_S",
167 "AT_CLIENT_ERROR_CODE");
168 ENUM_NEXT(aka_attribute_names, AT_IV, AT_RESULT_IND, AT_CLIENT_ERROR_CODE,
169 "AT_IV",
170 "AT_ENCR_DATA",
171 "AT_131",
172 "AT_NEXT_PSEUDONYM",
173 "AT_NEXT_REAUTH_ID",
174 "AT_CHECKCODE",
175 "AT_RESULT_IND");
176 ENUM_END(aka_attribute_names, AT_RESULT_IND);
177
178
179 typedef struct private_eap_aka_t private_eap_aka_t;
180
181 /**
182 * Private data of an eap_aka_t object.
183 */
184 struct private_eap_aka_t {
185
186 /**
187 * Public authenticator_t interface.
188 */
189 eap_aka_t public;
190
191 /**
192 * ID of the server
193 */
194 identification_t *server;
195
196 /**
197 * ID of the peer
198 */
199 identification_t *peer;
200
201 /**
202 * SHA11 hasher
203 */
204 hasher_t *sha1;
205
206 /**
207 * MAC function used in EAP-AKA
208 */
209 signer_t *signer;
210
211 /**
212 * pseudo random function used in EAP-aka
213 */
214 prf_t *prf;
215
216 /**
217 * Special keyed SHA1 hasher used in EAP-AKA, implemented as PRF
218 */
219 prf_t *keyed_prf;
220
221 /**
222 * Key for EAP MAC
223 */
224 chunk_t k_auth;
225
226 /**
227 * Key for EAP encryption
228 */
229 chunk_t k_encr;
230
231 /**
232 * MSK
233 */
234 chunk_t msk;
235
236 /**
237 * Extendend MSK
238 */
239 chunk_t emsk;
240
241 /**
242 * Expected result from client XRES
243 */
244 chunk_t xres;
245
246 /**
247 * Shared secret K from ipsec.conf (padded)
248 */
249 chunk_t k;
250
251 /**
252 * random value RAND generated by server
253 */
254 chunk_t rand;
255 };
256
257 /** Family key, as proposed in S.S0055 */
258 static u_int8_t fmk_buf[] = {0x41, 0x48, 0x41, 0x47};
259 static chunk_t fmk = chunk_from_buf(fmk_buf);
260
261 /** Authentication management field */
262 static u_int8_t amf_buf[] = {0x00, 0x01};
263 static chunk_t amf = chunk_from_buf(amf_buf);
264
265 /** AT_CLIENT_ERROR_CODE AKA attribute */
266 static u_int8_t client_error_code_buf[] = {0, 0};
267 static chunk_t client_error_code = chunk_from_buf(client_error_code_buf);
268
269 /** previously used sqn by peer, next one must be greater */
270 static u_int8_t peer_sqn_buf[6];
271 static chunk_t peer_sqn = chunk_from_buf(peer_sqn_buf);
272
273 /** set SQN to the current time */
274 static void update_sqn(u_int8_t *sqn, time_t offset)
275 {
276 timeval_t time;
277 gettimeofday(&time, NULL);
278 /* set sqb_sqn to an integer containing seconds followed by most
279 * significant useconds */
280 time.tv_sec = htonl(time.tv_sec + offset);
281 /* usec's are never larger than 0x000f423f, so we shift the 12 first bits */
282 time.tv_usec <<= 12;
283 time.tv_usec = htonl(time.tv_usec);
284 memcpy(sqn, &time.tv_sec, 4);
285 memcpy(sqn + 4, &time.tv_usec, 2);
286 }
287
288 /** initialize peers SQN to the current system time at startup */
289 static void __attribute__ ((constructor))init_sqn(void)
290 {
291 update_sqn(peer_sqn_buf, 0);
292 }
293
294 /**
295 * Binary represnation of the polynom T^160 + T^5 + T^3 + T^2 + 1
296 */
297 static u_int8_t g[] = {
298 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x2d
301 };
302
303 /**
304 * Predefined random bits from the RAND Corporation book
305 */
306 static u_int8_t a[] = {
307 0x9d, 0xe9, 0xc9, 0xc8, 0xef, 0xd5, 0x78, 0x11,
308 0x48, 0x23, 0x14, 0x01, 0x90, 0x1f, 0x2d, 0x49,
309 0x3f, 0x4c, 0x63, 0x65
310 };
311
312 /**
313 * Predefined random bits from the RAND Corporation book
314 */
315 static u_int8_t b[] = {
316 0x75, 0xef, 0xd1, 0x5c, 0x4b, 0x8f, 0x8f, 0x51,
317 0x4e, 0xf3, 0xbc, 0xc3, 0x79, 0x4a, 0x76, 0x5e,
318 0x7e, 0xec, 0x45, 0xe0
319 };
320
321 /**
322 * Multiplicate two mpz_t with bits interpreted as polynoms.
323 */
324 static void mpz_mul_poly(mpz_t r, mpz_t a, mpz_t b)
325 {
326 mpz_t bm, rm;
327 int current = 0, shifted = 0, shift;
328
329 mpz_init_set(bm, b);
330 mpz_init_set_ui(rm, 0);
331 /* scan through a, for each found bit: */
332 while ((current = mpz_scan1(a, current)) != ULONG_MAX)
333 {
334 /* XOR shifted b into r */
335 shift = current - shifted;
336 mpz_mul_2exp(bm, bm, shift);
337 shifted += shift;
338 mpz_xor(rm, rm, bm);
339 current++;
340 }
341
342 mpz_swap(r, rm);
343 mpz_clear(rm);
344 mpz_clear(bm);
345 }
346
347 /**
348 * Calculate the sum of a + b interpreted as polynoms.
349 */
350 static void mpz_add_poly(mpz_t res, mpz_t a, mpz_t b)
351 {
352 /* addition of polynominals is just the XOR */
353 mpz_xor(res, a, b);
354 }
355
356 /**
357 * Calculate the remainder of a/b interpreted as polynoms.
358 */
359 static void mpz_mod_poly(mpz_t r, mpz_t a, mpz_t b)
360 {
361 /* Example:
362 * a = 10001010
363 * b = 00000101
364 */
365 int a_bit, b_bit, diff;
366 mpz_t bm, am;
367
368 mpz_init_set(am, a);
369 mpz_init(bm);
370
371 a_bit = mpz_sizeinbase(a, 2);
372 b_bit = mpz_sizeinbase(b, 2);
373
374 /* don't do anything if b > a */
375 if (a_bit >= b_bit)
376 {
377 /* shift b left to align up most signaficant "1" to a:
378 * a = 10001010
379 * b = 10100000
380 */
381 mpz_mul_2exp(bm, b, a_bit - b_bit);
382 do
383 {
384 /* XOR b into a, this kills the most significant "1":
385 * a = 00101010
386 */
387 mpz_xor(am, am, bm);
388 /* find the next most significant "1" in a, and align up b:
389 * a = 00101010
390 * b = 00101000
391 */
392 diff = a_bit - mpz_sizeinbase(am, 2);
393 mpz_div_2exp(bm, bm, diff);
394 a_bit -= diff;
395 }
396 while (b_bit <= mpz_sizeinbase(bm, 2));
397 /* While b is not shifted to its original value */
398 }
399 /* after another iteration:
400 * a = 00000010
401 * which is the polynomial modulo
402 */
403
404 mpz_swap(r, am);
405 mpz_clear(am);
406 mpz_clear(bm);
407 }
408
409 /**
410 * Step 4 of the various fx() functions:
411 * Polynomial whiten calculations
412 */
413 static void step4(private_eap_aka_t *this, u_int8_t x[])
414 {
415 mpz_t xm, am, bm, gm;
416
417 mpz_init(xm);
418 mpz_init(am);
419 mpz_init(bm);
420 mpz_init(gm);
421
422 mpz_import(xm, HASH_SIZE_SHA1, 1, 1, 1, 0, x);
423 mpz_import(am, sizeof(a), 1, 1, 1, 0, a);
424 mpz_import(bm, sizeof(b), 1, 1, 1, 0, b);
425 mpz_import(gm, sizeof(g), 1, 1, 1, 0, g);
426
427 mpz_mul_poly(xm, am, xm);
428 mpz_add_poly(xm, bm, xm);
429 mpz_mod_poly(xm, xm, gm);
430
431 mpz_export(x, NULL, 1, HASH_SIZE_SHA1, 1, 0, xm);
432
433 mpz_clear(xm);
434 mpz_clear(am);
435 mpz_clear(bm);
436 mpz_clear(gm);
437 }
438
439 /**
440 * Step 3 of the various fx() functions:
441 * XOR the key into the SHA1 IV
442 */
443 static void step3(private_eap_aka_t *this,
444 chunk_t k, chunk_t payload, u_int8_t h[])
445 {
446 u_int8_t buf[64];
447
448 if (payload.len < sizeof(buf))
449 {
450 /* pad c with zeros */
451 memset(buf, 0, sizeof(buf));
452 memcpy(buf, payload.ptr, payload.len);
453 payload.ptr = buf;
454 payload.len = sizeof(buf);
455 }
456 else
457 {
458 /* not more than 512 bits can be G()-ed */
459 payload.len = sizeof(buf);
460 }
461
462 /* use the keyed hasher to build the hash */
463 this->keyed_prf->set_key(this->keyed_prf, k);
464 this->keyed_prf->get_bytes(this->keyed_prf, payload, h);
465 }
466
467 /**
468 * Calculation function for f2(), f3(), f4()
469 */
470 static void fx(private_eap_aka_t *this,
471 u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
472 {
473 chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
474 u_int8_t h[HASH_SIZE_SHA1];
475 u_int8_t i;
476
477 for (i = 0; i < 2; i++)
478 {
479 memset(payload.ptr, 0x5c, payload.len);
480 payload.ptr[11] ^= f;
481 memxor(payload.ptr + 12, fmk.ptr, fmk.len);
482 memxor(payload.ptr + 24, rand.ptr, rand.len);
483
484 payload.ptr[3] ^= i;
485 payload.ptr[19] ^= i;
486 payload.ptr[35] ^= i;
487 payload.ptr[51] ^= i;
488
489 step3(this, k, payload, h);
490 step4(this, h);
491 memcpy(out + i * 8, h, 8);
492 }
493 }
494
495 /**
496 * Calculation function of f1() and f1star()
497 */
498 static void f1x(private_eap_aka_t *this,
499 u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
500 chunk_t amf, u_int8_t mac[])
501 {
502 /* generate MAC = f1(FMK, SQN, RAND, AMF)
503 * K is loaded into hashers IV; FMK, RAND, SQN, AMF are XORed in a 512-bit
504 * payload which gets hashed
505 */
506 chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
507 u_int8_t h[HASH_SIZE_SHA1];
508
509 memset(payload.ptr, 0x5c, PAYLOAD_LENGTH);
510 payload.ptr[11] ^= f;
511 memxor(payload.ptr + 12, fmk.ptr, fmk.len);
512 memxor(payload.ptr + 16, rand.ptr, rand.len);
513 memxor(payload.ptr + 34, sqn.ptr, sqn.len);
514 memxor(payload.ptr + 42, amf.ptr, amf.len);
515
516 step3(this, k, payload, h);
517 step4(this, h);
518 memcpy(mac, h, MAC_LENGTH);
519 }
520
521 /**
522 * Calculation function of f5() and f5star()
523 */
524 static void f5x(private_eap_aka_t *this,
525 u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
526 {
527 chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
528 u_int8_t h[HASH_SIZE_SHA1];
529
530 memset(payload.ptr, 0x5c, payload.len);
531 payload.ptr[11] ^= f;
532 memxor(payload.ptr + 12, fmk.ptr, fmk.len);
533 memxor(payload.ptr + 16, rand.ptr, rand.len);
534
535 step3(this, k, payload, h);
536 step4(this, h);
537 memcpy(ak, h, AK_LENGTH);
538 }
539
540 /**
541 * Calculate the MAC from a RAND, SQN, AMF value using K
542 */
543 static void f1(private_eap_aka_t *this, chunk_t k, chunk_t rand, chunk_t sqn,
544 chunk_t amf, u_int8_t mac[])
545 {
546 f1x(this, F1, k, rand, sqn, amf, mac);
547 DBG3(DBG_IKE, "MAC %b", mac, MAC_LENGTH);
548 }
549
550 /**
551 * Calculate the MACS from a RAND, SQN, AMF value using K
552 */
553 static void f1star(private_eap_aka_t *this, chunk_t k, chunk_t rand,
554 chunk_t sqn, chunk_t amf, u_int8_t macs[])
555 {
556 f1x(this, F1STAR, k, rand, sqn, amf, macs);
557 DBG3(DBG_IKE, "MACS %b", macs, MAC_LENGTH);
558 }
559
560 /**
561 * Calculate RES from RAND using K
562 */
563 static void f2(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t res[])
564 {
565 fx(this, F2, k, rand, res);
566 DBG3(DBG_IKE, "RES %b", res, RES_LENGTH);
567 }
568
569 /**
570 * Calculate CK from RAND using K
571 */
572 static void f3(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ck[])
573 {
574 fx(this, F3, k, rand, ck);
575 DBG3(DBG_IKE, "CK %b", ck, CK_LENGTH);
576 }
577
578 /**
579 * Calculate IK from RAND using K
580 */
581 static void f4(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ik[])
582 {
583 fx(this, F4, k, rand, ik);
584 DBG3(DBG_IKE, "IK %b", ik, IK_LENGTH);
585 }
586
587 /**
588 * Calculate AK from a RAND using K
589 */
590 static void f5(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ak[])
591 {
592 f5x(this, F5, k, rand, ak);
593 DBG3(DBG_IKE, "AK %b", ak, AK_LENGTH);
594 }
595
596 /**
597 * Calculate AKS from a RAND using K
598 */
599 static void f5star(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t aks[])
600 {
601 f5x(this, F5STAR, k, rand, aks);
602 DBG3(DBG_IKE, "AKS %b", aks, AK_LENGTH);
603 }
604
605 /**
606 * derive the keys needed for EAP_AKA
607 */
608 static bool derive_keys(private_eap_aka_t *this, identification_t *id)
609 {
610 chunk_t ck, ik, mk, identity, tmp;
611
612 ck = chunk_alloca(CK_LENGTH);
613 ik = chunk_alloca(IK_LENGTH);
614 mk = chunk_alloca(MK_LENGTH);
615 identity = id->get_encoding(id);
616
617 /* MK = SHA1( Identity | IK | CK ) */
618 f3(this, this->k, this->rand, ck.ptr);
619 f4(this, this->k, this->rand, ik.ptr);
620 DBG3(DBG_IKE, "Identity %B", &identity);
621 tmp = chunk_cata("ccc", identity, ik, ck);
622 DBG3(DBG_IKE, "Identity|IK|CK %B", &tmp);
623 this->sha1->get_hash(this->sha1, tmp, mk.ptr);
624
625 /* K_encr | K_auth | MSK | EMSK = prf(0) | prf(0)
626 * FIPS PRF has 320 bit block size, we need 160 byte for keys
627 * => run prf four times */
628 this->prf->set_key(this->prf, mk);
629 tmp = chunk_alloca(this->prf->get_block_size(this->prf) * 4);
630 this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr);
631 this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
632 this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
633 this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
634 chunk_free(&this->k_encr);
635 chunk_free(&this->k_auth);
636 chunk_free(&this->msk);
637 chunk_free(&this->emsk);
638 chunk_split(tmp, "aaaa", 16, &this->k_encr, 16, &this->k_auth,
639 64, &this->msk, 64, &this->emsk);
640 DBG3(DBG_IKE, "MK %B", &mk);
641 DBG3(DBG_IKE, "PRF res %B", &tmp);
642 DBG3(DBG_IKE, "K_encr %B", &this->k_encr);
643 DBG3(DBG_IKE, "K_auth %B", &this->k_auth);
644 DBG3(DBG_IKE, "MSK %B", &this->msk);
645 DBG3(DBG_IKE, "EMSK %B", &this->emsk);
646 return TRUE;
647 }
648
649 /*
650 * Get a shared key from ipsec.secrets.
651 * We use the standard keys as used in preshared key authentication. As
652 * these keys have an undefined length, we:
653 * - strip them if they are longer
654 * - fill them up with '\0' if they are shorter
655 */
656 static status_t load_key(identification_t *me, identification_t *other, chunk_t *k)
657 {
658 shared_key_t *shared;
659 chunk_t key;
660
661 shared = charon->credentials->get_shared(charon->credentials, SHARED_EAP,
662 me, other);
663 if (shared == NULL)
664 {
665 return NOT_FOUND;
666 }
667 key = shared->get_key(shared);
668 chunk_free(k);
669 *k = chunk_alloc(K_LENGTH);
670 memset(k->ptr, '\0', k->len);
671 memcpy(k->ptr, key.ptr, min(key.len, k->len));
672 shared->destroy(shared);
673 return SUCCESS;
674 }
675
676 /**
677 * skip EAP_AKA header in message and returns its AKA subtype
678 */
679 static aka_subtype_t read_header(chunk_t *message)
680 {
681 aka_subtype_t type;
682
683 if (message->len < 8)
684 {
685 *message = chunk_empty;
686 return 0;
687 }
688 type = *(message->ptr + 5);
689 *message = chunk_skip(*message, 8);
690 return type;
691 }
692
693 /**
694 * read the next attribute from the chunk data
695 */
696 static aka_attribute_t read_attribute(chunk_t *data, chunk_t *attr_data)
697 {
698 aka_attribute_t attribute;
699 size_t length;
700
701 DBG3(DBG_IKE, "reading attribute from %B", data);
702
703 if (data->len < 2)
704 {
705 return AT_END;
706 }
707 /* read attribute and length */
708 attribute = *data->ptr++;
709 length = *data->ptr++ * 4 - 2;
710 data->len -= 2;
711 DBG3(DBG_IKE, "found attribute %N with length %d",
712 aka_attribute_names, attribute, length);
713 if (length > data->len)
714 {
715 return AT_END;
716 }
717 /* apply attribute value to attr_data */
718 attr_data->len = length;
719 attr_data->ptr = data->ptr;
720 /* update data to point to next attribute */
721 *data = chunk_skip(*data, length);
722 return attribute;
723 }
724
725 /**
726 * Build an AKA payload from different attributes.
727 * The variable argument takes an aka_attribute_t
728 * followed by its data in a chunk.
729 */
730 static eap_payload_t *build_aka_payload(private_eap_aka_t *this, eap_code_t code,
731 u_int8_t identifier, aka_subtype_t type, ...)
732 {
733 chunk_t message = chunk_alloca(512); /* is enought for all current messages */
734 chunk_t pos = message;
735 eap_payload_t *payload;
736 va_list args;
737 aka_attribute_t attr;
738 u_int8_t *mac_pos = NULL;
739
740 /* write EAP header, skip length bytes */
741 *pos.ptr++ = code;
742 *pos.ptr++ = identifier;
743 pos.ptr += 2;
744 pos.len -= 4;
745 /* write AKA header with type and subtype, null reserved bytes */
746 *pos.ptr++ = EAP_AKA;
747 *pos.ptr++ = type;
748 *pos.ptr++ = 0;
749 *pos.ptr++ = 0;
750 pos.len -= 4;
751
752 va_start(args, type);
753 while ((attr = va_arg(args, aka_attribute_t)) != AT_END)
754 {
755 chunk_t data = va_arg(args, chunk_t);
756
757 DBG3(DBG_IKE, "building %N %B", aka_attribute_names, attr, &data);
758
759 /* write attribute header */
760 *pos.ptr++ = attr;
761 pos.len--;
762
763 switch (attr)
764 {
765 case AT_RES:
766 {
767 /* attribute length in 4byte words */
768 *pos.ptr = data.len/4 + 1;
769 pos = chunk_skip(pos, 1);
770 /* RES length in bits */
771 *(u_int16_t*)pos.ptr = htons(data.len * 8);
772 pos = chunk_skip(pos, sizeof(u_int16_t));
773 memcpy(pos.ptr, data.ptr, data.len);
774 pos = chunk_skip(pos, data.len);
775 break;
776 }
777 case AT_AUTN:
778 case AT_RAND:
779 {
780 *pos.ptr++ = data.len/4 + 1; pos.len--;
781 *pos.ptr++ = 0; pos.len--;
782 *pos.ptr++ = 0; pos.len--;
783 memcpy(pos.ptr, data.ptr, data.len);
784 pos = chunk_skip(pos, data.len);
785 break;
786 }
787 case AT_MAC:
788 {
789 *pos.ptr++ = 5; pos.len--;
790 *pos.ptr++ = 0; pos.len--;
791 *pos.ptr++ = 0; pos.len--;
792 mac_pos = pos.ptr;
793 /* MAC is calculated over message including zeroed AT_MAC attribute */
794 memset(mac_pos, 0, AT_MAC_LENGTH);
795 pos.ptr += AT_MAC_LENGTH;
796 pos.len -= AT_MAC_LENGTH;
797 break;
798 }
799 default:
800 {
801 /* length is data length in 4-bytes + 1 for header */
802 *pos.ptr = data.len/4 + 1;
803 pos = chunk_skip(pos, 1);
804 memcpy(pos.ptr, data.ptr, data.len);
805 pos = chunk_skip(pos, data.len);
806 }
807 }
808 }
809 va_end(args);
810
811 /* calculate message length, write into header */
812 message.len = pos.ptr - message.ptr;
813 *(u_int16_t*)(message.ptr + 2) = htons(message.len);
814
815 /* create MAC if AT_MAC attribte was included */
816 if (mac_pos)
817 {
818 this->signer->set_key(this->signer, this->k_auth);
819 DBG3(DBG_IKE, "AT_MAC signature of %B", &message);
820 DBG3(DBG_IKE, "using key %B", &this->k_auth);
821 this->signer->get_signature(this->signer, message, mac_pos);
822 DBG3(DBG_IKE, "is %b", mac_pos, AT_MAC_LENGTH);
823 }
824
825 /* payload constructor takes data with some bytes skipped */
826 payload = eap_payload_create_data(message);
827
828 DBG3(DBG_IKE, "created EAP message %B", &message);
829 return payload;
830 }
831
832 /**
833 * generate a new non-zero identifier
834 */
835 static u_char get_identifier()
836 {
837 u_char id;
838
839 do {
840 id = random();
841 } while (!id);
842 return id;
843 }
844
845 /**
846 * Initiate a AKA-Challenge using SQN
847 */
848 static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn,
849 eap_payload_t **out)
850 {
851 rng_t *rng;
852 chunk_t mac, ak, autn;
853
854 mac = chunk_alloca(MAC_LENGTH);
855 ak = chunk_alloca(AK_LENGTH);
856 chunk_free(&this->rand);
857 chunk_free(&this->xres);
858
859 /* generate RAND:
860 * we use a registered RNG, not f0() proposed in S.S0055
861 */
862 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
863 if (!rng)
864 {
865 DBG1(DBG_IKE, "generating RAND for EAP-AKA authentication failed");
866 return FAILED;
867 }
868 rng->allocate_bytes(rng, RAND_LENGTH, &this->rand);
869 rng->destroy(rng);
870
871 # ifdef TEST_VECTORS
872 /* Test vector for RAND */
873 u_int8_t test_rand[] = {
874 0x4b,0x05,0x2b,0x20,0xe2,0xa0,0x6c,0x8f,
875 0xf7,0x00,0xda,0x51,0x2b,0x4e,0x11,0x1e,
876 };
877 memcpy(this->rand.ptr, test_rand, this->rand.len);
878 # endif /* TEST_VECTORS */
879
880 /* Get the shared key K: */
881 if (load_key(this->server, this->peer, &this->k) != SUCCESS)
882 {
883 DBG1(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
884 "with EAP-AKA", this->server, this->peer);
885 return FAILED;
886 }
887
888 # ifdef TEST_VECTORS
889 /* Test vector for K */
890 u_int8_t test_k[] = {
891 0xad,0x1b,0x5a,0x15,0x9b,0xe8,0x6b,0x2c,
892 0xa6,0x6c,0x7a,0xe4,0x0b,0xba,0x9b,0x9d,
893 };
894 memcpy(this->k.ptr, test_k, this->k.len);
895 # endif /* TEST_VECTORS */
896
897 /* generate MAC */
898 f1(this, this->k, this->rand, sqn, amf, mac.ptr);
899
900 /* generate AK */
901 f5(this, this->k, this->rand, ak.ptr);
902
903 /* precalculate XRES as expected from client */
904 this->xres = chunk_alloc(RES_LENGTH);
905 f2(this, this->k, this->rand, this->xres.ptr);
906
907 /* calculate AUTN = (SQN xor AK) || AMF || MAC */
908 autn = chunk_cata("ccc", sqn, amf, mac);
909 memxor(autn.ptr, ak.ptr, ak.len);
910 DBG3(DBG_IKE, "AUTN %B", &autn);
911
912
913 /* derive K_encr, K_auth, MSK, EMSK */
914 derive_keys(this, this->peer);
915
916 /* build payload */
917 *out = build_aka_payload(this, EAP_REQUEST, get_identifier(), AKA_CHALLENGE,
918 AT_RAND, this->rand, AT_AUTN, autn, AT_MAC,
919 chunk_empty, AT_END);
920 return NEED_MORE;
921 }
922
923 /**
924 * Implementation of eap_method_t.initiate for an EAP_AKA server
925 */
926 static status_t server_initiate(private_eap_aka_t *this, eap_payload_t **out)
927 {
928 chunk_t sqn = chunk_alloca(SQN_LENGTH);
929
930 /* we use an offset of 3 minutes to tolerate clock inaccuracy
931 * without the need to synchronize sequence numbers */
932 update_sqn(sqn.ptr, 180);
933
934 # ifdef TEST_VECTORS
935 /* Test vector for SQN */
936 u_int8_t test_sqn[] = {0x00,0x00,0x00,0x00,0x00,0x01};
937 memcpy(sqn.ptr, test_sqn, sqn.len);
938 # endif /* TEST_VECTORS */
939
940 return server_initiate_challenge(this, sqn, out);
941 }
942
943 static status_t server_process_synchronize(private_eap_aka_t *this,
944 eap_payload_t *in, eap_payload_t **out)
945 {
946 chunk_t attr, auts = chunk_empty, pos, message, macs, xmacs, sqn, aks, amf;
947 u_int i;
948
949 message = in->get_data(in);
950 pos = message;
951 read_header(&pos);
952
953 /* iterate over attributes */
954 while (TRUE)
955 {
956 aka_attribute_t attribute = read_attribute(&pos, &attr);
957 switch (attribute)
958 {
959 case AT_END:
960 break;
961 case AT_AUTS:
962 auts = attr;
963 continue;
964 default:
965 if (attribute >= 0 && attribute <= 127)
966 {
967 DBG1(DBG_IKE, "found non skippable attribute %N",
968 aka_attribute_names, attribute);
969 return FAILED;
970 }
971 DBG1(DBG_IKE, "ignoring skippable attribute %N",
972 aka_attribute_names, attribute);
973 continue;
974 }
975 break;
976 }
977
978 if (auts.len != AUTS_LENGTH)
979 {
980 DBG1(DBG_IKE, "synchronization request didn't contain useable AUTS");
981 return FAILED;
982 }
983
984 chunk_split(auts, "mm", SQN_LENGTH, &sqn, MAC_LENGTH, &macs);
985 aks = chunk_alloca(AK_LENGTH);
986 f5star(this, this->k, this->rand, aks.ptr);
987 /* decrypt serial number by XORing AKS */
988 memxor(sqn.ptr, aks.ptr, aks.len);
989
990 /* verify MACS */
991 xmacs = chunk_alloca(MAC_LENGTH);
992 amf = chunk_alloca(AMF_LENGTH);
993 /* an AMF of zero is used for MACS calculation */
994 memset(amf.ptr, 0, amf.len);
995 f1star(this, this->k, this->rand, sqn, amf, xmacs.ptr);
996 if (!chunk_equals(macs, xmacs))
997 {
998 DBG1(DBG_IKE, "received MACS does not match XMACS");
999 DBG3(DBG_IKE, "MACS %B XMACS %B", &macs, &xmacs);
1000 return FAILED;
1001 }
1002
1003 /* retry the challenge with the received SQN + 1*/
1004 for (i = SQN_LENGTH - 1; i >= 0; i--)
1005 {
1006 if (++sqn.ptr[i] != 0)
1007 {
1008 break;
1009 }
1010 }
1011 return server_initiate_challenge(this, sqn, out);
1012 }
1013
1014 /**
1015 * process an AKA_Challenge response
1016 */
1017 static status_t server_process_challenge(private_eap_aka_t *this, eap_payload_t *in)
1018 {
1019 chunk_t attr, res = chunk_empty, at_mac = chunk_empty, pos, message;
1020
1021 message = in->get_data(in);
1022 pos = message;
1023 read_header(&pos);
1024
1025 /* iterate over attributes */
1026 while (TRUE)
1027 {
1028 aka_attribute_t attribute = read_attribute(&pos, &attr);
1029 switch (attribute)
1030 {
1031 case AT_END:
1032 break;
1033 case AT_RES:
1034 res = attr;
1035 if (attr.len == 2 + RES_LENGTH &&
1036 *(u_int16_t*)attr.ptr == htons(RES_LENGTH * 8))
1037 {
1038 res = chunk_skip(attr, 2);
1039 }
1040 continue;
1041
1042 case AT_MAC:
1043 attr = chunk_skip(attr, 2);
1044 at_mac = chunk_clonea(attr);
1045 /* zero MAC in message for MAC verification */
1046 memset(attr.ptr, 0, attr.len);
1047 continue;
1048 default:
1049 if (attribute >= 0 && attribute <= 127)
1050 {
1051 DBG1(DBG_IKE, "found non skippable attribute %N",
1052 aka_attribute_names, attribute);
1053 return FAILED;
1054 }
1055 DBG1(DBG_IKE, "ignoring skippable attribute %N",
1056 aka_attribute_names, attribute);
1057 continue;
1058 }
1059 break;
1060 }
1061
1062 /* verify EAP message MAC AT_MAC */
1063 {
1064 this->signer->set_key(this->signer, this->k_auth);
1065 DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
1066 DBG3(DBG_IKE, "using key %B", &this->k_auth);
1067 if (!this->signer->verify_signature(this->signer, message, at_mac))
1068 {
1069 DBG1(DBG_IKE, "MAC in AT_MAC attribute verification failed");
1070 return FAILED;
1071 }
1072 }
1073
1074 /* compare received RES against stored precalculated XRES */
1075 if (!chunk_equals(res, this->xres))
1076 {
1077 DBG1(DBG_IKE, "received RES does not match XRES");
1078 DBG3(DBG_IKE, "RES %Bb XRES %B", &res, &this->xres);
1079 return FAILED;
1080 }
1081 return SUCCESS;
1082 }
1083
1084 /**
1085 * Implementation of eap_method_t.process for EAP_AKA servers
1086 */
1087 static status_t server_process(private_eap_aka_t *this,
1088 eap_payload_t *in, eap_payload_t **out)
1089 {
1090 chunk_t message;
1091 aka_subtype_t type;
1092
1093 message = in->get_data(in);
1094 type = read_header(&message);
1095
1096 DBG3(DBG_IKE, "received EAP message %B", &message);
1097
1098 switch (type)
1099 {
1100 case AKA_CHALLENGE:
1101 {
1102 return server_process_challenge(this, in);
1103 }
1104 case AKA_AUTHENTICATION_REJECT:
1105 case AKA_CLIENT_ERROR:
1106 {
1107 DBG1(DBG_IKE, "received %N, authentication failed",
1108 aka_subtype_names, type);
1109 return FAILED;
1110 }
1111 case AKA_SYNCHRONIZATION_FAILURE:
1112 {
1113 DBG1(DBG_IKE, "received %N, retrying with received SQN",
1114 aka_subtype_names, type);
1115 return server_process_synchronize(this, in, out);
1116 }
1117 default:
1118 DBG1(DBG_IKE, "received unknown AKA subtype %N, authentication failed",
1119 aka_subtype_names, type);
1120 return FAILED;
1121 }
1122 }
1123
1124 /**
1125 * Process an incoming AKA-Challenge client side
1126 */
1127 static status_t peer_process_challenge(private_eap_aka_t *this,
1128 eap_payload_t *in, eap_payload_t **out)
1129 {
1130 chunk_t attr = chunk_empty;
1131 chunk_t autn = chunk_empty, at_mac = chunk_empty;
1132 chunk_t ak, sqn, sqn_ak, mac, xmac, res, amf, message, pos;
1133 u_int8_t identifier;
1134
1135 ak = chunk_alloca(AK_LENGTH);
1136 xmac = chunk_alloca(MAC_LENGTH);
1137 res = chunk_alloca(RES_LENGTH);
1138 chunk_free(&this->rand);
1139
1140 message = in->get_data(in);
1141 pos = message;
1142 read_header(&pos);
1143 identifier = in->get_identifier(in);
1144
1145 DBG3(DBG_IKE, "reading attributes from %B", &pos);
1146
1147 /* iterate over attributes */
1148 while (TRUE)
1149 {
1150 aka_attribute_t attribute = read_attribute(&pos, &attr);
1151 switch (attribute)
1152 {
1153 case AT_END:
1154 break;
1155 case AT_RAND:
1156 this->rand = chunk_clone(chunk_skip(attr, 2));
1157 continue;
1158 case AT_AUTN:
1159 autn = chunk_skip(attr, 2);
1160 continue;
1161 case AT_MAC:
1162 attr = chunk_skip(attr, 2);
1163 at_mac = chunk_clonea(attr);
1164 /* set MAC in message to zero for own MAC verification */
1165 memset(attr.ptr, 0, attr.len);
1166 continue;
1167 default:
1168 if (attribute >= 0 && attribute <= 127)
1169 {
1170 /* non skippable attribute, abort */
1171 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
1172 AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
1173 DBG1(DBG_IKE, "found non skippable attribute %N, sending %N %d",
1174 aka_attribute_names, attribute,
1175 aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
1176 return NEED_MORE;
1177 }
1178 DBG1(DBG_IKE, "ignoring skippable attribute %N",
1179 aka_attribute_names, attribute);
1180 continue;
1181 }
1182 break;
1183 }
1184
1185 if (this->rand.len != RAND_LENGTH || autn.len != AUTN_LENGTH)
1186 {
1187 /* required attributes wrong/not found, abort */
1188 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
1189 AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
1190 DBG1(DBG_IKE, "could not find valid RAND/AUTN attribute, sending %N %d",
1191 aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
1192 return NEED_MORE;
1193 }
1194
1195 DBG3(DBG_IKE, "using autn %B", &autn);
1196 /* split up AUTN = SQN xor AK | AMF | MAC */
1197 chunk_split(autn, "mmm", SQN_LENGTH, &sqn_ak, AMF_LENGTH, &amf, MAC_LENGTH, &mac);
1198
1199 /* Get the shared key K: */
1200 chunk_free(&this->k);
1201 if (load_key(this->peer, this->server, &this->k) != SUCCESS)
1202 {
1203 *out = build_aka_payload(this, EAP_RESPONSE, identifier,
1204 AKA_AUTHENTICATION_REJECT, AT_END);
1205 DBG3(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
1206 "with EAP-AKA, sending %N", this->peer, this->server,
1207 aka_subtype_names, AKA_AUTHENTICATION_REJECT);
1208 return NEED_MORE;
1209 }
1210 DBG3(DBG_IKE, "using K %B", &this->k);
1211 # ifdef TEST_VECTORS
1212 /* Test vector for K */
1213 u_int8_t test_k[] = {
1214 0xad,0x1b,0x5a,0x15,0x9b,0xe8,0x6b,0x2c,
1215 0xa6,0x6c,0x7a,0xe4,0x0b,0xba,0x9b,0x9d,
1216 };
1217 memcpy(this->k.ptr, test_k, this->k.len);
1218 # endif /* TEST_VECTORS */
1219
1220 /* calculate anonymity key AK */
1221 f5(this, this->k, this->rand, ak.ptr);
1222 DBG3(DBG_IKE, "using rand %B", &this->rand);
1223 DBG3(DBG_IKE, "using ak %B", &ak);
1224 /* XOR AK into SQN to decrypt it */
1225
1226 sqn = chunk_clonea(sqn_ak);
1227
1228 DBG3(DBG_IKE, "using ak xor sqn %B", &sqn_ak);
1229 memxor(sqn.ptr, ak.ptr, sqn.len);
1230 DBG3(DBG_IKE, "using sqn %B", &sqn);
1231
1232 /* calculate expected MAC and compare against received one */
1233 f1(this, this->k, this->rand, sqn, amf, xmac.ptr);
1234 if (!chunk_equals(mac, xmac))
1235 {
1236 *out = build_aka_payload(this, EAP_RESPONSE, identifier,
1237 AKA_AUTHENTICATION_REJECT, AT_END);
1238 DBG1(DBG_IKE, "received MAC does not match XMAC, sending %N",
1239 aka_subtype_names, AKA_AUTHENTICATION_REJECT);
1240 DBG3(DBG_IKE, "MAC %B\nXMAC %B", &mac, &xmac);
1241 return NEED_MORE;
1242 }
1243
1244 #if SEQ_CHECK
1245 if (memcmp(peer_sqn.ptr, sqn.ptr, sqn.len) >= 0)
1246 {
1247 /* sequence number invalid. send AUTS */
1248 chunk_t auts, macs, aks, amf;
1249
1250 macs = chunk_alloca(MAC_LENGTH);
1251 aks = chunk_alloca(AK_LENGTH);
1252 amf = chunk_alloca(AMF_LENGTH);
1253
1254 /* AMF is set to zero in AKA_SYNCHRONIZATION_FAILURE */
1255 memset(amf.ptr, 0, amf.len);
1256 /* AKS = f5*(RAND) */
1257 f5star(this, this->k, this->rand, aks.ptr);
1258 /* MACS = f1*(RAND) */
1259 f1star(this, this->k, this->rand, peer_sqn, amf, macs.ptr);
1260 /* AUTS = SQN xor AKS | MACS */
1261 memxor(aks.ptr, peer_sqn.ptr, aks.len);
1262 auts = chunk_cata("cc", aks, macs);
1263
1264 *out = build_aka_payload(this, EAP_RESPONSE, identifier,
1265 AKA_SYNCHRONIZATION_FAILURE,
1266 AT_AUTS, auts, AT_END);
1267 DBG1(DBG_IKE, "received SQN invalid, sending %N",
1268 aka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
1269 DBG3(DBG_IKE, "received SQN %B\ncurrent SQN %B", &sqn, &peer_sqn);
1270 return NEED_MORE;
1271 }
1272 #endif /* SEQ_CHECK */
1273
1274 /* derive K_encr, K_auth, MSK, EMSK */
1275 derive_keys(this, this->peer);
1276
1277 /* verify EAP message MAC AT_MAC */
1278 DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
1279 DBG3(DBG_IKE, "using key %B", &this->k_auth);
1280 this->signer->set_key(this->signer, this->k_auth);
1281 if (!this->signer->verify_signature(this->signer, message, at_mac))
1282 {
1283 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
1284 AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
1285 DBG1(DBG_IKE, "MAC in AT_MAC attribute verification "
1286 "failed, sending %N %d", aka_attribute_names,
1287 AT_CLIENT_ERROR_CODE, 0);
1288 return NEED_MORE;
1289 }
1290
1291 /* update stored SQN to the received one */
1292 memcpy(peer_sqn.ptr, sqn.ptr, sqn.len);
1293
1294 /* calculate RES */
1295 f2(this, this->k, this->rand, res.ptr);
1296
1297 /* build response */
1298 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CHALLENGE,
1299 AT_RES, res, AT_MAC, chunk_empty, AT_END);
1300 return NEED_MORE;
1301 }
1302
1303 /**
1304 * Process an incoming AKA-Notification as client
1305 */
1306 static status_t peer_process_notification(private_eap_aka_t *this,
1307 eap_payload_t *in, eap_payload_t **out)
1308 {
1309 chunk_t message, pos, attr;
1310 u_int8_t identifier;
1311
1312 message = in->get_data(in);
1313 pos = message;
1314 read_header(&pos);
1315 identifier = in->get_identifier(in);
1316
1317 DBG3(DBG_IKE, "reading attributes from %B", &pos);
1318
1319 /* iterate over attributes */
1320 while (TRUE)
1321 {
1322 aka_attribute_t attribute = read_attribute(&pos, &attr);
1323 switch (attribute)
1324 {
1325 case AT_END:
1326 break;
1327 case AT_NOTIFICATION:
1328 {
1329 u_int16_t code;
1330
1331 if (attr.len != 2)
1332 {
1333 DBG1(DBG_IKE, "received invalid AKA notification, ignored");
1334 continue;
1335 }
1336 code = ntohs(*(u_int16_t*)attr.ptr);
1337 switch (code)
1338 {
1339 case 0:
1340 DBG1(DBG_IKE, "received AKA notification 'general "
1341 "failure after authentication' (%d)", code);
1342 return FAILED;
1343 case 16384:
1344 DBG1(DBG_IKE, "received AKA notification 'general "
1345 "failure' (%d)", code);
1346 return FAILED;
1347 case 32768:
1348 DBG1(DBG_IKE, "received AKA notification 'successfully "
1349 "authenticated' (%d)", code);
1350 continue;
1351 case 1026:
1352 DBG1(DBG_IKE, "received AKA notification 'access "
1353 "temporarily denied' (%d)", code);
1354 return FAILED;
1355 case 1031:
1356 DBG1(DBG_IKE, "received AKA notification 'not "
1357 "subscribed to service' (%d)", code);
1358 return FAILED;
1359 default:
1360 DBG1(DBG_IKE, "received AKA notification code %d, "
1361 "ignored", code);
1362 continue;
1363 }
1364 }
1365 default:
1366 if (attribute >= 0 && attribute <= 127)
1367 {
1368 DBG1(DBG_IKE, "ignoring non-skippable attribute %N in %N",
1369 aka_attribute_names, attribute, aka_subtype_names,
1370 AKA_NOTIFICATION);
1371 }
1372 else
1373 {
1374 DBG1(DBG_IKE, "ignoring skippable attribute %N",
1375 aka_attribute_names, attribute);
1376 }
1377 continue;
1378 }
1379 break;
1380 }
1381 return NEED_MORE;
1382 }
1383
1384 /**
1385 * Implementation of eap_method_t.process for an EAP_AKA peer
1386 */
1387 static status_t peer_process(private_eap_aka_t *this,
1388 eap_payload_t *in, eap_payload_t **out)
1389 {
1390 aka_subtype_t type;
1391 chunk_t message;
1392 u_int8_t identifier;
1393
1394 message = in->get_data(in);
1395 type = read_header(&message);
1396 identifier = in->get_identifier(in);
1397
1398 DBG3(DBG_IKE, "received EAP message %B", &message);
1399
1400 switch (type)
1401 {
1402 case AKA_CHALLENGE:
1403 {
1404 return peer_process_challenge(this, in, out);
1405 }
1406 case AKA_NOTIFICATION:
1407 {
1408 return peer_process_notification(this, in, out);
1409 }
1410 default:
1411 {
1412 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
1413 AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
1414 DBG1(DBG_IKE, "received unsupported %N request, sending %N %d",
1415 aka_subtype_names, type,
1416 aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
1417 return NEED_MORE;
1418 }
1419 }
1420 }
1421
1422 /**
1423 * Implementation of eap_method_t.initiate for an EAP AKA peer
1424 */
1425 static status_t peer_initiate(private_eap_aka_t *this, eap_payload_t **out)
1426 {
1427 /* peer never initiates */
1428 return FAILED;
1429 }
1430
1431 /**
1432 * Implementation of eap_method_t.get_type.
1433 */
1434 static eap_type_t get_type(private_eap_aka_t *this, u_int32_t *vendor)
1435 {
1436 *vendor = 0;
1437 return EAP_AKA;
1438 }
1439
1440 /**
1441 * Implementation of eap_method_t.get_msk.
1442 */
1443 static status_t get_msk(private_eap_aka_t *this, chunk_t *msk)
1444 {
1445 if (this->msk.ptr)
1446 {
1447 *msk = this->msk;
1448 return SUCCESS;
1449 }
1450 return FAILED;
1451 }
1452
1453 /**
1454 * Implementation of eap_method_t.is_mutual.
1455 */
1456 static bool is_mutual(private_eap_aka_t *this)
1457 {
1458 return TRUE;
1459 }
1460
1461 /**
1462 * Implementation of eap_method_t.destroy.
1463 */
1464 static void destroy(private_eap_aka_t *this)
1465 {
1466 this->server->destroy(this->server);
1467 this->peer->destroy(this->peer);
1468 DESTROY_IF(this->sha1);
1469 DESTROY_IF(this->signer);
1470 DESTROY_IF(this->prf);
1471 DESTROY_IF(this->keyed_prf);
1472 chunk_free(&this->k_encr);
1473 chunk_free(&this->k_auth);
1474 chunk_free(&this->msk);
1475 chunk_free(&this->emsk);
1476 chunk_free(&this->xres);
1477 chunk_free(&this->k);
1478 chunk_free(&this->rand);
1479 free(this);
1480 }
1481
1482 /**
1483 * generic constructor used by client & server
1484 */
1485 static private_eap_aka_t *eap_aka_create_generic(identification_t *server,
1486 identification_t *peer)
1487 {
1488 private_eap_aka_t *this = malloc_thing(private_eap_aka_t);
1489
1490 this->public.eap_method_interface.initiate = NULL;
1491 this->public.eap_method_interface.process = NULL;
1492 this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
1493 this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
1494 this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
1495 this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
1496
1497 /* private data */
1498 this->server = server->clone(server);
1499 this->peer = peer->clone(peer);
1500 this->k_encr = chunk_empty;
1501 this->k_auth = chunk_empty;
1502 this->msk = chunk_empty;
1503 this->emsk = chunk_empty;
1504 this->xres = chunk_empty;
1505 this->k = chunk_empty;
1506 this->rand = chunk_empty;
1507
1508 this->sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1509 this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
1510 this->prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
1511 this->keyed_prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
1512
1513 if (!this->sha1 || !this->signer || !this->prf || !this->keyed_prf)
1514 {
1515 DBG1(DBG_IKE, "unable to initiate EAP-AKA, FIPS-PRF/SHA1 not supported");
1516 DESTROY_IF(this->sha1);
1517 DESTROY_IF(this->signer);
1518 DESTROY_IF(this->prf);
1519 DESTROY_IF(this->keyed_prf);
1520 destroy(this);
1521 return NULL;
1522 }
1523 return this;
1524 }
1525
1526 /*
1527 * Described in header.
1528 */
1529 eap_aka_t *eap_aka_create_server(identification_t *server, identification_t *peer)
1530 {
1531 private_eap_aka_t *this = eap_aka_create_generic(server, peer);
1532
1533 if (this)
1534 {
1535 this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate;
1536 this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process;
1537 }
1538 return (eap_aka_t*)this;
1539 }
1540
1541 /*
1542 * Described in header.
1543 */
1544 eap_aka_t *eap_aka_create_peer(identification_t *server, identification_t *peer)
1545 {
1546 private_eap_aka_t *this = eap_aka_create_generic(server, peer);
1547
1548 if (this)
1549 {
1550 this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate;
1551 this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
1552 }
1553 return (eap_aka_t*)this;
1554 }
1555