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