The introduced SHA1_NOFINAL hasher was not sufficient for EAP-AKA,
[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 <string.h>
39 #include <unistd.h>
40 #include <sys/time.h>
41 #include <time.h>
42 #include <gmp.h>
43
44 #include "eap_aka.h"
45
46 #include <daemon.h>
47 #include <library.h>
48 #include <utils/randomizer.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 * Initiate a AKA-Challenge using SQN
834 */
835 static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn,
836 eap_payload_t **out)
837 {
838 randomizer_t *randomizer;
839 status_t status;
840 chunk_t mac, ak, autn;
841
842 mac = chunk_alloca(MAC_LENGTH);
843 ak = chunk_alloca(AK_LENGTH);
844 chunk_free(&this->rand);
845 chunk_free(&this->xres);
846
847 /* generate RAND:
848 * we use our standard randomizer, not f0() proposed in S.S0055
849 */
850 randomizer = randomizer_create();
851 status = randomizer->allocate_pseudo_random_bytes(randomizer, RAND_LENGTH, &this->rand);
852 randomizer->destroy(randomizer);
853 if (status != SUCCESS)
854 {
855 DBG1(DBG_IKE, "generating RAND for EAP-AKA authentication failed");
856 return FAILED;
857 }
858
859 # ifdef TEST_VECTORS
860 /* Test vector for RAND */
861 u_int8_t test_rand[] = {
862 0x4b,0x05,0x2b,0x20,0xe2,0xa0,0x6c,0x8f,
863 0xf7,0x00,0xda,0x51,0x2b,0x4e,0x11,0x1e,
864 };
865 memcpy(this->rand.ptr, test_rand, this->rand.len);
866 # endif /* TEST_VECTORS */
867
868 /* Get the shared key K: */
869 if (load_key(this->server, this->peer, &this->k) != SUCCESS)
870 {
871 DBG1(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
872 "with EAP-AKA", this->server, this->peer);
873 return FAILED;
874 }
875
876 # ifdef TEST_VECTORS
877 /* Test vector for K */
878 u_int8_t test_k[] = {
879 0xad,0x1b,0x5a,0x15,0x9b,0xe8,0x6b,0x2c,
880 0xa6,0x6c,0x7a,0xe4,0x0b,0xba,0x9b,0x9d,
881 };
882 memcpy(this->k.ptr, test_k, this->k.len);
883 # endif /* TEST_VECTORS */
884
885 /* generate MAC */
886 f1(this, this->k, this->rand, sqn, amf, mac.ptr);
887
888 /* generate AK */
889 f5(this, this->k, this->rand, ak.ptr);
890
891 /* precalculate XRES as expected from client */
892 this->xres = chunk_alloc(RES_LENGTH);
893 f2(this, this->k, this->rand, this->xres.ptr);
894
895 /* calculate AUTN = (SQN xor AK) || AMF || MAC */
896 autn = chunk_cata("ccc", sqn, amf, mac);
897 memxor(autn.ptr, ak.ptr, ak.len);
898 DBG3(DBG_IKE, "AUTN %B", &autn);
899
900
901 /* derive K_encr, K_auth, MSK, EMSK */
902 derive_keys(this, this->peer);
903
904 /* build payload */
905 *out = build_aka_payload(this, EAP_REQUEST, 0, AKA_CHALLENGE,
906 AT_RAND, this->rand, AT_AUTN, autn, AT_MAC,
907 chunk_empty, AT_END);
908 return NEED_MORE;
909 }
910
911 /**
912 * Implementation of eap_method_t.initiate for an EAP_AKA server
913 */
914 static status_t server_initiate(private_eap_aka_t *this, eap_payload_t **out)
915 {
916 chunk_t sqn = chunk_alloca(SQN_LENGTH);
917
918 /* we use an offset of 3 minutes to tolerate clock inaccuracy
919 * without the need to synchronize sequence numbers */
920 update_sqn(sqn.ptr, 180);
921
922 # ifdef TEST_VECTORS
923 /* Test vector for SQN */
924 u_int8_t test_sqn[] = {0x00,0x00,0x00,0x00,0x00,0x01};
925 memcpy(sqn.ptr, test_sqn, sqn.len);
926 # endif /* TEST_VECTORS */
927
928 return server_initiate_challenge(this, sqn, out);
929 }
930
931 static status_t server_process_synchronize(private_eap_aka_t *this,
932 eap_payload_t *in, eap_payload_t **out)
933 {
934 chunk_t attr, auts = chunk_empty, pos, message, macs, xmacs, sqn, aks, amf;
935 u_int i;
936
937 message = in->get_data(in);
938 pos = message;
939 read_header(&pos);
940
941 /* iterate over attributes */
942 while (TRUE)
943 {
944 aka_attribute_t attribute = read_attribute(&pos, &attr);
945 switch (attribute)
946 {
947 case AT_END:
948 break;
949 case AT_AUTS:
950 auts = attr;
951 continue;
952 default:
953 if (attribute >= 0 && attribute <= 127)
954 {
955 DBG1(DBG_IKE, "found non skippable attribute %N",
956 aka_attribute_names, attribute);
957 return FAILED;
958 }
959 DBG1(DBG_IKE, "ignoring skippable attribute %N",
960 aka_attribute_names, attribute);
961 continue;
962 }
963 break;
964 }
965
966 if (auts.len != AUTS_LENGTH)
967 {
968 DBG1(DBG_IKE, "synchronization request didn't contain useable AUTS");
969 return FAILED;
970 }
971
972 chunk_split(auts, "mm", SQN_LENGTH, &sqn, MAC_LENGTH, &macs);
973 aks = chunk_alloca(AK_LENGTH);
974 f5star(this, this->k, this->rand, aks.ptr);
975 /* decrypt serial number by XORing AKS */
976 memxor(sqn.ptr, aks.ptr, aks.len);
977
978 /* verify MACS */
979 xmacs = chunk_alloca(MAC_LENGTH);
980 amf = chunk_alloca(AMF_LENGTH);
981 /* an AMF of zero is used for MACS calculation */
982 memset(amf.ptr, 0, amf.len);
983 f1star(this, this->k, this->rand, sqn, amf, xmacs.ptr);
984 if (!chunk_equals(macs, xmacs))
985 {
986 DBG1(DBG_IKE, "received MACS does not match XMACS");
987 DBG3(DBG_IKE, "MACS %B XMACS %B", &macs, &xmacs);
988 return FAILED;
989 }
990
991 /* retry the challenge with the received SQN + 1*/
992 for (i = SQN_LENGTH - 1; i >= 0; i--)
993 {
994 if (++sqn.ptr[i] != 0)
995 {
996 break;
997 }
998 }
999 return server_initiate_challenge(this, sqn, out);
1000 }
1001
1002 /**
1003 * process an AKA_Challenge response
1004 */
1005 static status_t server_process_challenge(private_eap_aka_t *this, eap_payload_t *in)
1006 {
1007 chunk_t attr, res = chunk_empty, at_mac = chunk_empty, pos, message;
1008
1009 message = in->get_data(in);
1010 pos = message;
1011 read_header(&pos);
1012
1013 /* iterate over attributes */
1014 while (TRUE)
1015 {
1016 aka_attribute_t attribute = read_attribute(&pos, &attr);
1017 switch (attribute)
1018 {
1019 case AT_END:
1020 break;
1021 case AT_RES:
1022 res = attr;
1023 if (attr.len == 2 + RES_LENGTH &&
1024 *(u_int16_t*)attr.ptr == htons(RES_LENGTH * 8))
1025 {
1026 res = chunk_skip(attr, 2);
1027 }
1028 continue;
1029
1030 case AT_MAC:
1031 attr = chunk_skip(attr, 2);
1032 at_mac = chunk_clonea(attr);
1033 /* zero MAC in message for MAC verification */
1034 memset(attr.ptr, 0, attr.len);
1035 continue;
1036 default:
1037 if (attribute >= 0 && attribute <= 127)
1038 {
1039 DBG1(DBG_IKE, "found non skippable attribute %N",
1040 aka_attribute_names, attribute);
1041 return FAILED;
1042 }
1043 DBG1(DBG_IKE, "ignoring skippable attribute %N",
1044 aka_attribute_names, attribute);
1045 continue;
1046 }
1047 break;
1048 }
1049
1050 /* verify EAP message MAC AT_MAC */
1051 {
1052 this->signer->set_key(this->signer, this->k_auth);
1053 DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
1054 DBG3(DBG_IKE, "using key %B", &this->k_auth);
1055 if (!this->signer->verify_signature(this->signer, message, at_mac))
1056 {
1057 DBG1(DBG_IKE, "MAC in AT_MAC attribute verification failed");
1058 return FAILED;
1059 }
1060 }
1061
1062 /* compare received RES against stored precalculated XRES */
1063 if (!chunk_equals(res, this->xres))
1064 {
1065 DBG1(DBG_IKE, "received RES does not match XRES");
1066 DBG3(DBG_IKE, "RES %Bb XRES %B", &res, &this->xres);
1067 return FAILED;
1068 }
1069 return SUCCESS;
1070 }
1071
1072 /**
1073 * Implementation of eap_method_t.process for EAP_AKA servers
1074 */
1075 static status_t server_process(private_eap_aka_t *this,
1076 eap_payload_t *in, eap_payload_t **out)
1077 {
1078 chunk_t message;
1079 aka_subtype_t type;
1080
1081 message = in->get_data(in);
1082 type = read_header(&message);
1083
1084 DBG3(DBG_IKE, "received EAP message %B", &message);
1085
1086 switch (type)
1087 {
1088 case AKA_CHALLENGE:
1089 {
1090 return server_process_challenge(this, in);
1091 }
1092 case AKA_AUTHENTICATION_REJECT:
1093 case AKA_CLIENT_ERROR:
1094 {
1095 DBG1(DBG_IKE, "received %N, authentication failed",
1096 aka_subtype_names, type);
1097 return FAILED;
1098 }
1099 case AKA_SYNCHRONIZATION_FAILURE:
1100 {
1101 DBG1(DBG_IKE, "received %N, retrying with received SQN",
1102 aka_subtype_names, type);
1103 return server_process_synchronize(this, in, out);
1104 }
1105 default:
1106 DBG1(DBG_IKE, "received unknown AKA subtype %N, authentication failed",
1107 aka_subtype_names, type);
1108 return FAILED;
1109 }
1110 }
1111
1112 /**
1113 * Process an incoming AKA-Challenge client side
1114 */
1115 static status_t peer_process_challenge(private_eap_aka_t *this,
1116 eap_payload_t *in, eap_payload_t **out)
1117 {
1118 chunk_t attr = chunk_empty;
1119 chunk_t autn = chunk_empty, at_mac = chunk_empty;
1120 chunk_t ak, sqn, sqn_ak, mac, xmac, res, amf, message, pos;
1121 u_int8_t identifier;
1122
1123 ak = chunk_alloca(AK_LENGTH);
1124 xmac = chunk_alloca(MAC_LENGTH);
1125 res = chunk_alloca(RES_LENGTH);
1126 chunk_free(&this->rand);
1127
1128 message = in->get_data(in);
1129 pos = message;
1130 read_header(&pos);
1131 identifier = in->get_identifier(in);
1132
1133 DBG3(DBG_IKE, "reading attributes from %B", &pos);
1134
1135 /* iterate over attributes */
1136 while (TRUE)
1137 {
1138 aka_attribute_t attribute = read_attribute(&pos, &attr);
1139 switch (attribute)
1140 {
1141 case AT_END:
1142 break;
1143 case AT_RAND:
1144 this->rand = chunk_clone(chunk_skip(attr, 2));
1145 continue;
1146 case AT_AUTN:
1147 autn = chunk_skip(attr, 2);
1148 continue;
1149 case AT_MAC:
1150 attr = chunk_skip(attr, 2);
1151 at_mac = chunk_clonea(attr);
1152 /* set MAC in message to zero for own MAC verification */
1153 memset(attr.ptr, 0, attr.len);
1154 continue;
1155 default:
1156 if (attribute >= 0 && attribute <= 127)
1157 {
1158 /* non skippable attribute, abort */
1159 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
1160 AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
1161 DBG1(DBG_IKE, "found non skippable attribute %N, sending %N %d",
1162 aka_attribute_names, attribute,
1163 aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
1164 return NEED_MORE;
1165 }
1166 DBG1(DBG_IKE, "ignoring skippable attribute %N",
1167 aka_attribute_names, attribute);
1168 continue;
1169 }
1170 break;
1171 }
1172
1173 if (this->rand.len != RAND_LENGTH || autn.len != AUTN_LENGTH)
1174 {
1175 /* required attributes wrong/not found, abort */
1176 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
1177 AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
1178 DBG1(DBG_IKE, "could not find valid RAND/AUTN attribute, sending %N %d",
1179 aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
1180 return NEED_MORE;
1181 }
1182
1183 DBG3(DBG_IKE, "using autn %B", &autn);
1184 /* split up AUTN = SQN xor AK | AMF | MAC */
1185 chunk_split(autn, "mmm", SQN_LENGTH, &sqn_ak, AMF_LENGTH, &amf, MAC_LENGTH, &mac);
1186
1187 /* Get the shared key K: */
1188 chunk_free(&this->k);
1189 if (load_key(this->peer, this->server, &this->k) != SUCCESS)
1190 {
1191 *out = build_aka_payload(this, EAP_RESPONSE, identifier,
1192 AKA_AUTHENTICATION_REJECT, AT_END);
1193 DBG3(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
1194 "with EAP-AKA, sending %N", this->peer, this->server,
1195 aka_subtype_names, AKA_AUTHENTICATION_REJECT);
1196 return NEED_MORE;
1197 }
1198 DBG3(DBG_IKE, "using K %B", &this->k);
1199 # ifdef TEST_VECTORS
1200 /* Test vector for K */
1201 u_int8_t test_k[] = {
1202 0xad,0x1b,0x5a,0x15,0x9b,0xe8,0x6b,0x2c,
1203 0xa6,0x6c,0x7a,0xe4,0x0b,0xba,0x9b,0x9d,
1204 };
1205 memcpy(this->k.ptr, test_k, this->k.len);
1206 # endif /* TEST_VECTORS */
1207
1208 /* calculate anonymity key AK */
1209 f5(this, this->k, this->rand, ak.ptr);
1210 DBG3(DBG_IKE, "using rand %B", &this->rand);
1211 DBG3(DBG_IKE, "using ak %B", &ak);
1212 /* XOR AK into SQN to decrypt it */
1213
1214 sqn = chunk_clonea(sqn_ak);
1215
1216 DBG3(DBG_IKE, "using ak xor sqn %B", &sqn_ak);
1217 memxor(sqn.ptr, ak.ptr, sqn.len);
1218 DBG3(DBG_IKE, "using sqn %B", &sqn);
1219
1220 /* calculate expected MAC and compare against received one */
1221 f1(this, this->k, this->rand, sqn, amf, xmac.ptr);
1222 if (!chunk_equals(mac, xmac))
1223 {
1224 *out = build_aka_payload(this, EAP_RESPONSE, identifier,
1225 AKA_AUTHENTICATION_REJECT, AT_END);
1226 DBG1(DBG_IKE, "received MAC does not match XMAC, sending %N",
1227 aka_subtype_names, AKA_AUTHENTICATION_REJECT);
1228 DBG3(DBG_IKE, "MAC %B\nXMAC %B", &mac, &xmac);
1229 return NEED_MORE;
1230 }
1231
1232 #if SEQ_CHECK
1233 if (memcmp(peer_sqn.ptr, sqn.ptr, sqn.len) >= 0)
1234 {
1235 /* sequence number invalid. send AUTS */
1236 chunk_t auts, macs, aks, amf;
1237
1238 macs = chunk_alloca(MAC_LENGTH);
1239 aks = chunk_alloca(AK_LENGTH);
1240 amf = chunk_alloca(AMF_LENGTH);
1241
1242 /* AMF is set to zero in AKA_SYNCHRONIZATION_FAILURE */
1243 memset(amf.ptr, 0, amf.len);
1244 /* AKS = f5*(RAND) */
1245 f5star(this, this->k, this->rand, aks.ptr);
1246 /* MACS = f1*(RAND) */
1247 f1star(this, this->k, this->rand, peer_sqn, amf, macs.ptr);
1248 /* AUTS = SQN xor AKS | MACS */
1249 memxor(aks.ptr, peer_sqn.ptr, aks.len);
1250 auts = chunk_cata("cc", aks, macs);
1251
1252 *out = build_aka_payload(this, EAP_RESPONSE, identifier,
1253 AKA_SYNCHRONIZATION_FAILURE,
1254 AT_AUTS, auts, AT_END);
1255 DBG1(DBG_IKE, "received SQN invalid, sending %N",
1256 aka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
1257 DBG3(DBG_IKE, "received SQN %B\ncurrent SQN %B", &sqn, &peer_sqn);
1258 return NEED_MORE;
1259 }
1260 #endif /* SEQ_CHECK */
1261
1262 /* derive K_encr, K_auth, MSK, EMSK */
1263 derive_keys(this, this->peer);
1264
1265 /* verify EAP message MAC AT_MAC */
1266 DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
1267 DBG3(DBG_IKE, "using key %B", &this->k_auth);
1268 this->signer->set_key(this->signer, this->k_auth);
1269 if (!this->signer->verify_signature(this->signer, message, at_mac))
1270 {
1271 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
1272 AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
1273 DBG1(DBG_IKE, "MAC in AT_MAC attribute verification "
1274 "failed, sending %N %d", aka_attribute_names,
1275 AT_CLIENT_ERROR_CODE, 0);
1276 return NEED_MORE;
1277 }
1278
1279 /* update stored SQN to the received one */
1280 memcpy(peer_sqn.ptr, sqn.ptr, sqn.len);
1281
1282 /* calculate RES */
1283 f2(this, this->k, this->rand, res.ptr);
1284
1285 /* build response */
1286 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CHALLENGE,
1287 AT_RES, res, AT_MAC, chunk_empty, AT_END);
1288 return NEED_MORE;
1289 }
1290
1291 /**
1292 * Process an incoming AKA-Notification as client
1293 */
1294 static status_t peer_process_notification(private_eap_aka_t *this,
1295 eap_payload_t *in, eap_payload_t **out)
1296 {
1297 chunk_t message, pos, attr;
1298 u_int8_t identifier;
1299
1300 message = in->get_data(in);
1301 pos = message;
1302 read_header(&pos);
1303 identifier = in->get_identifier(in);
1304
1305 DBG3(DBG_IKE, "reading attributes from %B", &pos);
1306
1307 /* iterate over attributes */
1308 while (TRUE)
1309 {
1310 aka_attribute_t attribute = read_attribute(&pos, &attr);
1311 switch (attribute)
1312 {
1313 case AT_END:
1314 break;
1315 case AT_NOTIFICATION:
1316 {
1317 u_int16_t code;
1318
1319 if (attr.len != 2)
1320 {
1321 DBG1(DBG_IKE, "received invalid AKA notification, ignored");
1322 continue;
1323 }
1324 code = ntohs(*(u_int16_t*)attr.ptr);
1325 switch (code)
1326 {
1327 case 0:
1328 DBG1(DBG_IKE, "received AKA notification 'general "
1329 "failure after authentication' (%d)", code);
1330 return FAILED;
1331 case 16384:
1332 DBG1(DBG_IKE, "received AKA notification 'general "
1333 "failure' (%d)", code);
1334 return FAILED;
1335 case 32768:
1336 DBG1(DBG_IKE, "received AKA notification 'successfully "
1337 "authenticated' (%d)", code);
1338 continue;
1339 case 1026:
1340 DBG1(DBG_IKE, "received AKA notification 'access "
1341 "temporarily denied' (%d)", code);
1342 return FAILED;
1343 case 1031:
1344 DBG1(DBG_IKE, "received AKA notification 'not "
1345 "subscribed to service' (%d)", code);
1346 return FAILED;
1347 default:
1348 DBG1(DBG_IKE, "received AKA notification code %d, "
1349 "ignored", code);
1350 continue;
1351 }
1352 }
1353 default:
1354 if (attribute >= 0 && attribute <= 127)
1355 {
1356 DBG1(DBG_IKE, "ignoring non-skippable attribute %N in %N",
1357 aka_attribute_names, attribute, aka_subtype_names,
1358 AKA_NOTIFICATION);
1359 }
1360 else
1361 {
1362 DBG1(DBG_IKE, "ignoring skippable attribute %N",
1363 aka_attribute_names, attribute);
1364 }
1365 continue;
1366 }
1367 break;
1368 }
1369 return NEED_MORE;
1370 }
1371
1372 /**
1373 * Implementation of eap_method_t.process for an EAP_AKA peer
1374 */
1375 static status_t peer_process(private_eap_aka_t *this,
1376 eap_payload_t *in, eap_payload_t **out)
1377 {
1378 aka_subtype_t type;
1379 chunk_t message;
1380 u_int8_t identifier;
1381
1382 message = in->get_data(in);
1383 type = read_header(&message);
1384 identifier = in->get_identifier(in);
1385
1386 DBG3(DBG_IKE, "received EAP message %B", &message);
1387
1388 switch (type)
1389 {
1390 case AKA_CHALLENGE:
1391 {
1392 return peer_process_challenge(this, in, out);
1393 }
1394 case AKA_NOTIFICATION:
1395 {
1396 return peer_process_notification(this, in, out);
1397 }
1398 default:
1399 {
1400 *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
1401 AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
1402 DBG1(DBG_IKE, "received unsupported %N request, sending %N %d",
1403 aka_subtype_names, type,
1404 aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
1405 return NEED_MORE;
1406 }
1407 }
1408 }
1409
1410 /**
1411 * Implementation of eap_method_t.initiate for an EAP AKA peer
1412 */
1413 static status_t peer_initiate(private_eap_aka_t *this, eap_payload_t **out)
1414 {
1415 /* peer never initiates */
1416 return FAILED;
1417 }
1418
1419 /**
1420 * Implementation of eap_method_t.get_type.
1421 */
1422 static eap_type_t get_type(private_eap_aka_t *this, u_int32_t *vendor)
1423 {
1424 *vendor = 0;
1425 return EAP_AKA;
1426 }
1427
1428 /**
1429 * Implementation of eap_method_t.get_msk.
1430 */
1431 static status_t get_msk(private_eap_aka_t *this, chunk_t *msk)
1432 {
1433 if (this->msk.ptr)
1434 {
1435 *msk = this->msk;
1436 return SUCCESS;
1437 }
1438 return FAILED;
1439 }
1440
1441 /**
1442 * Implementation of eap_method_t.is_mutual.
1443 */
1444 static bool is_mutual(private_eap_aka_t *this)
1445 {
1446 return TRUE;
1447 }
1448
1449 /**
1450 * Implementation of eap_method_t.destroy.
1451 */
1452 static void destroy(private_eap_aka_t *this)
1453 {
1454 DESTROY_IF(this->sha1);
1455 DESTROY_IF(this->signer);
1456 DESTROY_IF(this->prf);
1457 DESTROY_IF(this->keyed_prf);
1458 chunk_free(&this->k_encr);
1459 chunk_free(&this->k_auth);
1460 chunk_free(&this->msk);
1461 chunk_free(&this->emsk);
1462 chunk_free(&this->xres);
1463 chunk_free(&this->k);
1464 chunk_free(&this->rand);
1465 free(this);
1466 }
1467
1468 /**
1469 * generic constructor used by client & server
1470 */
1471 static private_eap_aka_t *eap_aka_create_generic(identification_t *server,
1472 identification_t *peer)
1473 {
1474 private_eap_aka_t *this = malloc_thing(private_eap_aka_t);
1475
1476 this->public.eap_method_interface.initiate = NULL;
1477 this->public.eap_method_interface.process = NULL;
1478 this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
1479 this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
1480 this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
1481 this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
1482
1483 /* private data */
1484 this->server = server;
1485 this->peer = peer;
1486 this->k_encr = chunk_empty;
1487 this->k_auth = chunk_empty;
1488 this->msk = chunk_empty;
1489 this->emsk = chunk_empty;
1490 this->xres = chunk_empty;
1491 this->k = chunk_empty;
1492 this->rand = chunk_empty;
1493
1494 this->sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1495 this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
1496 this->prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
1497 this->keyed_prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
1498
1499 if (!this->sha1 || !this->signer || !this->prf || !this->keyed_prf)
1500 {
1501 DBG1(DBG_IKE, "unable to initiate EAP-AKA, FIPS-PRF/SHA1 not supported");
1502 DESTROY_IF(this->sha1);
1503 DESTROY_IF(this->signer);
1504 DESTROY_IF(this->prf);
1505 DESTROY_IF(this->keyed_prf);
1506 destroy(this);
1507 return NULL;
1508 }
1509 return this;
1510 }
1511
1512 /*
1513 * Described in header.
1514 */
1515 eap_aka_t *eap_aka_create_server(identification_t *server, identification_t *peer)
1516 {
1517 private_eap_aka_t *this = eap_aka_create_generic(server, peer);
1518
1519 if (this)
1520 {
1521 this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate;
1522 this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process;
1523 }
1524 return (eap_aka_t*)this;
1525 }
1526
1527 /*
1528 * Described in header.
1529 */
1530 eap_aka_t *eap_aka_create_peer(identification_t *server, identification_t *peer)
1531 {
1532 private_eap_aka_t *this = eap_aka_create_generic(server, peer);
1533
1534 if (this)
1535 {
1536 this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate;
1537 this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
1538 }
1539 return (eap_aka_t*)this;
1540 }
1541