2 * EAP peer: EAP-SIM/AKA shared routines
3 * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
22 #include "eap_sim_common.h"
25 static int eap_sim_prf(const u8 *key, u8 *x, size_t xlen)
27 return fips186_2_prf(key, EAP_SIM_MK_LEN, x, xlen);
31 void eap_sim_derive_mk(const u8 *identity, size_t identity_len,
32 const u8 *nonce_mt, u16 selected_version,
33 const u8 *ver_list, size_t ver_list_len,
34 int num_chal, const u8 *kc, u8 *mk)
37 const unsigned char *addr[5];
41 len[0] = identity_len;
43 len[1] = num_chal * EAP_SIM_KC_LEN;
45 len[2] = EAP_SIM_NONCE_MT_LEN;
47 len[3] = ver_list_len;
51 WPA_PUT_BE16(sel_ver, selected_version);
53 /* MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */
54 sha1_vector(5, addr, len, mk);
55 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: MK", mk, EAP_SIM_MK_LEN);
59 void eap_aka_derive_mk(const u8 *identity, size_t identity_len,
60 const u8 *ik, const u8 *ck, u8 *mk)
66 len[0] = identity_len;
68 len[1] = EAP_AKA_IK_LEN;
70 len[2] = EAP_AKA_CK_LEN;
72 /* MK = SHA1(Identity|IK|CK) */
73 sha1_vector(3, addr, len, mk);
74 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: IK", ik, EAP_AKA_IK_LEN);
75 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: CK", ck, EAP_AKA_CK_LEN);
76 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: MK", mk, EAP_SIM_MK_LEN);
80 int eap_sim_derive_keys(const u8 *mk, u8 *k_encr, u8 *k_aut, u8 *msk, u8 *emsk)
82 u8 buf[EAP_SIM_K_ENCR_LEN + EAP_SIM_K_AUT_LEN +
83 EAP_SIM_KEYING_DATA_LEN + EAP_EMSK_LEN], *pos;
84 if (eap_sim_prf(mk, buf, sizeof(buf)) < 0) {
85 wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys");
89 os_memcpy(k_encr, pos, EAP_SIM_K_ENCR_LEN);
90 pos += EAP_SIM_K_ENCR_LEN;
91 os_memcpy(k_aut, pos, EAP_SIM_K_AUT_LEN);
92 pos += EAP_SIM_K_AUT_LEN;
93 os_memcpy(msk, pos, EAP_SIM_KEYING_DATA_LEN);
94 pos += EAP_SIM_KEYING_DATA_LEN;
95 os_memcpy(emsk, pos, EAP_EMSK_LEN);
97 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_encr",
98 k_encr, EAP_SIM_K_ENCR_LEN);
99 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_aut",
100 k_aut, EAP_SIM_K_AUT_LEN);
101 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: keying material (MSK)",
102 msk, EAP_SIM_KEYING_DATA_LEN);
103 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: EMSK", emsk, EAP_EMSK_LEN);
104 os_memset(buf, 0, sizeof(buf));
110 int eap_sim_derive_keys_reauth(u16 _counter,
111 const u8 *identity, size_t identity_len,
112 const u8 *nonce_s, const u8 *mk, u8 *msk,
115 u8 xkey[SHA1_MAC_LEN];
116 u8 buf[EAP_SIM_KEYING_DATA_LEN + EAP_EMSK_LEN + 32];
121 while (identity_len > 0 && identity[identity_len - 1] == 0) {
122 wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop null "
123 "character from the end of identity");
127 len[0] = identity_len;
131 len[2] = EAP_SIM_NONCE_S_LEN;
133 len[3] = EAP_SIM_MK_LEN;
135 WPA_PUT_BE16(counter, _counter);
137 wpa_printf(MSG_DEBUG, "EAP-SIM: Deriving keying data from reauth");
138 wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity",
139 identity, identity_len);
140 wpa_hexdump(MSG_DEBUG, "EAP-SIM: counter", counter, 2);
141 wpa_hexdump(MSG_DEBUG, "EAP-SIM: NONCE_S", nonce_s,
142 EAP_SIM_NONCE_S_LEN);
143 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: MK", mk, EAP_SIM_MK_LEN);
145 /* XKEY' = SHA1(Identity|counter|NONCE_S|MK) */
146 sha1_vector(4, addr, len, xkey);
147 wpa_hexdump(MSG_DEBUG, "EAP-SIM: XKEY'", xkey, SHA1_MAC_LEN);
149 if (eap_sim_prf(xkey, buf, sizeof(buf)) < 0) {
150 wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys");
154 os_memcpy(msk, buf, EAP_SIM_KEYING_DATA_LEN);
155 wpa_hexdump(MSG_DEBUG, "EAP-SIM: keying material (MSK)",
156 msk, EAP_SIM_KEYING_DATA_LEN);
159 os_memcpy(emsk, buf + EAP_SIM_KEYING_DATA_LEN, EAP_EMSK_LEN);
160 wpa_hexdump(MSG_DEBUG, "EAP-SIM: EMSK", emsk, EAP_EMSK_LEN);
162 os_memset(buf, 0, sizeof(buf));
168 int eap_sim_verify_mac(const u8 *k_aut, const u8 *req, size_t req_len,
169 const u8 *mac, const u8 *extra, size_t extra_len)
171 unsigned char hmac[SHA1_MAC_LEN];
176 if (mac == NULL || req_len < EAP_SIM_MAC_LEN || mac < req ||
177 mac > req + req_len - EAP_SIM_MAC_LEN)
180 tmp = os_malloc(req_len);
190 os_memcpy(tmp, req, req_len);
191 os_memset(tmp + (mac - req), 0, EAP_SIM_MAC_LEN);
192 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - msg", tmp, req_len);
193 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - extra data",
195 wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: Verify MAC - K_aut",
196 k_aut, EAP_SIM_K_AUT_LEN);
197 hmac_sha1_vector(k_aut, EAP_SIM_K_AUT_LEN, 2, addr, len, hmac);
198 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC: MAC",
199 hmac, EAP_SIM_MAC_LEN);
202 return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
206 void eap_sim_add_mac(const u8 *k_aut, u8 *msg, size_t msg_len, u8 *mac,
207 const u8 *extra, size_t extra_len)
209 unsigned char hmac[SHA1_MAC_LEN];
219 os_memset(mac, 0, EAP_SIM_MAC_LEN);
220 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC - msg", msg, msg_len);
221 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC - extra data",
223 wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: Add MAC - K_aut",
224 k_aut, EAP_SIM_K_AUT_LEN);
225 hmac_sha1_vector(k_aut, EAP_SIM_K_AUT_LEN, 2, addr, len, hmac);
226 os_memcpy(mac, hmac, EAP_SIM_MAC_LEN);
227 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC: MAC",
228 mac, EAP_SIM_MAC_LEN);
232 int eap_sim_parse_attr(const u8 *start, const u8 *end,
233 struct eap_sim_attrs *attr, int aka, int encr)
235 const u8 *pos = start, *apos;
236 size_t alen, plen, i, list_len;
238 os_memset(attr, 0, sizeof(*attr));
239 attr->id_req = NO_ID_REQ;
240 attr->notification = -1;
242 attr->selected_version = -1;
243 attr->client_error_code = -1;
247 wpa_printf(MSG_INFO, "EAP-SIM: Attribute overflow(1)");
250 wpa_printf(MSG_MSGDUMP, "EAP-SIM: Attribute: Type=%d Len=%d",
252 if (pos + pos[1] * 4 > end) {
253 wpa_printf(MSG_INFO, "EAP-SIM: Attribute overflow "
254 "(pos=%p len=%d end=%p)",
255 pos, pos[1] * 4, end);
259 wpa_printf(MSG_INFO, "EAP-SIM: Attribute underflow");
263 alen = pos[1] * 4 - 2;
264 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Attribute data",
268 case EAP_SIM_AT_RAND:
269 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RAND");
272 if ((!aka && (alen % GSM_RAND_LEN)) ||
273 (aka && alen != EAP_AKA_RAND_LEN)) {
274 wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_RAND"
276 (unsigned long) alen);
280 attr->num_chal = alen / GSM_RAND_LEN;
282 case EAP_SIM_AT_AUTN:
283 wpa_printf(MSG_DEBUG, "EAP-AKA: AT_AUTN");
285 wpa_printf(MSG_DEBUG, "EAP-SIM: "
286 "Unexpected AT_AUTN");
291 if (alen != EAP_AKA_AUTN_LEN) {
292 wpa_printf(MSG_INFO, "EAP-AKA: Invalid AT_AUTN"
294 (unsigned long) alen);
299 case EAP_SIM_AT_PADDING:
301 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
305 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) AT_PADDING");
306 for (i = 2; i < alen; i++) {
308 wpa_printf(MSG_INFO, "EAP-SIM: (encr) "
309 "AT_PADDING used a non-zero"
311 wpa_hexdump(MSG_DEBUG, "EAP-SIM: "
312 "(encr) padding bytes",
318 case EAP_SIM_AT_NONCE_MT:
319 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_NONCE_MT");
320 if (alen != 2 + EAP_SIM_NONCE_MT_LEN) {
321 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
322 "AT_NONCE_MT length");
325 attr->nonce_mt = apos + 2;
327 case EAP_SIM_AT_PERMANENT_ID_REQ:
328 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_PERMANENT_ID_REQ");
329 attr->id_req = PERMANENT_ID;
332 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_MAC");
333 if (alen != 2 + EAP_SIM_MAC_LEN) {
334 wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_MAC "
338 attr->mac = apos + 2;
340 case EAP_SIM_AT_NOTIFICATION:
342 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
343 "AT_NOTIFICATION length %lu",
344 (unsigned long) alen);
347 attr->notification = apos[0] * 256 + apos[1];
348 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_NOTIFICATION %d",
351 case EAP_SIM_AT_ANY_ID_REQ:
352 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_ANY_ID_REQ");
353 attr->id_req = ANY_ID;
355 case EAP_SIM_AT_IDENTITY:
356 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_IDENTITY");
357 attr->identity = apos + 2;
358 attr->identity_len = alen - 2;
360 case EAP_SIM_AT_VERSION_LIST:
362 wpa_printf(MSG_DEBUG, "EAP-AKA: "
363 "Unexpected AT_VERSION_LIST");
366 list_len = apos[0] * 256 + apos[1];
367 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_VERSION_LIST");
368 if (list_len < 2 || list_len > alen - 2) {
369 wpa_printf(MSG_WARNING, "EAP-SIM: Invalid "
370 "AT_VERSION_LIST (list_len=%lu "
372 (unsigned long) list_len,
373 (unsigned long) alen);
376 attr->version_list = apos + 2;
377 attr->version_list_len = list_len;
379 case EAP_SIM_AT_SELECTED_VERSION:
380 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_SELECTED_VERSION");
382 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
383 "AT_SELECTED_VERSION length %lu",
384 (unsigned long) alen);
387 attr->selected_version = apos[0] * 256 + apos[1];
388 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_SELECTED_VERSION "
389 "%d", attr->selected_version);
391 case EAP_SIM_AT_FULLAUTH_ID_REQ:
392 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_FULLAUTH_ID_REQ");
393 attr->id_req = FULLAUTH_ID;
395 case EAP_SIM_AT_COUNTER:
397 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
402 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid "
403 "AT_COUNTER (alen=%lu)",
404 (unsigned long) alen);
407 attr->counter = apos[0] * 256 + apos[1];
408 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) AT_COUNTER %d",
411 case EAP_SIM_AT_COUNTER_TOO_SMALL:
413 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
414 "AT_COUNTER_TOO_SMALL");
418 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid "
419 "AT_COUNTER_TOO_SMALL (alen=%lu)",
420 (unsigned long) alen);
423 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) "
424 "AT_COUNTER_TOO_SMALL");
425 attr->counter_too_small = 1;
427 case EAP_SIM_AT_NONCE_S:
429 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
433 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) "
435 if (alen != 2 + EAP_SIM_NONCE_S_LEN) {
436 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid "
437 "AT_NONCE_S (alen=%lu)",
438 (unsigned long) alen);
441 attr->nonce_s = apos + 2;
443 case EAP_SIM_AT_CLIENT_ERROR_CODE:
445 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
446 "AT_CLIENT_ERROR_CODE length %lu",
447 (unsigned long) alen);
450 attr->client_error_code = apos[0] * 256 + apos[1];
451 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_CLIENT_ERROR_CODE "
452 "%d", attr->client_error_code);
455 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_IV");
456 if (alen != 2 + EAP_SIM_MAC_LEN) {
457 wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_IV "
458 "length %lu", (unsigned long) alen);
463 case EAP_SIM_AT_ENCR_DATA:
464 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_ENCR_DATA");
465 attr->encr_data = apos + 2;
466 attr->encr_data_len = alen - 2;
467 if (attr->encr_data_len % 16) {
468 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
469 "AT_ENCR_DATA length %lu",
471 attr->encr_data_len);
475 case EAP_SIM_AT_NEXT_PSEUDONYM:
477 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
478 "AT_NEXT_PSEUDONYM");
481 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) "
482 "AT_NEXT_PSEUDONYM");
483 plen = apos[0] * 256 + apos[1];
484 if (plen > alen - 2) {
485 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid"
486 " AT_NEXT_PSEUDONYM (actual"
487 " len %lu, attr len %lu)",
488 (unsigned long) plen,
489 (unsigned long) alen);
492 attr->next_pseudonym = pos + 4;
493 attr->next_pseudonym_len = plen;
495 case EAP_SIM_AT_NEXT_REAUTH_ID:
497 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
498 "AT_NEXT_REAUTH_ID");
501 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) "
502 "AT_NEXT_REAUTH_ID");
503 plen = apos[0] * 256 + apos[1];
504 if (plen > alen - 2) {
505 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid"
506 " AT_NEXT_REAUTH_ID (actual"
507 " len %lu, attr len %lu)",
508 (unsigned long) plen,
509 (unsigned long) alen);
512 attr->next_reauth_id = pos + 4;
513 attr->next_reauth_id_len = plen;
516 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RES");
519 if (!aka || alen < EAP_AKA_MIN_RES_LEN ||
520 alen > EAP_AKA_MAX_RES_LEN) {
521 wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_RES "
523 (unsigned long) alen);
527 attr->res_len = alen;
529 case EAP_SIM_AT_AUTS:
530 wpa_printf(MSG_DEBUG, "EAP-AKA: AT_AUTS");
532 wpa_printf(MSG_DEBUG, "EAP-SIM: "
533 "Unexpected AT_AUTS");
536 if (alen != EAP_AKA_AUTS_LEN) {
537 wpa_printf(MSG_INFO, "EAP-AKA: Invalid AT_AUTS"
539 (unsigned long) alen);
546 wpa_printf(MSG_INFO, "EAP-SIM: Unrecognized "
547 "non-skippable attribute %d",
552 wpa_printf(MSG_DEBUG, "EAP-SIM: Unrecognized skippable"
553 " attribute %d ignored", pos[0]);
560 wpa_printf(MSG_DEBUG, "EAP-SIM: Attributes parsed successfully "
561 "(aka=%d encr=%d)", aka, encr);
567 u8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data,
568 size_t encr_data_len, const u8 *iv,
569 struct eap_sim_attrs *attr, int aka)
574 wpa_printf(MSG_INFO, "EAP-SIM: Encrypted data, but no IV");
578 decrypted = os_malloc(encr_data_len);
579 if (decrypted == NULL)
581 os_memcpy(decrypted, encr_data, encr_data_len);
583 aes_128_cbc_decrypt(k_encr, iv, decrypted, encr_data_len);
584 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Decrypted AT_ENCR_DATA",
585 decrypted, encr_data_len);
587 if (eap_sim_parse_attr(decrypted, decrypted + encr_data_len, attr,
589 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Failed to parse "
590 "decrypted AT_ENCR_DATA");
599 #define EAP_SIM_INIT_LEN 128
603 size_t buf_len, used;
604 size_t mac, iv, encr; /* index from buf */
608 struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype)
610 struct eap_sim_msg *msg;
614 msg = os_zalloc(sizeof(*msg));
618 msg->buf = os_zalloc(EAP_SIM_INIT_LEN);
619 if (msg->buf == NULL) {
623 msg->buf_len = EAP_SIM_INIT_LEN;
624 eap = (struct eap_hdr *) msg->buf;
626 eap->identifier = id;
627 msg->used = sizeof(*eap);
629 pos = (u8 *) (eap + 1);
632 *pos++ = 0; /* Reserved */
633 *pos++ = 0; /* Reserved */
640 u8 * eap_sim_msg_finish(struct eap_sim_msg *msg, size_t *len, const u8 *k_aut,
641 const u8 *extra, size_t extra_len)
649 eap = (struct eap_hdr *) msg->buf;
650 eap->length = host_to_be16(msg->used);
652 if (k_aut && msg->mac) {
653 eap_sim_add_mac(k_aut, msg->buf, msg->used,
654 msg->buf + msg->mac, extra, extra_len);
664 void eap_sim_msg_free(struct eap_sim_msg *msg)
673 static int eap_sim_msg_resize(struct eap_sim_msg *msg, size_t add_len)
675 if (msg->used + add_len > msg->buf_len) {
676 u8 *nbuf = os_realloc(msg->buf, msg->used + add_len);
680 msg->buf_len = msg->used + add_len;
686 u8 * eap_sim_msg_add_full(struct eap_sim_msg *msg, u8 attr,
687 const u8 *data, size_t len)
689 int attr_len = 2 + len;
696 pad_len = (4 - attr_len % 4) % 4;
698 if (eap_sim_msg_resize(msg, attr_len))
700 start = pos = msg->buf + msg->used;
702 *pos++ = attr_len / 4;
703 os_memcpy(pos, data, len);
706 os_memset(pos, 0, pad_len);
708 msg->used += attr_len;
713 u8 * eap_sim_msg_add(struct eap_sim_msg *msg, u8 attr, u16 value,
714 const u8 *data, size_t len)
716 int attr_len = 4 + len;
723 pad_len = (4 - attr_len % 4) % 4;
725 if (eap_sim_msg_resize(msg, attr_len))
727 start = pos = msg->buf + msg->used;
729 *pos++ = attr_len / 4;
730 WPA_PUT_BE16(pos, value);
733 os_memcpy(pos, data, len);
736 os_memset(pos, 0, pad_len);
738 msg->used += attr_len;
743 u8 * eap_sim_msg_add_mac(struct eap_sim_msg *msg, u8 attr)
745 u8 *pos = eap_sim_msg_add(msg, attr, 0, NULL, EAP_SIM_MAC_LEN);
747 msg->mac = (pos - msg->buf) + 4;
752 int eap_sim_msg_add_encr_start(struct eap_sim_msg *msg, u8 attr_iv,
755 u8 *pos = eap_sim_msg_add(msg, attr_iv, 0, NULL, EAP_SIM_IV_LEN);
758 msg->iv = (pos - msg->buf) + 4;
759 if (hostapd_get_rand(msg->buf + msg->iv, EAP_SIM_IV_LEN)) {
764 pos = eap_sim_msg_add(msg, attr_encr, 0, NULL, 0);
769 msg->encr = pos - msg->buf;
775 int eap_sim_msg_add_encr_end(struct eap_sim_msg *msg, u8 *k_encr, int attr_pad)
779 if (msg == NULL || k_encr == NULL || msg->iv == 0 || msg->encr == 0)
782 encr_len = msg->used - msg->encr - 4;
785 int pad_len = 16 - (encr_len % 16);
787 wpa_printf(MSG_WARNING, "EAP-SIM: "
788 "eap_sim_msg_add_encr_end - invalid pad_len"
792 wpa_printf(MSG_DEBUG, " *AT_PADDING");
793 pos = eap_sim_msg_add(msg, attr_pad, 0, NULL, pad_len - 4);
796 os_memset(pos + 4, 0, pad_len - 4);
799 wpa_printf(MSG_DEBUG, " (AT_ENCR_DATA data len %lu)",
800 (unsigned long) encr_len);
801 msg->buf[msg->encr + 1] = encr_len / 4 + 1;
802 aes_128_cbc_encrypt(k_encr, msg->buf + msg->iv,
803 msg->buf + msg->encr + 4, encr_len);
809 void eap_sim_report_notification(void *msg_ctx, int notification, int aka)
811 #ifndef CONFIG_NO_STDOUT_DEBUG
812 const char *type = aka ? "AKA" : "SIM";
813 #endif /* CONFIG_NO_STDOUT_DEBUG */
815 switch (notification) {
816 case EAP_SIM_GENERAL_FAILURE_AFTER_AUTH:
817 wpa_printf(MSG_WARNING, "EAP-%s: General failure "
818 "notification (after authentication)", type);
820 case EAP_SIM_TEMPORARILY_DENIED:
821 wpa_printf(MSG_WARNING, "EAP-%s: Failure notification: "
822 "User has been temporarily denied access to the "
823 "requested service", type);
825 case EAP_SIM_NOT_SUBSCRIBED:
826 wpa_printf(MSG_WARNING, "EAP-%s: Failure notification: "
827 "User has not subscribed to the requested service",
830 case EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH:
831 wpa_printf(MSG_WARNING, "EAP-%s: General failure "
832 "notification (before authentication)", type);
834 case EAP_SIM_SUCCESS:
835 wpa_printf(MSG_INFO, "EAP-%s: Successful authentication "
836 "notification", type);
839 if (notification >= 32768) {
840 wpa_printf(MSG_INFO, "EAP-%s: Unrecognized "
841 "non-failure notification %d",
844 wpa_printf(MSG_WARNING, "EAP-%s: Unrecognized "
845 "failure notification %d",