Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / src / eap_peer / eap_aka.c
1 /*
2  * EAP peer method: EAP-AKA (RFC 4187) and EAP-AKA' (RFC 5448)
3  * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "pcsc_funcs.h"
13 #include "crypto/crypto.h"
14 #include "crypto/sha1.h"
15 #include "crypto/sha256.h"
16 #include "crypto/milenage.h"
17 #include "eap_common/eap_sim_common.h"
18 #include "eap_config.h"
19 #include "eap_i.h"
20
21
22 struct eap_aka_data {
23         u8 ik[EAP_AKA_IK_LEN], ck[EAP_AKA_CK_LEN], res[EAP_AKA_RES_MAX_LEN];
24         size_t res_len;
25         u8 nonce_s[EAP_SIM_NONCE_S_LEN];
26         u8 mk[EAP_SIM_MK_LEN];
27         u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
28         u8 k_encr[EAP_SIM_K_ENCR_LEN];
29         u8 k_re[EAP_AKA_PRIME_K_RE_LEN]; /* EAP-AKA' only */
30         u8 msk[EAP_SIM_KEYING_DATA_LEN];
31         u8 emsk[EAP_EMSK_LEN];
32         u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN];
33         u8 auts[EAP_AKA_AUTS_LEN];
34
35         int num_id_req, num_notification;
36         u8 *pseudonym;
37         size_t pseudonym_len;
38         u8 *reauth_id;
39         size_t reauth_id_len;
40         int reauth;
41         unsigned int counter, counter_too_small;
42         u8 *last_eap_identity;
43         size_t last_eap_identity_len;
44         enum {
45                 CONTINUE, RESULT_SUCCESS, SUCCESS, FAILURE
46         } state;
47
48         struct wpabuf *id_msgs;
49         int prev_id;
50         int result_ind, use_result_ind;
51         u8 eap_method;
52         u8 *network_name;
53         size_t network_name_len;
54         u16 kdf;
55         int kdf_negotiation;
56 };
57
58
59 #ifndef CONFIG_NO_STDOUT_DEBUG
60 static const char * eap_aka_state_txt(int state)
61 {
62         switch (state) {
63         case CONTINUE:
64                 return "CONTINUE";
65         case RESULT_SUCCESS:
66                 return "RESULT_SUCCESS";
67         case SUCCESS:
68                 return "SUCCESS";
69         case FAILURE:
70                 return "FAILURE";
71         default:
72                 return "?";
73         }
74 }
75 #endif /* CONFIG_NO_STDOUT_DEBUG */
76
77
78 static void eap_aka_state(struct eap_aka_data *data, int state)
79 {
80         wpa_printf(MSG_DEBUG, "EAP-AKA: %s -> %s",
81                    eap_aka_state_txt(data->state),
82                    eap_aka_state_txt(state));
83         data->state = state;
84 }
85
86
87 static void * eap_aka_init(struct eap_sm *sm)
88 {
89         struct eap_aka_data *data;
90         const char *phase1 = eap_get_config_phase1(sm);
91         struct eap_peer_config *config = eap_get_config(sm);
92
93         data = os_zalloc(sizeof(*data));
94         if (data == NULL)
95                 return NULL;
96
97         data->eap_method = EAP_TYPE_AKA;
98
99         eap_aka_state(data, CONTINUE);
100         data->prev_id = -1;
101
102         data->result_ind = phase1 && os_strstr(phase1, "result_ind=1") != NULL;
103
104         if (config && config->anonymous_identity) {
105                 data->pseudonym = os_malloc(config->anonymous_identity_len);
106                 if (data->pseudonym) {
107                         os_memcpy(data->pseudonym, config->anonymous_identity,
108                                   config->anonymous_identity_len);
109                         data->pseudonym_len = config->anonymous_identity_len;
110                 }
111         }
112
113         return data;
114 }
115
116
117 #ifdef EAP_AKA_PRIME
118 static void * eap_aka_prime_init(struct eap_sm *sm)
119 {
120         struct eap_aka_data *data = eap_aka_init(sm);
121         if (data == NULL)
122                 return NULL;
123         data->eap_method = EAP_TYPE_AKA_PRIME;
124         return data;
125 }
126 #endif /* EAP_AKA_PRIME */
127
128
129 static void eap_aka_clear_keys(struct eap_aka_data *data, int reauth)
130 {
131         if (!reauth) {
132                 os_memset(data->mk, 0, EAP_SIM_MK_LEN);
133                 os_memset(data->k_aut, 0, EAP_AKA_PRIME_K_AUT_LEN);
134                 os_memset(data->k_encr, 0, EAP_SIM_K_ENCR_LEN);
135                 os_memset(data->k_re, 0, EAP_AKA_PRIME_K_RE_LEN);
136         }
137         os_memset(data->msk, 0, EAP_SIM_KEYING_DATA_LEN);
138         os_memset(data->emsk, 0, EAP_EMSK_LEN);
139         os_memset(data->autn, 0, EAP_AKA_AUTN_LEN);
140         os_memset(data->auts, 0, EAP_AKA_AUTS_LEN);
141 }
142
143
144 static void eap_aka_deinit(struct eap_sm *sm, void *priv)
145 {
146         struct eap_aka_data *data = priv;
147         if (data) {
148                 os_free(data->pseudonym);
149                 os_free(data->reauth_id);
150                 os_free(data->last_eap_identity);
151                 wpabuf_free(data->id_msgs);
152                 os_free(data->network_name);
153                 eap_aka_clear_keys(data, 0);
154                 os_free(data);
155         }
156 }
157
158
159 static int eap_aka_ext_sim_req(struct eap_sm *sm, struct eap_aka_data *data)
160 {
161         char req[200], *pos, *end;
162
163         wpa_printf(MSG_DEBUG, "EAP-AKA: Use external USIM processing");
164         pos = req;
165         end = pos + sizeof(req);
166         pos += os_snprintf(pos, end - pos, "UMTS-AUTH");
167         pos += os_snprintf(pos, end - pos, ":");
168         pos += wpa_snprintf_hex(pos, end - pos, data->rand, EAP_AKA_RAND_LEN);
169         pos += os_snprintf(pos, end - pos, ":");
170         wpa_snprintf_hex(pos, end - pos, data->autn, EAP_AKA_AUTN_LEN);
171
172         eap_sm_request_sim(sm, req);
173         return 1;
174 }
175
176
177 static int eap_aka_ext_sim_result(struct eap_sm *sm, struct eap_aka_data *data,
178                                   struct eap_peer_config *conf)
179 {
180         char *resp, *pos;
181
182         wpa_printf(MSG_DEBUG,
183                    "EAP-AKA: Use result from external USIM processing");
184
185         resp = conf->external_sim_resp;
186         conf->external_sim_resp = NULL;
187
188         if (os_strncmp(resp, "UMTS-AUTS:", 10) == 0) {
189                 pos = resp + 10;
190                 if (hexstr2bin(pos, data->auts, EAP_AKA_AUTS_LEN) < 0)
191                         goto invalid;
192                 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: AUTS", data->auts,
193                                 EAP_AKA_AUTS_LEN);
194                 os_free(resp);
195                 return -2;
196         }
197
198         if (os_strncmp(resp, "UMTS-AUTH:", 10) != 0) {
199                 wpa_printf(MSG_DEBUG, "EAP-AKA: Unrecognized external USIM processing response");
200                 os_free(resp);
201                 return -1;
202         }
203
204         pos = resp + 10;
205         wpa_hexdump(MSG_DEBUG, "EAP-AKA: RAND", data->rand, EAP_AKA_RAND_LEN);
206
207         if (hexstr2bin(pos, data->ik, EAP_AKA_IK_LEN) < 0)
208                 goto invalid;
209         wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: IK", data->ik, EAP_AKA_IK_LEN);
210         pos += EAP_AKA_IK_LEN * 2;
211         if (*pos != ':')
212                 goto invalid;
213         pos++;
214
215         if (hexstr2bin(pos, data->ck, EAP_AKA_CK_LEN) < 0)
216                 goto invalid;
217         wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: CK", data->ck, EAP_AKA_CK_LEN);
218         pos += EAP_AKA_CK_LEN * 2;
219         if (*pos != ':')
220                 goto invalid;
221         pos++;
222
223         data->res_len = os_strlen(pos) / 2;
224         if (data->res_len > EAP_AKA_RES_MAX_LEN) {
225                 data->res_len = 0;
226                 goto invalid;
227         }
228         if (hexstr2bin(pos, data->res, data->res_len) < 0)
229                 goto invalid;
230         wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: RES", data->res, data->res_len);
231
232         os_free(resp);
233         return 0;
234
235 invalid:
236         wpa_printf(MSG_DEBUG, "EAP-AKA: Invalid external USIM processing UMTS-AUTH response");
237         os_free(resp);
238         return -1;
239 }
240
241
242 static int eap_aka_umts_auth(struct eap_sm *sm, struct eap_aka_data *data)
243 {
244         struct eap_peer_config *conf;
245
246         wpa_printf(MSG_DEBUG, "EAP-AKA: UMTS authentication algorithm");
247
248         conf = eap_get_config(sm);
249         if (conf == NULL)
250                 return -1;
251
252         if (sm->external_sim) {
253                 if (conf->external_sim_resp)
254                         return eap_aka_ext_sim_result(sm, data, conf);
255                 else
256                         return eap_aka_ext_sim_req(sm, data);
257         }
258
259         if (conf->pcsc) {
260                 return scard_umts_auth(sm->scard_ctx, data->rand,
261                                        data->autn, data->res, &data->res_len,
262                                        data->ik, data->ck, data->auts);
263         }
264
265 #ifdef CONFIG_USIM_SIMULATOR
266         if (conf->password) {
267                 u8 opc[16], k[16], sqn[6];
268                 const char *pos;
269                 wpa_printf(MSG_DEBUG, "EAP-AKA: Use internal Milenage "
270                            "implementation for UMTS authentication");
271                 if (conf->password_len < 78) {
272                         wpa_printf(MSG_DEBUG, "EAP-AKA: invalid Milenage "
273                                    "password");
274                         return -1;
275                 }
276                 pos = (const char *) conf->password;
277                 if (hexstr2bin(pos, k, 16))
278                         return -1;
279                 pos += 32;
280                 if (*pos != ':')
281                         return -1;
282                 pos++;
283
284                 if (hexstr2bin(pos, opc, 16))
285                         return -1;
286                 pos += 32;
287                 if (*pos != ':')
288                         return -1;
289                 pos++;
290
291                 if (hexstr2bin(pos, sqn, 6))
292                         return -1;
293
294                 return milenage_check(opc, k, sqn, data->rand, data->autn,
295                                       data->ik, data->ck,
296                                       data->res, &data->res_len, data->auts);
297         }
298 #endif /* CONFIG_USIM_SIMULATOR */
299
300 #ifdef CONFIG_USIM_HARDCODED
301         wpa_printf(MSG_DEBUG, "EAP-AKA: Use hardcoded Kc and SRES values for "
302                    "testing");
303
304         /* These hardcoded Kc and SRES values are used for testing.
305          * Could consider making them configurable. */
306         os_memset(data->res, '2', EAP_AKA_RES_MAX_LEN);
307         data->res_len = EAP_AKA_RES_MAX_LEN;
308         os_memset(data->ik, '3', EAP_AKA_IK_LEN);
309         os_memset(data->ck, '4', EAP_AKA_CK_LEN);
310         {
311                 u8 autn[EAP_AKA_AUTN_LEN];
312                 os_memset(autn, '1', EAP_AKA_AUTN_LEN);
313                 if (os_memcmp_const(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) {
314                         wpa_printf(MSG_WARNING, "EAP-AKA: AUTN did not match "
315                                    "with expected value");
316                         return -1;
317                 }
318         }
319 #if 0
320         {
321                 static int test_resync = 1;
322                 if (test_resync) {
323                         /* Test Resynchronization */
324                         test_resync = 0;
325                         return -2;
326                 }
327         }
328 #endif
329         return 0;
330
331 #else /* CONFIG_USIM_HARDCODED */
332
333         wpa_printf(MSG_DEBUG, "EAP-AKA: No UMTS authentication algorithm "
334                    "enabled");
335         return -1;
336
337 #endif /* CONFIG_USIM_HARDCODED */
338 }
339
340
341 #define CLEAR_PSEUDONYM 0x01
342 #define CLEAR_REAUTH_ID 0x02
343 #define CLEAR_EAP_ID    0x04
344
345 static void eap_aka_clear_identities(struct eap_sm *sm,
346                                      struct eap_aka_data *data, int id)
347 {
348         if ((id & CLEAR_PSEUDONYM) && data->pseudonym) {
349                 wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old pseudonym");
350                 os_free(data->pseudonym);
351                 data->pseudonym = NULL;
352                 data->pseudonym_len = 0;
353                 eap_set_anon_id(sm, NULL, 0);
354         }
355         if ((id & CLEAR_REAUTH_ID) && data->reauth_id) {
356                 wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old reauth_id");
357                 os_free(data->reauth_id);
358                 data->reauth_id = NULL;
359                 data->reauth_id_len = 0;
360         }
361         if ((id & CLEAR_EAP_ID) && data->last_eap_identity) {
362                 wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old eap_id");
363                 os_free(data->last_eap_identity);
364                 data->last_eap_identity = NULL;
365                 data->last_eap_identity_len = 0;
366         }
367 }
368
369
370 static int eap_aka_learn_ids(struct eap_sm *sm, struct eap_aka_data *data,
371                              struct eap_sim_attrs *attr)
372 {
373         if (attr->next_pseudonym) {
374                 const u8 *identity = NULL;
375                 size_t identity_len = 0;
376                 const u8 *realm = NULL;
377                 size_t realm_len = 0;
378
379                 wpa_hexdump_ascii(MSG_DEBUG,
380                                   "EAP-AKA: (encr) AT_NEXT_PSEUDONYM",
381                                   attr->next_pseudonym,
382                                   attr->next_pseudonym_len);
383                 os_free(data->pseudonym);
384                 /* Look for the realm of the permanent identity */
385                 identity = eap_get_config_identity(sm, &identity_len);
386                 if (identity) {
387                         for (realm = identity, realm_len = identity_len;
388                              realm_len > 0; realm_len--, realm++) {
389                                 if (*realm == '@')
390                                         break;
391                         }
392                 }
393                 data->pseudonym = os_malloc(attr->next_pseudonym_len +
394                                             realm_len);
395                 if (data->pseudonym == NULL) {
396                         wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
397                                    "next pseudonym");
398                         data->pseudonym_len = 0;
399                         return -1;
400                 }
401                 os_memcpy(data->pseudonym, attr->next_pseudonym,
402                           attr->next_pseudonym_len);
403                 if (realm_len) {
404                         os_memcpy(data->pseudonym + attr->next_pseudonym_len,
405                                   realm, realm_len);
406                 }
407                 data->pseudonym_len = attr->next_pseudonym_len + realm_len;
408                 eap_set_anon_id(sm, data->pseudonym, data->pseudonym_len);
409         }
410
411         if (attr->next_reauth_id) {
412                 os_free(data->reauth_id);
413                 data->reauth_id = os_malloc(attr->next_reauth_id_len);
414                 if (data->reauth_id == NULL) {
415                         wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
416                                    "next reauth_id");
417                         data->reauth_id_len = 0;
418                         return -1;
419                 }
420                 os_memcpy(data->reauth_id, attr->next_reauth_id,
421                           attr->next_reauth_id_len);
422                 data->reauth_id_len = attr->next_reauth_id_len;
423                 wpa_hexdump_ascii(MSG_DEBUG,
424                                   "EAP-AKA: (encr) AT_NEXT_REAUTH_ID",
425                                   data->reauth_id,
426                                   data->reauth_id_len);
427         }
428
429         return 0;
430 }
431
432
433 static int eap_aka_add_id_msg(struct eap_aka_data *data,
434                               const struct wpabuf *msg)
435 {
436         if (msg == NULL)
437                 return -1;
438
439         if (data->id_msgs == NULL) {
440                 data->id_msgs = wpabuf_dup(msg);
441                 return data->id_msgs == NULL ? -1 : 0;
442         }
443
444         if (wpabuf_resize(&data->id_msgs, wpabuf_len(msg)) < 0)
445                 return -1;
446         wpabuf_put_buf(data->id_msgs, msg);
447
448         return 0;
449 }
450
451
452 static void eap_aka_add_checkcode(struct eap_aka_data *data,
453                                   struct eap_sim_msg *msg)
454 {
455         const u8 *addr;
456         size_t len;
457         u8 hash[SHA256_MAC_LEN];
458
459         wpa_printf(MSG_DEBUG, "   AT_CHECKCODE");
460
461         if (data->id_msgs == NULL) {
462                 /*
463                  * No EAP-AKA/Identity packets were exchanged - send empty
464                  * checkcode.
465                  */
466                 eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, NULL, 0);
467                 return;
468         }
469
470         /* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
471         addr = wpabuf_head(data->id_msgs);
472         len = wpabuf_len(data->id_msgs);
473         wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
474 #ifdef EAP_AKA_PRIME
475         if (data->eap_method == EAP_TYPE_AKA_PRIME)
476                 sha256_vector(1, &addr, &len, hash);
477         else
478 #endif /* EAP_AKA_PRIME */
479                 sha1_vector(1, &addr, &len, hash);
480
481         eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
482                         data->eap_method == EAP_TYPE_AKA_PRIME ?
483                         EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN);
484 }
485
486
487 static int eap_aka_verify_checkcode(struct eap_aka_data *data,
488                                     const u8 *checkcode, size_t checkcode_len)
489 {
490         const u8 *addr;
491         size_t len;
492         u8 hash[SHA256_MAC_LEN];
493         size_t hash_len;
494
495         if (checkcode == NULL)
496                 return -1;
497
498         if (data->id_msgs == NULL) {
499                 if (checkcode_len != 0) {
500                         wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
501                                    "indicates that AKA/Identity messages were "
502                                    "used, but they were not");
503                         return -1;
504                 }
505                 return 0;
506         }
507
508         hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ?
509                 EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN;
510
511         if (checkcode_len != hash_len) {
512                 wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
513                            "indicates that AKA/Identity message were not "
514                            "used, but they were");
515                 return -1;
516         }
517
518         /* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
519         addr = wpabuf_head(data->id_msgs);
520         len = wpabuf_len(data->id_msgs);
521 #ifdef EAP_AKA_PRIME
522         if (data->eap_method == EAP_TYPE_AKA_PRIME)
523                 sha256_vector(1, &addr, &len, hash);
524         else
525 #endif /* EAP_AKA_PRIME */
526                 sha1_vector(1, &addr, &len, hash);
527
528         if (os_memcmp_const(hash, checkcode, hash_len) != 0) {
529                 wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
530                 return -1;
531         }
532
533         return 0;
534 }
535
536
537 static struct wpabuf * eap_aka_client_error(struct eap_aka_data *data, u8 id,
538                                             int err)
539 {
540         struct eap_sim_msg *msg;
541
542         eap_aka_state(data, FAILURE);
543         data->num_id_req = 0;
544         data->num_notification = 0;
545
546         wpa_printf(MSG_DEBUG, "EAP-AKA: Send Client-Error (error code %d)",
547                    err);
548         msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
549                                EAP_AKA_SUBTYPE_CLIENT_ERROR);
550         eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
551         return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
552 }
553
554
555 static struct wpabuf * eap_aka_authentication_reject(struct eap_aka_data *data,
556                                                      u8 id)
557 {
558         struct eap_sim_msg *msg;
559
560         eap_aka_state(data, FAILURE);
561         data->num_id_req = 0;
562         data->num_notification = 0;
563
564         wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject "
565                    "(id=%d)", id);
566         msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
567                                EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT);
568         return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
569 }
570
571
572 static struct wpabuf * eap_aka_synchronization_failure(
573         struct eap_aka_data *data, u8 id)
574 {
575         struct eap_sim_msg *msg;
576
577         data->num_id_req = 0;
578         data->num_notification = 0;
579
580         wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure "
581                    "(id=%d)", id);
582         msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
583                                EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE);
584         wpa_printf(MSG_DEBUG, "   AT_AUTS");
585         eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts,
586                              EAP_AKA_AUTS_LEN);
587         return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
588 }
589
590
591 static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm,
592                                                  struct eap_aka_data *data,
593                                                  u8 id,
594                                                  enum eap_sim_id_req id_req)
595 {
596         const u8 *identity = NULL;
597         size_t identity_len = 0;
598         struct eap_sim_msg *msg;
599
600         data->reauth = 0;
601         if (id_req == ANY_ID && data->reauth_id) {
602                 identity = data->reauth_id;
603                 identity_len = data->reauth_id_len;
604                 data->reauth = 1;
605         } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
606                    data->pseudonym) {
607                 identity = data->pseudonym;
608                 identity_len = data->pseudonym_len;
609                 eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID);
610         } else if (id_req != NO_ID_REQ) {
611                 identity = eap_get_config_identity(sm, &identity_len);
612                 if (identity) {
613                         eap_aka_clear_identities(sm, data, CLEAR_PSEUDONYM |
614                                                  CLEAR_REAUTH_ID);
615                 }
616         }
617         if (id_req != NO_ID_REQ)
618                 eap_aka_clear_identities(sm, data, CLEAR_EAP_ID);
619
620         wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", id);
621         msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
622                                EAP_AKA_SUBTYPE_IDENTITY);
623
624         if (identity) {
625                 wpa_hexdump_ascii(MSG_DEBUG, "   AT_IDENTITY",
626                                   identity, identity_len);
627                 eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len,
628                                 identity, identity_len);
629         }
630
631         return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
632 }
633
634
635 static struct wpabuf * eap_aka_response_challenge(struct eap_aka_data *data,
636                                                   u8 id)
637 {
638         struct eap_sim_msg *msg;
639
640         wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", id);
641         msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
642                                EAP_AKA_SUBTYPE_CHALLENGE);
643         wpa_printf(MSG_DEBUG, "   AT_RES");
644         eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8,
645                         data->res, data->res_len);
646         eap_aka_add_checkcode(data, msg);
647         if (data->use_result_ind) {
648                 wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
649                 eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
650         }
651         wpa_printf(MSG_DEBUG, "   AT_MAC");
652         eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
653         return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, (u8 *) "",
654                                   0);
655 }
656
657
658 static struct wpabuf * eap_aka_response_reauth(struct eap_aka_data *data,
659                                                u8 id, int counter_too_small,
660                                                const u8 *nonce_s)
661 {
662         struct eap_sim_msg *msg;
663         unsigned int counter;
664
665         wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)",
666                    id);
667         msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
668                                EAP_AKA_SUBTYPE_REAUTHENTICATION);
669         wpa_printf(MSG_DEBUG, "   AT_IV");
670         wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
671         eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA);
672
673         if (counter_too_small) {
674                 wpa_printf(MSG_DEBUG, "   *AT_COUNTER_TOO_SMALL");
675                 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0);
676                 counter = data->counter_too_small;
677         } else
678                 counter = data->counter;
679
680         wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", counter);
681         eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0);
682
683         if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
684                 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
685                            "AT_ENCR_DATA");
686                 eap_sim_msg_free(msg);
687                 return NULL;
688         }
689         eap_aka_add_checkcode(data, msg);
690         if (data->use_result_ind) {
691                 wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
692                 eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
693         }
694         wpa_printf(MSG_DEBUG, "   AT_MAC");
695         eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
696         return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, nonce_s,
697                                   EAP_SIM_NONCE_S_LEN);
698 }
699
700
701 static struct wpabuf * eap_aka_response_notification(struct eap_aka_data *data,
702                                                      u8 id, u16 notification)
703 {
704         struct eap_sim_msg *msg;
705         u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
706
707         wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", id);
708         msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
709                                EAP_AKA_SUBTYPE_NOTIFICATION);
710         if (k_aut && data->reauth) {
711                 wpa_printf(MSG_DEBUG, "   AT_IV");
712                 wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
713                 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
714                                            EAP_SIM_AT_ENCR_DATA);
715                 wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", data->counter);
716                 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter,
717                                 NULL, 0);
718                 if (eap_sim_msg_add_encr_end(msg, data->k_encr,
719                                              EAP_SIM_AT_PADDING)) {
720                         wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
721                                    "AT_ENCR_DATA");
722                         eap_sim_msg_free(msg);
723                         return NULL;
724                 }
725         }
726         if (k_aut) {
727                 wpa_printf(MSG_DEBUG, "   AT_MAC");
728                 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
729         }
730         return eap_sim_msg_finish(msg, data->eap_method, k_aut, (u8 *) "", 0);
731 }
732
733
734 static struct wpabuf * eap_aka_process_identity(struct eap_sm *sm,
735                                                 struct eap_aka_data *data,
736                                                 u8 id,
737                                                 const struct wpabuf *reqData,
738                                                 struct eap_sim_attrs *attr)
739 {
740         int id_error;
741         struct wpabuf *buf;
742
743         wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity");
744
745         id_error = 0;
746         switch (attr->id_req) {
747         case NO_ID_REQ:
748                 break;
749         case ANY_ID:
750                 if (data->num_id_req > 0)
751                         id_error++;
752                 data->num_id_req++;
753                 break;
754         case FULLAUTH_ID:
755                 if (data->num_id_req > 1)
756                         id_error++;
757                 data->num_id_req++;
758                 break;
759         case PERMANENT_ID:
760                 if (data->num_id_req > 2)
761                         id_error++;
762                 data->num_id_req++;
763                 break;
764         }
765         if (id_error) {
766                 wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests "
767                            "used within one authentication");
768                 return eap_aka_client_error(data, id,
769                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
770         }
771
772         buf = eap_aka_response_identity(sm, data, id, attr->id_req);
773
774         if (data->prev_id != id) {
775                 eap_aka_add_id_msg(data, reqData);
776                 eap_aka_add_id_msg(data, buf);
777                 data->prev_id = id;
778         }
779
780         return buf;
781 }
782
783
784 static int eap_aka_verify_mac(struct eap_aka_data *data,
785                               const struct wpabuf *req,
786                               const u8 *mac, const u8 *extra,
787                               size_t extra_len)
788 {
789         if (data->eap_method == EAP_TYPE_AKA_PRIME)
790                 return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra,
791                                                  extra_len);
792         return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len);
793 }
794
795
796 #ifdef EAP_AKA_PRIME
797 static struct wpabuf * eap_aka_prime_kdf_select(struct eap_aka_data *data,
798                                                 u8 id, u16 kdf)
799 {
800         struct eap_sim_msg *msg;
801
802         data->kdf_negotiation = 1;
803         data->kdf = kdf;
804         wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d) (KDF "
805                    "select)", id);
806         msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
807                                EAP_AKA_SUBTYPE_CHALLENGE);
808         wpa_printf(MSG_DEBUG, "   AT_KDF");
809         eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0);
810         return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
811 }
812
813
814 static struct wpabuf * eap_aka_prime_kdf_neg(struct eap_aka_data *data,
815                                              u8 id, struct eap_sim_attrs *attr)
816 {
817         size_t i;
818
819         for (i = 0; i < attr->kdf_count; i++) {
820                 if (attr->kdf[i] == EAP_AKA_PRIME_KDF)
821                         return eap_aka_prime_kdf_select(data, id,
822                                                         EAP_AKA_PRIME_KDF);
823         }
824
825         /* No matching KDF found - fail authentication as if AUTN had been
826          * incorrect */
827         return eap_aka_authentication_reject(data, id);
828 }
829
830
831 static int eap_aka_prime_kdf_valid(struct eap_aka_data *data,
832                                    struct eap_sim_attrs *attr)
833 {
834         size_t i, j;
835
836         if (attr->kdf_count == 0)
837                 return 0;
838
839         /* The only allowed (and required) duplication of a KDF is the addition
840          * of the selected KDF into the beginning of the list. */
841
842         if (data->kdf_negotiation) {
843                 if (attr->kdf[0] != data->kdf) {
844                         wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "
845                                    "accept the selected KDF");
846                         return 0;
847                 }
848
849                 for (i = 1; i < attr->kdf_count; i++) {
850                         if (attr->kdf[i] == data->kdf)
851                                 break;
852                 }
853                 if (i == attr->kdf_count &&
854                     attr->kdf_count < EAP_AKA_PRIME_KDF_MAX) {
855                         wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "
856                                    "duplicate the selected KDF");
857                         return 0;
858                 }
859
860                 /* TODO: should check that the list is identical to the one
861                  * used in the previous Challenge message apart from the added
862                  * entry in the beginning. */
863         }
864
865         for (i = data->kdf ? 1 : 0; i < attr->kdf_count; i++) {
866                 for (j = i + 1; j < attr->kdf_count; j++) {
867                         if (attr->kdf[i] == attr->kdf[j]) {
868                                 wpa_printf(MSG_WARNING, "EAP-AKA': The server "
869                                            "included a duplicated KDF");
870                                 return 0;
871                         }
872                 }
873         }
874
875         return 1;
876 }
877 #endif /* EAP_AKA_PRIME */
878
879
880 static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
881                                                  struct eap_aka_data *data,
882                                                  u8 id,
883                                                  const struct wpabuf *reqData,
884                                                  struct eap_sim_attrs *attr)
885 {
886         const u8 *identity;
887         size_t identity_len;
888         int res;
889         struct eap_sim_attrs eattr;
890
891         wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge");
892
893         if (attr->checkcode &&
894             eap_aka_verify_checkcode(data, attr->checkcode,
895                                      attr->checkcode_len)) {
896                 wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
897                            "message");
898                 return eap_aka_client_error(data, id,
899                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
900         }
901
902 #ifdef EAP_AKA_PRIME
903         if (data->eap_method == EAP_TYPE_AKA_PRIME) {
904                 if (!attr->kdf_input || attr->kdf_input_len == 0) {
905                         wpa_printf(MSG_WARNING, "EAP-AKA': Challenge message "
906                                    "did not include non-empty AT_KDF_INPUT");
907                         /* Fail authentication as if AUTN had been incorrect */
908                         return eap_aka_authentication_reject(data, id);
909                 }
910                 os_free(data->network_name);
911                 data->network_name = os_malloc(attr->kdf_input_len);
912                 if (data->network_name == NULL) {
913                         wpa_printf(MSG_WARNING, "EAP-AKA': No memory for "
914                                    "storing Network Name");
915                         return eap_aka_authentication_reject(data, id);
916                 }
917                 os_memcpy(data->network_name, attr->kdf_input,
918                           attr->kdf_input_len);
919                 data->network_name_len = attr->kdf_input_len;
920                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': Network Name "
921                                   "(AT_KDF_INPUT)",
922                                   data->network_name, data->network_name_len);
923                 /* TODO: check Network Name per 3GPP.33.402 */
924
925                 if (!eap_aka_prime_kdf_valid(data, attr))
926                         return eap_aka_authentication_reject(data, id);
927
928                 if (attr->kdf[0] != EAP_AKA_PRIME_KDF)
929                         return eap_aka_prime_kdf_neg(data, id, attr);
930
931                 data->kdf = EAP_AKA_PRIME_KDF;
932                 wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf);
933         }
934
935         if (data->eap_method == EAP_TYPE_AKA && attr->bidding) {
936                 u16 flags = WPA_GET_BE16(attr->bidding);
937                 if ((flags & EAP_AKA_BIDDING_FLAG_D) &&
938                     eap_allowed_method(sm, EAP_VENDOR_IETF,
939                                        EAP_TYPE_AKA_PRIME)) {
940                         wpa_printf(MSG_WARNING, "EAP-AKA: Bidding down from "
941                                    "AKA' to AKA detected");
942                         /* Fail authentication as if AUTN had been incorrect */
943                         return eap_aka_authentication_reject(data, id);
944                 }
945         }
946 #endif /* EAP_AKA_PRIME */
947
948         data->reauth = 0;
949         if (!attr->mac || !attr->rand || !attr->autn) {
950                 wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
951                            "did not include%s%s%s",
952                            !attr->mac ? " AT_MAC" : "",
953                            !attr->rand ? " AT_RAND" : "",
954                            !attr->autn ? " AT_AUTN" : "");
955                 return eap_aka_client_error(data, id,
956                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
957         }
958         os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN);
959         os_memcpy(data->autn, attr->autn, EAP_AKA_AUTN_LEN);
960
961         res = eap_aka_umts_auth(sm, data);
962         if (res == -1) {
963                 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
964                            "failed (AUTN)");
965                 return eap_aka_authentication_reject(data, id);
966         } else if (res == -2) {
967                 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
968                            "failed (AUTN seq# -> AUTS)");
969                 return eap_aka_synchronization_failure(data, id);
970         } else if (res > 0) {
971                 wpa_printf(MSG_DEBUG, "EAP-AKA: Wait for external USIM processing");
972                 return NULL;
973         } else if (res) {
974                 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed");
975                 return eap_aka_client_error(data, id,
976                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
977         }
978 #ifdef EAP_AKA_PRIME
979         if (data->eap_method == EAP_TYPE_AKA_PRIME) {
980                 /* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the
981                  * needed 6-octet SQN ^ AK for CK',IK' derivation */
982                 u16 amf = WPA_GET_BE16(data->autn + 6);
983                 if (!(amf & 0x8000)) {
984                         wpa_printf(MSG_WARNING, "EAP-AKA': AMF separation bit "
985                                    "not set (AMF=0x%4x)", amf);
986                         return eap_aka_authentication_reject(data, id);
987                 }
988                 eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik,
989                                                  data->autn,
990                                                  data->network_name,
991                                                  data->network_name_len);
992         }
993 #endif /* EAP_AKA_PRIME */
994         if (data->last_eap_identity) {
995                 identity = data->last_eap_identity;
996                 identity_len = data->last_eap_identity_len;
997         } else if (data->pseudonym) {
998                 identity = data->pseudonym;
999                 identity_len = data->pseudonym_len;
1000         } else
1001                 identity = eap_get_config_identity(sm, &identity_len);
1002         wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "
1003                           "derivation", identity, identity_len);
1004         if (data->eap_method == EAP_TYPE_AKA_PRIME) {
1005                 eap_aka_prime_derive_keys(identity, identity_len, data->ik,
1006                                           data->ck, data->k_encr, data->k_aut,
1007                                           data->k_re, data->msk, data->emsk);
1008         } else {
1009                 eap_aka_derive_mk(identity, identity_len, data->ik, data->ck,
1010                                   data->mk);
1011                 eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
1012                                     data->msk, data->emsk);
1013         }
1014         if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
1015                 wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
1016                            "used invalid AT_MAC");
1017                 return eap_aka_client_error(data, id,
1018                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1019         }
1020
1021         /* Old reauthentication identity must not be used anymore. In
1022          * other words, if no new identities are received, full
1023          * authentication will be used on next reauthentication (using
1024          * pseudonym identity or permanent identity). */
1025         eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
1026
1027         if (attr->encr_data) {
1028                 u8 *decrypted;
1029                 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
1030                                                attr->encr_data_len, attr->iv,
1031                                                &eattr, 0);
1032                 if (decrypted == NULL) {
1033                         return eap_aka_client_error(
1034                                 data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1035                 }
1036                 eap_aka_learn_ids(sm, data, &eattr);
1037                 os_free(decrypted);
1038         }
1039
1040         if (data->result_ind && attr->result_ind)
1041                 data->use_result_ind = 1;
1042
1043         if (data->state != FAILURE) {
1044                 eap_aka_state(data, data->use_result_ind ?
1045                               RESULT_SUCCESS : SUCCESS);
1046         }
1047
1048         data->num_id_req = 0;
1049         data->num_notification = 0;
1050         /* RFC 4187 specifies that counter is initialized to one after
1051          * fullauth, but initializing it to zero makes it easier to implement
1052          * reauth verification. */
1053         data->counter = 0;
1054         return eap_aka_response_challenge(data, id);
1055 }
1056
1057
1058 static int eap_aka_process_notification_reauth(struct eap_aka_data *data,
1059                                                struct eap_sim_attrs *attr)
1060 {
1061         struct eap_sim_attrs eattr;
1062         u8 *decrypted;
1063
1064         if (attr->encr_data == NULL || attr->iv == NULL) {
1065                 wpa_printf(MSG_WARNING, "EAP-AKA: Notification message after "
1066                            "reauth did not include encrypted data");
1067                 return -1;
1068         }
1069
1070         decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
1071                                        attr->encr_data_len, attr->iv, &eattr,
1072                                        0);
1073         if (decrypted == NULL) {
1074                 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
1075                            "data from notification message");
1076                 return -1;
1077         }
1078
1079         if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) {
1080                 wpa_printf(MSG_WARNING, "EAP-AKA: Counter in notification "
1081                            "message does not match with counter in reauth "
1082                            "message");
1083                 os_free(decrypted);
1084                 return -1;
1085         }
1086
1087         os_free(decrypted);
1088         return 0;
1089 }
1090
1091
1092 static int eap_aka_process_notification_auth(struct eap_aka_data *data,
1093                                              const struct wpabuf *reqData,
1094                                              struct eap_sim_attrs *attr)
1095 {
1096         if (attr->mac == NULL) {
1097                 wpa_printf(MSG_INFO, "EAP-AKA: no AT_MAC in after_auth "
1098                            "Notification message");
1099                 return -1;
1100         }
1101
1102         if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
1103                 wpa_printf(MSG_WARNING, "EAP-AKA: Notification message "
1104                            "used invalid AT_MAC");
1105                 return -1;
1106         }
1107
1108         if (data->reauth &&
1109             eap_aka_process_notification_reauth(data, attr)) {
1110                 wpa_printf(MSG_WARNING, "EAP-AKA: Invalid notification "
1111                            "message after reauth");
1112                 return -1;
1113         }
1114
1115         return 0;
1116 }
1117
1118
1119 static struct wpabuf * eap_aka_process_notification(
1120         struct eap_sm *sm, struct eap_aka_data *data, u8 id,
1121         const struct wpabuf *reqData, struct eap_sim_attrs *attr)
1122 {
1123         wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Notification");
1124         if (data->num_notification > 0) {
1125                 wpa_printf(MSG_INFO, "EAP-AKA: too many notification "
1126                            "rounds (only one allowed)");
1127                 return eap_aka_client_error(data, id,
1128                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1129         }
1130         data->num_notification++;
1131         if (attr->notification == -1) {
1132                 wpa_printf(MSG_INFO, "EAP-AKA: no AT_NOTIFICATION in "
1133                            "Notification message");
1134                 return eap_aka_client_error(data, id,
1135                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1136         }
1137
1138         if ((attr->notification & 0x4000) == 0 &&
1139             eap_aka_process_notification_auth(data, reqData, attr)) {
1140                 return eap_aka_client_error(data, id,
1141                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1142         }
1143
1144         eap_sim_report_notification(sm->msg_ctx, attr->notification, 1);
1145         if (attr->notification >= 0 && attr->notification < 32768) {
1146                 eap_aka_state(data, FAILURE);
1147         } else if (attr->notification == EAP_SIM_SUCCESS &&
1148                    data->state == RESULT_SUCCESS)
1149                 eap_aka_state(data, SUCCESS);
1150         return eap_aka_response_notification(data, id, attr->notification);
1151 }
1152
1153
1154 static struct wpabuf * eap_aka_process_reauthentication(
1155         struct eap_sm *sm, struct eap_aka_data *data, u8 id,
1156         const struct wpabuf *reqData, struct eap_sim_attrs *attr)
1157 {
1158         struct eap_sim_attrs eattr;
1159         u8 *decrypted;
1160
1161         wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Reauthentication");
1162
1163         if (attr->checkcode &&
1164             eap_aka_verify_checkcode(data, attr->checkcode,
1165                                      attr->checkcode_len)) {
1166                 wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
1167                            "message");
1168                 return eap_aka_client_error(data, id,
1169                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1170         }
1171
1172         if (data->reauth_id == NULL) {
1173                 wpa_printf(MSG_WARNING, "EAP-AKA: Server is trying "
1174                            "reauthentication, but no reauth_id available");
1175                 return eap_aka_client_error(data, id,
1176                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1177         }
1178
1179         data->reauth = 1;
1180         if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
1181                 wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
1182                            "did not have valid AT_MAC");
1183                 return eap_aka_client_error(data, id,
1184                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1185         }
1186
1187         if (attr->encr_data == NULL || attr->iv == NULL) {
1188                 wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
1189                            "message did not include encrypted data");
1190                 return eap_aka_client_error(data, id,
1191                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1192         }
1193
1194         decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
1195                                        attr->encr_data_len, attr->iv, &eattr,
1196                                        0);
1197         if (decrypted == NULL) {
1198                 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
1199                            "data from reauthentication message");
1200                 return eap_aka_client_error(data, id,
1201                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1202         }
1203
1204         if (eattr.nonce_s == NULL || eattr.counter < 0) {
1205                 wpa_printf(MSG_INFO, "EAP-AKA: (encr) No%s%s in reauth packet",
1206                            !eattr.nonce_s ? " AT_NONCE_S" : "",
1207                            eattr.counter < 0 ? " AT_COUNTER" : "");
1208                 os_free(decrypted);
1209                 return eap_aka_client_error(data, id,
1210                                             EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1211         }
1212
1213         if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) {
1214                 struct wpabuf *res;
1215                 wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter "
1216                            "(%d <= %d)", eattr.counter, data->counter);
1217                 data->counter_too_small = eattr.counter;
1218
1219                 /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
1220                  * reauth_id must not be used to start a new reauthentication.
1221                  * However, since it was used in the last EAP-Response-Identity
1222                  * packet, it has to saved for the following fullauth to be
1223                  * used in MK derivation. */
1224                 os_free(data->last_eap_identity);
1225                 data->last_eap_identity = data->reauth_id;
1226                 data->last_eap_identity_len = data->reauth_id_len;
1227                 data->reauth_id = NULL;
1228                 data->reauth_id_len = 0;
1229
1230                 res = eap_aka_response_reauth(data, id, 1, eattr.nonce_s);
1231                 os_free(decrypted);
1232
1233                 return res;
1234         }
1235         data->counter = eattr.counter;
1236
1237         os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN);
1238         wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S",
1239                     data->nonce_s, EAP_SIM_NONCE_S_LEN);
1240
1241         if (data->eap_method == EAP_TYPE_AKA_PRIME) {
1242                 eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
1243                                                  data->reauth_id,
1244                                                  data->reauth_id_len,
1245                                                  data->nonce_s,
1246                                                  data->msk, data->emsk);
1247         } else {
1248                 eap_sim_derive_keys_reauth(data->counter, data->reauth_id,
1249                                            data->reauth_id_len,
1250                                            data->nonce_s, data->mk,
1251                                            data->msk, data->emsk);
1252         }
1253         eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
1254         eap_aka_learn_ids(sm, data, &eattr);
1255
1256         if (data->result_ind && attr->result_ind)
1257                 data->use_result_ind = 1;
1258
1259         if (data->state != FAILURE) {
1260                 eap_aka_state(data, data->use_result_ind ?
1261                               RESULT_SUCCESS : SUCCESS);
1262         }
1263
1264         data->num_id_req = 0;
1265         data->num_notification = 0;
1266         if (data->counter > EAP_AKA_MAX_FAST_REAUTHS) {
1267                 wpa_printf(MSG_DEBUG, "EAP-AKA: Maximum number of "
1268                            "fast reauths performed - force fullauth");
1269                 eap_aka_clear_identities(sm, data,
1270                                          CLEAR_REAUTH_ID | CLEAR_EAP_ID);
1271         }
1272         os_free(decrypted);
1273         return eap_aka_response_reauth(data, id, 0, data->nonce_s);
1274 }
1275
1276
1277 static struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv,
1278                                        struct eap_method_ret *ret,
1279                                        const struct wpabuf *reqData)
1280 {
1281         struct eap_aka_data *data = priv;
1282         const struct eap_hdr *req;
1283         u8 subtype, id;
1284         struct wpabuf *res;
1285         const u8 *pos;
1286         struct eap_sim_attrs attr;
1287         size_t len;
1288
1289         wpa_hexdump_buf(MSG_DEBUG, "EAP-AKA: EAP data", reqData);
1290         if (eap_get_config_identity(sm, &len) == NULL) {
1291                 wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured");
1292                 eap_sm_request_identity(sm);
1293                 ret->ignore = TRUE;
1294                 return NULL;
1295         }
1296
1297         pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData,
1298                                &len);
1299         if (pos == NULL || len < 3) {
1300                 ret->ignore = TRUE;
1301                 return NULL;
1302         }
1303         req = wpabuf_head(reqData);
1304         id = req->identifier;
1305         len = be_to_host16(req->length);
1306
1307         ret->ignore = FALSE;
1308         ret->methodState = METHOD_MAY_CONT;
1309         ret->decision = DECISION_FAIL;
1310         ret->allowNotifications = TRUE;
1311
1312         subtype = *pos++;
1313         wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype);
1314         pos += 2; /* Reserved */
1315
1316         if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr,
1317                                data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1,
1318                                0)) {
1319                 res = eap_aka_client_error(data, id,
1320                                            EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1321                 goto done;
1322         }
1323
1324         switch (subtype) {
1325         case EAP_AKA_SUBTYPE_IDENTITY:
1326                 res = eap_aka_process_identity(sm, data, id, reqData, &attr);
1327                 break;
1328         case EAP_AKA_SUBTYPE_CHALLENGE:
1329                 res = eap_aka_process_challenge(sm, data, id, reqData, &attr);
1330                 break;
1331         case EAP_AKA_SUBTYPE_NOTIFICATION:
1332                 res = eap_aka_process_notification(sm, data, id, reqData,
1333                                                    &attr);
1334                 break;
1335         case EAP_AKA_SUBTYPE_REAUTHENTICATION:
1336                 res = eap_aka_process_reauthentication(sm, data, id, reqData,
1337                                                        &attr);
1338                 break;
1339         case EAP_AKA_SUBTYPE_CLIENT_ERROR:
1340                 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error");
1341                 res = eap_aka_client_error(data, id,
1342                                            EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1343                 break;
1344         default:
1345                 wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype);
1346                 res = eap_aka_client_error(data, id,
1347                                            EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1348                 break;
1349         }
1350
1351 done:
1352         if (data->state == FAILURE) {
1353                 ret->decision = DECISION_FAIL;
1354                 ret->methodState = METHOD_DONE;
1355         } else if (data->state == SUCCESS) {
1356                 ret->decision = data->use_result_ind ?
1357                         DECISION_UNCOND_SUCC : DECISION_COND_SUCC;
1358                 /*
1359                  * It is possible for the server to reply with AKA
1360                  * Notification, so we must allow the method to continue and
1361                  * not only accept EAP-Success at this point.
1362                  */
1363                 ret->methodState = data->use_result_ind ?
1364                         METHOD_DONE : METHOD_MAY_CONT;
1365         } else if (data->state == RESULT_SUCCESS)
1366                 ret->methodState = METHOD_CONT;
1367
1368         if (ret->methodState == METHOD_DONE) {
1369                 ret->allowNotifications = FALSE;
1370         }
1371
1372         return res;
1373 }
1374
1375
1376 static Boolean eap_aka_has_reauth_data(struct eap_sm *sm, void *priv)
1377 {
1378         struct eap_aka_data *data = priv;
1379         return data->pseudonym || data->reauth_id;
1380 }
1381
1382
1383 static void eap_aka_deinit_for_reauth(struct eap_sm *sm, void *priv)
1384 {
1385         struct eap_aka_data *data = priv;
1386         eap_aka_clear_identities(sm, data, CLEAR_EAP_ID);
1387         data->prev_id = -1;
1388         wpabuf_free(data->id_msgs);
1389         data->id_msgs = NULL;
1390         data->use_result_ind = 0;
1391         data->kdf_negotiation = 0;
1392         eap_aka_clear_keys(data, 1);
1393 }
1394
1395
1396 static void * eap_aka_init_for_reauth(struct eap_sm *sm, void *priv)
1397 {
1398         struct eap_aka_data *data = priv;
1399         data->num_id_req = 0;
1400         data->num_notification = 0;
1401         eap_aka_state(data, CONTINUE);
1402         return priv;
1403 }
1404
1405
1406 static const u8 * eap_aka_get_identity(struct eap_sm *sm, void *priv,
1407                                        size_t *len)
1408 {
1409         struct eap_aka_data *data = priv;
1410
1411         if (data->reauth_id) {
1412                 *len = data->reauth_id_len;
1413                 return data->reauth_id;
1414         }
1415
1416         if (data->pseudonym) {
1417                 *len = data->pseudonym_len;
1418                 return data->pseudonym;
1419         }
1420
1421         return NULL;
1422 }
1423
1424
1425 static Boolean eap_aka_isKeyAvailable(struct eap_sm *sm, void *priv)
1426 {
1427         struct eap_aka_data *data = priv;
1428         return data->state == SUCCESS;
1429 }
1430
1431
1432 static u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len)
1433 {
1434         struct eap_aka_data *data = priv;
1435         u8 *key;
1436
1437         if (data->state != SUCCESS)
1438                 return NULL;
1439
1440         key = os_malloc(EAP_SIM_KEYING_DATA_LEN);
1441         if (key == NULL)
1442                 return NULL;
1443
1444         *len = EAP_SIM_KEYING_DATA_LEN;
1445         os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
1446
1447         return key;
1448 }
1449
1450
1451 static u8 * eap_aka_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
1452 {
1453         struct eap_aka_data *data = priv;
1454         u8 *id;
1455
1456         if (data->state != SUCCESS)
1457                 return NULL;
1458
1459         *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN;
1460         id = os_malloc(*len);
1461         if (id == NULL)
1462                 return NULL;
1463
1464         id[0] = data->eap_method;
1465         os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN);
1466         os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn, EAP_AKA_AUTN_LEN);
1467         wpa_hexdump(MSG_DEBUG, "EAP-AKA: Derived Session-Id", id, *len);
1468
1469         return id;
1470 }
1471
1472
1473 static u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1474 {
1475         struct eap_aka_data *data = priv;
1476         u8 *key;
1477
1478         if (data->state != SUCCESS)
1479                 return NULL;
1480
1481         key = os_malloc(EAP_EMSK_LEN);
1482         if (key == NULL)
1483                 return NULL;
1484
1485         *len = EAP_EMSK_LEN;
1486         os_memcpy(key, data->emsk, EAP_EMSK_LEN);
1487
1488         return key;
1489 }
1490
1491
1492 int eap_peer_aka_register(void)
1493 {
1494         struct eap_method *eap;
1495         int ret;
1496
1497         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
1498                                     EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA");
1499         if (eap == NULL)
1500                 return -1;
1501
1502         eap->init = eap_aka_init;
1503         eap->deinit = eap_aka_deinit;
1504         eap->process = eap_aka_process;
1505         eap->isKeyAvailable = eap_aka_isKeyAvailable;
1506         eap->getKey = eap_aka_getKey;
1507         eap->getSessionId = eap_aka_get_session_id;
1508         eap->has_reauth_data = eap_aka_has_reauth_data;
1509         eap->deinit_for_reauth = eap_aka_deinit_for_reauth;
1510         eap->init_for_reauth = eap_aka_init_for_reauth;
1511         eap->get_identity = eap_aka_get_identity;
1512         eap->get_emsk = eap_aka_get_emsk;
1513
1514         ret = eap_peer_method_register(eap);
1515         if (ret)
1516                 eap_peer_method_free(eap);
1517         return ret;
1518 }
1519
1520
1521 #ifdef EAP_AKA_PRIME
1522 int eap_peer_aka_prime_register(void)
1523 {
1524         struct eap_method *eap;
1525         int ret;
1526
1527         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
1528                                     EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME,
1529                                     "AKA'");
1530         if (eap == NULL)
1531                 return -1;
1532
1533         eap->init = eap_aka_prime_init;
1534         eap->deinit = eap_aka_deinit;
1535         eap->process = eap_aka_process;
1536         eap->isKeyAvailable = eap_aka_isKeyAvailable;
1537         eap->getKey = eap_aka_getKey;
1538         eap->getSessionId = eap_aka_get_session_id;
1539         eap->has_reauth_data = eap_aka_has_reauth_data;
1540         eap->deinit_for_reauth = eap_aka_deinit_for_reauth;
1541         eap->init_for_reauth = eap_aka_init_for_reauth;
1542         eap->get_identity = eap_aka_get_identity;
1543         eap->get_emsk = eap_aka_get_emsk;
1544
1545         ret = eap_peer_method_register(eap);
1546         if (ret)
1547                 eap_peer_method_free(eap);
1548
1549         return ret;
1550 }
1551 #endif /* EAP_AKA_PRIME */