00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "eap_common/eap_defs.h"
00020 #include "sha1.h"
00021 #include "sha256.h"
00022 #include "crypto.h"
00023 #include "aes_wrap.h"
00024 #include "wpabuf.h"
00025 #include "eap_common/eap_sim_common.h"
00026
00027
00028 static int eap_sim_prf(const u8 *key, u8 *x, size_t xlen)
00029 {
00030 return fips186_2_prf(key, EAP_SIM_MK_LEN, x, xlen);
00031 }
00032
00033
00034 void eap_sim_derive_mk(const u8 *identity, size_t identity_len,
00035 const u8 *nonce_mt, u16 selected_version,
00036 const u8 *ver_list, size_t ver_list_len,
00037 int num_chal, const u8 *kc, u8 *mk)
00038 {
00039 u8 sel_ver[2];
00040 const unsigned char *addr[5];
00041 size_t len[5];
00042
00043 addr[0] = identity;
00044 len[0] = identity_len;
00045 addr[1] = kc;
00046 len[1] = num_chal * EAP_SIM_KC_LEN;
00047 addr[2] = nonce_mt;
00048 len[2] = EAP_SIM_NONCE_MT_LEN;
00049 addr[3] = ver_list;
00050 len[3] = ver_list_len;
00051 addr[4] = sel_ver;
00052 len[4] = 2;
00053
00054 WPA_PUT_BE16(sel_ver, selected_version);
00055
00056
00057 sha1_vector(5, addr, len, mk);
00058 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: MK", mk, EAP_SIM_MK_LEN);
00059 }
00060
00061
00062 void eap_aka_derive_mk(const u8 *identity, size_t identity_len,
00063 const u8 *ik, const u8 *ck, u8 *mk)
00064 {
00065 const u8 *addr[3];
00066 size_t len[3];
00067
00068 addr[0] = identity;
00069 len[0] = identity_len;
00070 addr[1] = ik;
00071 len[1] = EAP_AKA_IK_LEN;
00072 addr[2] = ck;
00073 len[2] = EAP_AKA_CK_LEN;
00074
00075
00076 sha1_vector(3, addr, len, mk);
00077 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: IK", ik, EAP_AKA_IK_LEN);
00078 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: CK", ck, EAP_AKA_CK_LEN);
00079 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: MK", mk, EAP_SIM_MK_LEN);
00080 }
00081
00082
00083 int eap_sim_derive_keys(const u8 *mk, u8 *k_encr, u8 *k_aut, u8 *msk, u8 *emsk)
00084 {
00085 u8 buf[EAP_SIM_K_ENCR_LEN + EAP_SIM_K_AUT_LEN +
00086 EAP_SIM_KEYING_DATA_LEN + EAP_EMSK_LEN], *pos;
00087 if (eap_sim_prf(mk, buf, sizeof(buf)) < 0) {
00088 wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys");
00089 return -1;
00090 }
00091 pos = buf;
00092 os_memcpy(k_encr, pos, EAP_SIM_K_ENCR_LEN);
00093 pos += EAP_SIM_K_ENCR_LEN;
00094 os_memcpy(k_aut, pos, EAP_SIM_K_AUT_LEN);
00095 pos += EAP_SIM_K_AUT_LEN;
00096 os_memcpy(msk, pos, EAP_SIM_KEYING_DATA_LEN);
00097 pos += EAP_SIM_KEYING_DATA_LEN;
00098 os_memcpy(emsk, pos, EAP_EMSK_LEN);
00099
00100 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_encr",
00101 k_encr, EAP_SIM_K_ENCR_LEN);
00102 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_aut",
00103 k_aut, EAP_SIM_K_AUT_LEN);
00104 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: keying material (MSK)",
00105 msk, EAP_SIM_KEYING_DATA_LEN);
00106 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: EMSK", emsk, EAP_EMSK_LEN);
00107 os_memset(buf, 0, sizeof(buf));
00108
00109 return 0;
00110 }
00111
00112
00113 int eap_sim_derive_keys_reauth(u16 _counter,
00114 const u8 *identity, size_t identity_len,
00115 const u8 *nonce_s, const u8 *mk, u8 *msk,
00116 u8 *emsk)
00117 {
00118 u8 xkey[SHA1_MAC_LEN];
00119 u8 buf[EAP_SIM_KEYING_DATA_LEN + EAP_EMSK_LEN + 32];
00120 u8 counter[2];
00121 const u8 *addr[4];
00122 size_t len[4];
00123
00124 while (identity_len > 0 && identity[identity_len - 1] == 0) {
00125 wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop null "
00126 "character from the end of identity");
00127 identity_len--;
00128 }
00129 addr[0] = identity;
00130 len[0] = identity_len;
00131 addr[1] = counter;
00132 len[1] = 2;
00133 addr[2] = nonce_s;
00134 len[2] = EAP_SIM_NONCE_S_LEN;
00135 addr[3] = mk;
00136 len[3] = EAP_SIM_MK_LEN;
00137
00138 WPA_PUT_BE16(counter, _counter);
00139
00140 wpa_printf(MSG_DEBUG, "EAP-SIM: Deriving keying data from reauth");
00141 wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity",
00142 identity, identity_len);
00143 wpa_hexdump(MSG_DEBUG, "EAP-SIM: counter", counter, 2);
00144 wpa_hexdump(MSG_DEBUG, "EAP-SIM: NONCE_S", nonce_s,
00145 EAP_SIM_NONCE_S_LEN);
00146 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: MK", mk, EAP_SIM_MK_LEN);
00147
00148
00149 sha1_vector(4, addr, len, xkey);
00150 wpa_hexdump(MSG_DEBUG, "EAP-SIM: XKEY'", xkey, SHA1_MAC_LEN);
00151
00152 if (eap_sim_prf(xkey, buf, sizeof(buf)) < 0) {
00153 wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys");
00154 return -1;
00155 }
00156 if (msk) {
00157 os_memcpy(msk, buf, EAP_SIM_KEYING_DATA_LEN);
00158 wpa_hexdump(MSG_DEBUG, "EAP-SIM: keying material (MSK)",
00159 msk, EAP_SIM_KEYING_DATA_LEN);
00160 }
00161 if (emsk) {
00162 os_memcpy(emsk, buf + EAP_SIM_KEYING_DATA_LEN, EAP_EMSK_LEN);
00163 wpa_hexdump(MSG_DEBUG, "EAP-SIM: EMSK", emsk, EAP_EMSK_LEN);
00164 }
00165 os_memset(buf, 0, sizeof(buf));
00166
00167 return 0;
00168 }
00169
00170
00171 int eap_sim_verify_mac(const u8 *k_aut, const struct wpabuf *req,
00172 const u8 *mac, const u8 *extra, size_t extra_len)
00173 {
00174 unsigned char hmac[SHA1_MAC_LEN];
00175 const u8 *addr[2];
00176 size_t len[2];
00177 u8 *tmp;
00178
00179 if (mac == NULL || wpabuf_len(req) < EAP_SIM_MAC_LEN ||
00180 mac < wpabuf_head_u8(req) ||
00181 mac > wpabuf_head_u8(req) + wpabuf_len(req) - EAP_SIM_MAC_LEN)
00182 return -1;
00183
00184 tmp = os_malloc(wpabuf_len(req));
00185 if (tmp == NULL)
00186 return -1;
00187
00188 addr[0] = tmp;
00189 len[0] = wpabuf_len(req);
00190 addr[1] = extra;
00191 len[1] = extra_len;
00192
00193
00194 os_memcpy(tmp, wpabuf_head(req), wpabuf_len(req));
00195 os_memset(tmp + (mac - wpabuf_head_u8(req)), 0, EAP_SIM_MAC_LEN);
00196 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - msg",
00197 tmp, wpabuf_len(req));
00198 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - extra data",
00199 extra, extra_len);
00200 wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: Verify MAC - K_aut",
00201 k_aut, EAP_SIM_K_AUT_LEN);
00202 hmac_sha1_vector(k_aut, EAP_SIM_K_AUT_LEN, 2, addr, len, hmac);
00203 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC: MAC",
00204 hmac, EAP_SIM_MAC_LEN);
00205 os_free(tmp);
00206
00207 return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
00208 }
00209
00210
00211 void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
00212 const u8 *extra, size_t extra_len)
00213 {
00214 unsigned char hmac[SHA1_MAC_LEN];
00215 const u8 *addr[2];
00216 size_t len[2];
00217
00218 addr[0] = msg;
00219 len[0] = msg_len;
00220 addr[1] = extra;
00221 len[1] = extra_len;
00222
00223
00224 os_memset(mac, 0, EAP_SIM_MAC_LEN);
00225 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC - msg", msg, msg_len);
00226 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC - extra data",
00227 extra, extra_len);
00228 wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: Add MAC - K_aut",
00229 k_aut, EAP_SIM_K_AUT_LEN);
00230 hmac_sha1_vector(k_aut, EAP_SIM_K_AUT_LEN, 2, addr, len, hmac);
00231 os_memcpy(mac, hmac, EAP_SIM_MAC_LEN);
00232 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC: MAC",
00233 mac, EAP_SIM_MAC_LEN);
00234 }
00235
00236
00237 #if defined(EAP_AKA_PRIME) || defined(EAP_SERVER_AKA_PRIME)
00238 static void prf_prime(const u8 *k, const char *seed1,
00239 const u8 *seed2, size_t seed2_len,
00240 const u8 *seed3, size_t seed3_len,
00241 u8 *res, size_t res_len)
00242 {
00243 const u8 *addr[5];
00244 size_t len[5];
00245 u8 hash[SHA256_MAC_LEN];
00246 u8 iter;
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 addr[0] = hash;
00258 len[0] = 0;
00259 addr[1] = (const u8 *) seed1;
00260 len[1] = os_strlen(seed1);
00261 addr[2] = seed2;
00262 len[2] = seed2_len;
00263 addr[3] = seed3;
00264 len[3] = seed3_len;
00265 addr[4] = &iter;
00266 len[4] = 1;
00267
00268 iter = 0;
00269 while (res_len) {
00270 size_t hlen;
00271 iter++;
00272 hmac_sha256_vector(k, 32, 5, addr, len, hash);
00273 len[0] = SHA256_MAC_LEN;
00274 hlen = res_len > SHA256_MAC_LEN ? SHA256_MAC_LEN : res_len;
00275 os_memcpy(res, hash, hlen);
00276 res += hlen;
00277 res_len -= hlen;
00278 }
00279 }
00280
00281
00282 void eap_aka_prime_derive_keys(const u8 *identity, size_t identity_len,
00283 const u8 *ik, const u8 *ck, u8 *k_encr,
00284 u8 *k_aut, u8 *k_re, u8 *msk, u8 *emsk)
00285 {
00286 u8 key[EAP_AKA_IK_LEN + EAP_AKA_CK_LEN];
00287 u8 keys[EAP_SIM_K_ENCR_LEN + EAP_AKA_PRIME_K_AUT_LEN +
00288 EAP_AKA_PRIME_K_RE_LEN + EAP_MSK_LEN + EAP_EMSK_LEN];
00289 u8 *pos;
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 os_memcpy(key, ik, EAP_AKA_IK_LEN);
00301 os_memcpy(key + EAP_AKA_IK_LEN, ck, EAP_AKA_CK_LEN);
00302
00303 prf_prime(key, "EAP-AKA'", identity, identity_len, NULL, 0,
00304 keys, sizeof(keys));
00305
00306 pos = keys;
00307 os_memcpy(k_encr, pos, EAP_SIM_K_ENCR_LEN);
00308 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_encr",
00309 k_encr, EAP_SIM_K_ENCR_LEN);
00310 pos += EAP_SIM_K_ENCR_LEN;
00311
00312 os_memcpy(k_aut, pos, EAP_AKA_PRIME_K_AUT_LEN);
00313 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_aut",
00314 k_aut, EAP_AKA_PRIME_K_AUT_LEN);
00315 pos += EAP_AKA_PRIME_K_AUT_LEN;
00316
00317 os_memcpy(k_re, pos, EAP_AKA_PRIME_K_RE_LEN);
00318 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_re",
00319 k_re, EAP_AKA_PRIME_K_RE_LEN);
00320 pos += EAP_AKA_PRIME_K_RE_LEN;
00321
00322 os_memcpy(msk, pos, EAP_MSK_LEN);
00323 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': MSK", msk, EAP_MSK_LEN);
00324 pos += EAP_MSK_LEN;
00325
00326 os_memcpy(emsk, pos, EAP_EMSK_LEN);
00327 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': EMSK", emsk, EAP_EMSK_LEN);
00328 }
00329
00330
00331 int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
00332 const u8 *identity, size_t identity_len,
00333 const u8 *nonce_s, u8 *msk, u8 *emsk)
00334 {
00335 u8 seed3[2 + EAP_SIM_NONCE_S_LEN];
00336 u8 keys[EAP_MSK_LEN + EAP_EMSK_LEN];
00337 u8 *pos;
00338
00339
00340
00341
00342
00343
00344
00345 WPA_PUT_BE16(seed3, counter);
00346 os_memcpy(seed3 + 2, nonce_s, EAP_SIM_NONCE_S_LEN);
00347
00348 prf_prime(k_re, "EAP-AKA' re-auth", identity, identity_len,
00349 seed3, sizeof(seed3),
00350 keys, sizeof(keys));
00351
00352 pos = keys;
00353 os_memcpy(msk, pos, EAP_MSK_LEN);
00354 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': MSK", msk, EAP_MSK_LEN);
00355 pos += EAP_MSK_LEN;
00356
00357 os_memcpy(emsk, pos, EAP_EMSK_LEN);
00358 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': EMSK", emsk, EAP_EMSK_LEN);
00359
00360 os_memset(keys, 0, sizeof(keys));
00361
00362 return 0;
00363 }
00364
00365
00366 int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
00367 const u8 *mac, const u8 *extra, size_t extra_len)
00368 {
00369 unsigned char hmac[SHA256_MAC_LEN];
00370 const u8 *addr[2];
00371 size_t len[2];
00372 u8 *tmp;
00373
00374 if (mac == NULL || wpabuf_len(req) < EAP_SIM_MAC_LEN ||
00375 mac < wpabuf_head_u8(req) ||
00376 mac > wpabuf_head_u8(req) + wpabuf_len(req) - EAP_SIM_MAC_LEN)
00377 return -1;
00378
00379 tmp = os_malloc(wpabuf_len(req));
00380 if (tmp == NULL)
00381 return -1;
00382
00383 addr[0] = tmp;
00384 len[0] = wpabuf_len(req);
00385 addr[1] = extra;
00386 len[1] = extra_len;
00387
00388
00389 os_memcpy(tmp, wpabuf_head(req), wpabuf_len(req));
00390 os_memset(tmp + (mac - wpabuf_head_u8(req)), 0, EAP_SIM_MAC_LEN);
00391 wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC - msg",
00392 tmp, wpabuf_len(req));
00393 wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC - extra data",
00394 extra, extra_len);
00395 wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA': Verify MAC - K_aut",
00396 k_aut, EAP_AKA_PRIME_K_AUT_LEN);
00397 hmac_sha256_vector(k_aut, EAP_AKA_PRIME_K_AUT_LEN, 2, addr, len, hmac);
00398 wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC: MAC",
00399 hmac, EAP_SIM_MAC_LEN);
00400 os_free(tmp);
00401
00402 return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
00403 }
00404
00405
00406 void eap_sim_add_mac_sha256(const u8 *k_aut, const u8 *msg, size_t msg_len,
00407 u8 *mac, const u8 *extra, size_t extra_len)
00408 {
00409 unsigned char hmac[SHA256_MAC_LEN];
00410 const u8 *addr[2];
00411 size_t len[2];
00412
00413 addr[0] = msg;
00414 len[0] = msg_len;
00415 addr[1] = extra;
00416 len[1] = extra_len;
00417
00418
00419 os_memset(mac, 0, EAP_SIM_MAC_LEN);
00420 wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC - msg", msg, msg_len);
00421 wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC - extra data",
00422 extra, extra_len);
00423 wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA': Add MAC - K_aut",
00424 k_aut, EAP_AKA_PRIME_K_AUT_LEN);
00425 hmac_sha256_vector(k_aut, EAP_AKA_PRIME_K_AUT_LEN, 2, addr, len, hmac);
00426 os_memcpy(mac, hmac, EAP_SIM_MAC_LEN);
00427 wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC: MAC",
00428 mac, EAP_SIM_MAC_LEN);
00429 }
00430
00431
00432 void eap_aka_prime_derive_ck_ik_prime(u8 *ck, u8 *ik, const u8 *sqn_ak,
00433 const u8 *network_name,
00434 size_t network_name_len)
00435 {
00436 u8 key[EAP_AKA_CK_LEN + EAP_AKA_IK_LEN];
00437 u8 hash[SHA256_MAC_LEN];
00438 const u8 *addr[5];
00439 size_t len[5];
00440 u8 fc;
00441 u8 l0[2], l1[2];
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 fc = 0x20;
00464
00465 wpa_printf(MSG_DEBUG, "EAP-AKA': Derive (CK',IK') from (CK,IK)");
00466 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': CK", ck, EAP_AKA_CK_LEN);
00467 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': IK", ik, EAP_AKA_IK_LEN);
00468 wpa_printf(MSG_DEBUG, "EAP-AKA': FC = 0x%x", fc);
00469 wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': P0 = Access network identity",
00470 network_name, network_name_len);
00471 wpa_hexdump(MSG_DEBUG, "EAP-AKA': P1 = SQN xor AK", sqn_ak, 6);
00472
00473 os_memcpy(key, ck, EAP_AKA_CK_LEN);
00474 os_memcpy(key + EAP_AKA_CK_LEN, ik, EAP_AKA_IK_LEN);
00475 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': Key = CK || IK",
00476 key, sizeof(key));
00477
00478 addr[0] = &fc;
00479 len[0] = 1;
00480 addr[1] = network_name;
00481 len[1] = network_name_len;
00482 WPA_PUT_BE16(l0, network_name_len);
00483 addr[2] = l0;
00484 len[2] = 2;
00485 addr[3] = sqn_ak;
00486 len[3] = 6;
00487 WPA_PUT_BE16(l1, 6);
00488 addr[4] = l1;
00489 len[4] = 2;
00490
00491 hmac_sha256_vector(key, sizeof(key), 5, addr, len, hash);
00492 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': KDF output (CK' || IK')",
00493 hash, sizeof(hash));
00494
00495 os_memcpy(ck, hash, EAP_AKA_CK_LEN);
00496 os_memcpy(ik, hash + EAP_AKA_CK_LEN, EAP_AKA_IK_LEN);
00497 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': CK'", ck, EAP_AKA_CK_LEN);
00498 wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': IK'", ik, EAP_AKA_IK_LEN);
00499 }
00500 #endif
00501
00502
00503 int eap_sim_parse_attr(const u8 *start, const u8 *end,
00504 struct eap_sim_attrs *attr, int aka, int encr)
00505 {
00506 const u8 *pos = start, *apos;
00507 size_t alen, plen, i, list_len;
00508
00509 os_memset(attr, 0, sizeof(*attr));
00510 attr->id_req = NO_ID_REQ;
00511 attr->notification = -1;
00512 attr->counter = -1;
00513 attr->selected_version = -1;
00514 attr->client_error_code = -1;
00515
00516 while (pos < end) {
00517 if (pos + 2 > end) {
00518 wpa_printf(MSG_INFO, "EAP-SIM: Attribute overflow(1)");
00519 return -1;
00520 }
00521 wpa_printf(MSG_MSGDUMP, "EAP-SIM: Attribute: Type=%d Len=%d",
00522 pos[0], pos[1] * 4);
00523 if (pos + pos[1] * 4 > end) {
00524 wpa_printf(MSG_INFO, "EAP-SIM: Attribute overflow "
00525 "(pos=%p len=%d end=%p)",
00526 pos, pos[1] * 4, end);
00527 return -1;
00528 }
00529 if (pos[1] == 0) {
00530 wpa_printf(MSG_INFO, "EAP-SIM: Attribute underflow");
00531 return -1;
00532 }
00533 apos = pos + 2;
00534 alen = pos[1] * 4 - 2;
00535 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Attribute data",
00536 apos, alen);
00537
00538 switch (pos[0]) {
00539 case EAP_SIM_AT_RAND:
00540 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RAND");
00541 apos += 2;
00542 alen -= 2;
00543 if ((!aka && (alen % GSM_RAND_LEN)) ||
00544 (aka && alen != EAP_AKA_RAND_LEN)) {
00545 wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_RAND"
00546 " (len %lu)",
00547 (unsigned long) alen);
00548 return -1;
00549 }
00550 attr->rand = apos;
00551 attr->num_chal = alen / GSM_RAND_LEN;
00552 break;
00553 case EAP_SIM_AT_AUTN:
00554 wpa_printf(MSG_DEBUG, "EAP-AKA: AT_AUTN");
00555 if (!aka) {
00556 wpa_printf(MSG_DEBUG, "EAP-SIM: "
00557 "Unexpected AT_AUTN");
00558 return -1;
00559 }
00560 apos += 2;
00561 alen -= 2;
00562 if (alen != EAP_AKA_AUTN_LEN) {
00563 wpa_printf(MSG_INFO, "EAP-AKA: Invalid AT_AUTN"
00564 " (len %lu)",
00565 (unsigned long) alen);
00566 return -1;
00567 }
00568 attr->autn = apos;
00569 break;
00570 case EAP_SIM_AT_PADDING:
00571 if (!encr) {
00572 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
00573 "AT_PADDING");
00574 return -1;
00575 }
00576 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) AT_PADDING");
00577 for (i = 2; i < alen; i++) {
00578 if (apos[i] != 0) {
00579 wpa_printf(MSG_INFO, "EAP-SIM: (encr) "
00580 "AT_PADDING used a non-zero"
00581 " padding byte");
00582 wpa_hexdump(MSG_DEBUG, "EAP-SIM: "
00583 "(encr) padding bytes",
00584 apos + 2, alen - 2);
00585 return -1;
00586 }
00587 }
00588 break;
00589 case EAP_SIM_AT_NONCE_MT:
00590 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_NONCE_MT");
00591 if (alen != 2 + EAP_SIM_NONCE_MT_LEN) {
00592 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
00593 "AT_NONCE_MT length");
00594 return -1;
00595 }
00596 attr->nonce_mt = apos + 2;
00597 break;
00598 case EAP_SIM_AT_PERMANENT_ID_REQ:
00599 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_PERMANENT_ID_REQ");
00600 attr->id_req = PERMANENT_ID;
00601 break;
00602 case EAP_SIM_AT_MAC:
00603 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_MAC");
00604 if (alen != 2 + EAP_SIM_MAC_LEN) {
00605 wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_MAC "
00606 "length");
00607 return -1;
00608 }
00609 attr->mac = apos + 2;
00610 break;
00611 case EAP_SIM_AT_NOTIFICATION:
00612 if (alen != 2) {
00613 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
00614 "AT_NOTIFICATION length %lu",
00615 (unsigned long) alen);
00616 return -1;
00617 }
00618 attr->notification = apos[0] * 256 + apos[1];
00619 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_NOTIFICATION %d",
00620 attr->notification);
00621 break;
00622 case EAP_SIM_AT_ANY_ID_REQ:
00623 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_ANY_ID_REQ");
00624 attr->id_req = ANY_ID;
00625 break;
00626 case EAP_SIM_AT_IDENTITY:
00627 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_IDENTITY");
00628 plen = WPA_GET_BE16(apos);
00629 apos += 2;
00630 alen -= 2;
00631 if (plen > alen) {
00632 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
00633 "AT_IDENTITY (Actual Length %lu, "
00634 "remaining length %lu)",
00635 (unsigned long) plen,
00636 (unsigned long) alen);
00637 return -1;
00638 }
00639
00640 attr->identity = apos;
00641 attr->identity_len = plen;
00642 break;
00643 case EAP_SIM_AT_VERSION_LIST:
00644 if (aka) {
00645 wpa_printf(MSG_DEBUG, "EAP-AKA: "
00646 "Unexpected AT_VERSION_LIST");
00647 return -1;
00648 }
00649 list_len = apos[0] * 256 + apos[1];
00650 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_VERSION_LIST");
00651 if (list_len < 2 || list_len > alen - 2) {
00652 wpa_printf(MSG_WARNING, "EAP-SIM: Invalid "
00653 "AT_VERSION_LIST (list_len=%lu "
00654 "attr_len=%lu)",
00655 (unsigned long) list_len,
00656 (unsigned long) alen);
00657 return -1;
00658 }
00659 attr->version_list = apos + 2;
00660 attr->version_list_len = list_len;
00661 break;
00662 case EAP_SIM_AT_SELECTED_VERSION:
00663 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_SELECTED_VERSION");
00664 if (alen != 2) {
00665 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
00666 "AT_SELECTED_VERSION length %lu",
00667 (unsigned long) alen);
00668 return -1;
00669 }
00670 attr->selected_version = apos[0] * 256 + apos[1];
00671 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_SELECTED_VERSION "
00672 "%d", attr->selected_version);
00673 break;
00674 case EAP_SIM_AT_FULLAUTH_ID_REQ:
00675 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_FULLAUTH_ID_REQ");
00676 attr->id_req = FULLAUTH_ID;
00677 break;
00678 case EAP_SIM_AT_COUNTER:
00679 if (!encr) {
00680 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
00681 "AT_COUNTER");
00682 return -1;
00683 }
00684 if (alen != 2) {
00685 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid "
00686 "AT_COUNTER (alen=%lu)",
00687 (unsigned long) alen);
00688 return -1;
00689 }
00690 attr->counter = apos[0] * 256 + apos[1];
00691 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) AT_COUNTER %d",
00692 attr->counter);
00693 break;
00694 case EAP_SIM_AT_COUNTER_TOO_SMALL:
00695 if (!encr) {
00696 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
00697 "AT_COUNTER_TOO_SMALL");
00698 return -1;
00699 }
00700 if (alen != 2) {
00701 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid "
00702 "AT_COUNTER_TOO_SMALL (alen=%lu)",
00703 (unsigned long) alen);
00704 return -1;
00705 }
00706 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) "
00707 "AT_COUNTER_TOO_SMALL");
00708 attr->counter_too_small = 1;
00709 break;
00710 case EAP_SIM_AT_NONCE_S:
00711 if (!encr) {
00712 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
00713 "AT_NONCE_S");
00714 return -1;
00715 }
00716 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) "
00717 "AT_NONCE_S");
00718 if (alen != 2 + EAP_SIM_NONCE_S_LEN) {
00719 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid "
00720 "AT_NONCE_S (alen=%lu)",
00721 (unsigned long) alen);
00722 return -1;
00723 }
00724 attr->nonce_s = apos + 2;
00725 break;
00726 case EAP_SIM_AT_CLIENT_ERROR_CODE:
00727 if (alen != 2) {
00728 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
00729 "AT_CLIENT_ERROR_CODE length %lu",
00730 (unsigned long) alen);
00731 return -1;
00732 }
00733 attr->client_error_code = apos[0] * 256 + apos[1];
00734 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_CLIENT_ERROR_CODE "
00735 "%d", attr->client_error_code);
00736 break;
00737 case EAP_SIM_AT_IV:
00738 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_IV");
00739 if (alen != 2 + EAP_SIM_MAC_LEN) {
00740 wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_IV "
00741 "length %lu", (unsigned long) alen);
00742 return -1;
00743 }
00744 attr->iv = apos + 2;
00745 break;
00746 case EAP_SIM_AT_ENCR_DATA:
00747 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_ENCR_DATA");
00748 attr->encr_data = apos + 2;
00749 attr->encr_data_len = alen - 2;
00750 if (attr->encr_data_len % 16) {
00751 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
00752 "AT_ENCR_DATA length %lu",
00753 (unsigned long)
00754 attr->encr_data_len);
00755 return -1;
00756 }
00757 break;
00758 case EAP_SIM_AT_NEXT_PSEUDONYM:
00759 if (!encr) {
00760 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
00761 "AT_NEXT_PSEUDONYM");
00762 return -1;
00763 }
00764 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) "
00765 "AT_NEXT_PSEUDONYM");
00766 plen = apos[0] * 256 + apos[1];
00767 if (plen > alen - 2) {
00768 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid"
00769 " AT_NEXT_PSEUDONYM (actual"
00770 " len %lu, attr len %lu)",
00771 (unsigned long) plen,
00772 (unsigned long) alen);
00773 return -1;
00774 }
00775 attr->next_pseudonym = pos + 4;
00776 attr->next_pseudonym_len = plen;
00777 break;
00778 case EAP_SIM_AT_NEXT_REAUTH_ID:
00779 if (!encr) {
00780 wpa_printf(MSG_ERROR, "EAP-SIM: Unencrypted "
00781 "AT_NEXT_REAUTH_ID");
00782 return -1;
00783 }
00784 wpa_printf(MSG_DEBUG, "EAP-SIM: (encr) "
00785 "AT_NEXT_REAUTH_ID");
00786 plen = apos[0] * 256 + apos[1];
00787 if (plen > alen - 2) {
00788 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid"
00789 " AT_NEXT_REAUTH_ID (actual"
00790 " len %lu, attr len %lu)",
00791 (unsigned long) plen,
00792 (unsigned long) alen);
00793 return -1;
00794 }
00795 attr->next_reauth_id = pos + 4;
00796 attr->next_reauth_id_len = plen;
00797 break;
00798 case EAP_SIM_AT_RES:
00799 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RES");
00800 attr->res_len_bits = WPA_GET_BE16(apos);
00801 apos += 2;
00802 alen -= 2;
00803 if (!aka || alen < EAP_AKA_MIN_RES_LEN ||
00804 alen > EAP_AKA_MAX_RES_LEN) {
00805 wpa_printf(MSG_INFO, "EAP-SIM: Invalid AT_RES "
00806 "(len %lu)",
00807 (unsigned long) alen);
00808 return -1;
00809 }
00810 attr->res = apos;
00811 attr->res_len = alen;
00812 break;
00813 case EAP_SIM_AT_AUTS:
00814 wpa_printf(MSG_DEBUG, "EAP-AKA: AT_AUTS");
00815 if (!aka) {
00816 wpa_printf(MSG_DEBUG, "EAP-SIM: "
00817 "Unexpected AT_AUTS");
00818 return -1;
00819 }
00820 if (alen != EAP_AKA_AUTS_LEN) {
00821 wpa_printf(MSG_INFO, "EAP-AKA: Invalid AT_AUTS"
00822 " (len %lu)",
00823 (unsigned long) alen);
00824 return -1;
00825 }
00826 attr->auts = apos;
00827 break;
00828 case EAP_SIM_AT_CHECKCODE:
00829 wpa_printf(MSG_DEBUG, "EAP-AKA: AT_CHECKCODE");
00830 if (!aka) {
00831 wpa_printf(MSG_DEBUG, "EAP-SIM: "
00832 "Unexpected AT_CHECKCODE");
00833 return -1;
00834 }
00835 apos += 2;
00836 alen -= 2;
00837 if (alen != 0 && alen != EAP_AKA_CHECKCODE_LEN &&
00838 alen != EAP_AKA_PRIME_CHECKCODE_LEN) {
00839 wpa_printf(MSG_INFO, "EAP-AKA: Invalid "
00840 "AT_CHECKCODE (len %lu)",
00841 (unsigned long) alen);
00842 return -1;
00843 }
00844 attr->checkcode = apos;
00845 attr->checkcode_len = alen;
00846 break;
00847 case EAP_SIM_AT_RESULT_IND:
00848 if (encr) {
00849 wpa_printf(MSG_ERROR, "EAP-SIM: Encrypted "
00850 "AT_RESULT_IND");
00851 return -1;
00852 }
00853 if (alen != 2) {
00854 wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
00855 "AT_RESULT_IND (alen=%lu)",
00856 (unsigned long) alen);
00857 return -1;
00858 }
00859 wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RESULT_IND");
00860 attr->result_ind = 1;
00861 break;
00862 #if defined(EAP_AKA_PRIME) || defined(EAP_SERVER_AKA_PRIME)
00863 case EAP_SIM_AT_KDF_INPUT:
00864 if (aka != 2) {
00865 wpa_printf(MSG_INFO, "EAP-AKA: Unexpected "
00866 "AT_KDF_INPUT");
00867 return -1;
00868 }
00869
00870 wpa_printf(MSG_DEBUG, "EAP-AKA: AT_KDF_INPUT");
00871 plen = WPA_GET_BE16(apos);
00872 apos += 2;
00873 alen -= 2;
00874 if (plen > alen) {
00875 wpa_printf(MSG_INFO, "EAP-AKA': Invalid "
00876 "AT_KDF_INPUT (Actual Length %lu, "
00877 "remaining length %lu)",
00878 (unsigned long) plen,
00879 (unsigned long) alen);
00880 return -1;
00881 }
00882 attr->kdf_input = apos;
00883 attr->kdf_input_len = plen;
00884 break;
00885 case EAP_SIM_AT_KDF:
00886 if (aka != 2) {
00887 wpa_printf(MSG_INFO, "EAP-AKA: Unexpected "
00888 "AT_KDF");
00889 return -1;
00890 }
00891
00892 wpa_printf(MSG_DEBUG, "EAP-AKA: AT_KDF");
00893 if (alen != 2) {
00894 wpa_printf(MSG_INFO, "EAP-AKA': Invalid "
00895 "AT_KDF (len %lu)",
00896 (unsigned long) alen);
00897 return -1;
00898 }
00899 if (attr->kdf_count == EAP_AKA_PRIME_KDF_MAX) {
00900 wpa_printf(MSG_DEBUG, "EAP-AKA': Too many "
00901 "AT_KDF attributes - ignore this");
00902 continue;
00903 }
00904 attr->kdf[attr->kdf_count] = WPA_GET_BE16(apos);
00905 attr->kdf_count++;
00906 break;
00907 case EAP_SIM_AT_BIDDING:
00908 wpa_printf(MSG_DEBUG, "EAP-AKA: AT_BIDDING");
00909 if (alen != 2) {
00910 wpa_printf(MSG_INFO, "EAP-AKA: Invalid "
00911 "AT_BIDDING (len %lu)",
00912 (unsigned long) alen);
00913 return -1;
00914 }
00915 attr->bidding = apos;
00916 break;
00917 #endif
00918 default:
00919 if (pos[0] < 128) {
00920 wpa_printf(MSG_INFO, "EAP-SIM: Unrecognized "
00921 "non-skippable attribute %d",
00922 pos[0]);
00923 return -1;
00924 }
00925
00926 wpa_printf(MSG_DEBUG, "EAP-SIM: Unrecognized skippable"
00927 " attribute %d ignored", pos[0]);
00928 break;
00929 }
00930
00931 pos += pos[1] * 4;
00932 }
00933
00934 wpa_printf(MSG_DEBUG, "EAP-SIM: Attributes parsed successfully "
00935 "(aka=%d encr=%d)", aka, encr);
00936
00937 return 0;
00938 }
00939
00940
00941 u8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data,
00942 size_t encr_data_len, const u8 *iv,
00943 struct eap_sim_attrs *attr, int aka)
00944 {
00945 u8 *decrypted;
00946
00947 if (!iv) {
00948 wpa_printf(MSG_INFO, "EAP-SIM: Encrypted data, but no IV");
00949 return NULL;
00950 }
00951
00952 decrypted = os_malloc(encr_data_len);
00953 if (decrypted == NULL)
00954 return NULL;
00955 os_memcpy(decrypted, encr_data, encr_data_len);
00956
00957 if (aes_128_cbc_decrypt(k_encr, iv, decrypted, encr_data_len)) {
00958 os_free(decrypted);
00959 return NULL;
00960 }
00961 wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Decrypted AT_ENCR_DATA",
00962 decrypted, encr_data_len);
00963
00964 if (eap_sim_parse_attr(decrypted, decrypted + encr_data_len, attr,
00965 aka, 1)) {
00966 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Failed to parse "
00967 "decrypted AT_ENCR_DATA");
00968 os_free(decrypted);
00969 return NULL;
00970 }
00971
00972 return decrypted;
00973 }
00974
00975
00976 #define EAP_SIM_INIT_LEN 128
00977
00978 struct eap_sim_msg {
00979 struct wpabuf *buf;
00980 size_t mac, iv, encr;
00981 int type;
00982 };
00983
00984
00985 struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype)
00986 {
00987 struct eap_sim_msg *msg;
00988 struct eap_hdr *eap;
00989 u8 *pos;
00990
00991 msg = os_zalloc(sizeof(*msg));
00992 if (msg == NULL)
00993 return NULL;
00994
00995 msg->type = type;
00996 msg->buf = wpabuf_alloc(EAP_SIM_INIT_LEN);
00997 if (msg->buf == NULL) {
00998 os_free(msg);
00999 return NULL;
01000 }
01001 eap = wpabuf_put(msg->buf, sizeof(*eap));
01002 eap->code = code;
01003 eap->identifier = id;
01004
01005 pos = wpabuf_put(msg->buf, 4);
01006 *pos++ = type;
01007 *pos++ = subtype;
01008 *pos++ = 0;
01009 *pos++ = 0;
01010
01011 return msg;
01012 }
01013
01014
01015 struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut,
01016 const u8 *extra, size_t extra_len)
01017 {
01018 struct eap_hdr *eap;
01019 struct wpabuf *buf;
01020
01021 if (msg == NULL)
01022 return NULL;
01023
01024 eap = wpabuf_mhead(msg->buf);
01025 eap->length = host_to_be16(wpabuf_len(msg->buf));
01026
01027 #if defined(EAP_AKA_PRIME) || defined(EAP_SERVER_AKA_PRIME)
01028 if (k_aut && msg->mac && msg->type == EAP_TYPE_AKA_PRIME) {
01029 eap_sim_add_mac_sha256(k_aut, (u8 *) wpabuf_head(msg->buf),
01030 wpabuf_len(msg->buf),
01031 (u8 *) wpabuf_mhead(msg->buf) +
01032 msg->mac, extra, extra_len);
01033 } else
01034 #endif
01035 if (k_aut && msg->mac) {
01036 eap_sim_add_mac(k_aut, (u8 *) wpabuf_head(msg->buf),
01037 wpabuf_len(msg->buf),
01038 (u8 *) wpabuf_mhead(msg->buf) + msg->mac,
01039 extra, extra_len);
01040 }
01041
01042 buf = msg->buf;
01043 os_free(msg);
01044 return buf;
01045 }
01046
01047
01048 void eap_sim_msg_free(struct eap_sim_msg *msg)
01049 {
01050 if (msg) {
01051 wpabuf_free(msg->buf);
01052 os_free(msg);
01053 }
01054 }
01055
01056
01057 u8 * eap_sim_msg_add_full(struct eap_sim_msg *msg, u8 attr,
01058 const u8 *data, size_t len)
01059 {
01060 int attr_len = 2 + len;
01061 int pad_len;
01062 u8 *start;
01063
01064 if (msg == NULL)
01065 return NULL;
01066
01067 pad_len = (4 - attr_len % 4) % 4;
01068 attr_len += pad_len;
01069 if (wpabuf_resize(&msg->buf, attr_len))
01070 return NULL;
01071 start = wpabuf_put(msg->buf, 0);
01072 wpabuf_put_u8(msg->buf, attr);
01073 wpabuf_put_u8(msg->buf, attr_len / 4);
01074 wpabuf_put_data(msg->buf, data, len);
01075 if (pad_len)
01076 os_memset(wpabuf_put(msg->buf, pad_len), 0, pad_len);
01077 return start;
01078 }
01079
01080
01081 u8 * eap_sim_msg_add(struct eap_sim_msg *msg, u8 attr, u16 value,
01082 const u8 *data, size_t len)
01083 {
01084 int attr_len = 4 + len;
01085 int pad_len;
01086 u8 *start;
01087
01088 if (msg == NULL)
01089 return NULL;
01090
01091 pad_len = (4 - attr_len % 4) % 4;
01092 attr_len += pad_len;
01093 if (wpabuf_resize(&msg->buf, attr_len))
01094 return NULL;
01095 start = wpabuf_put(msg->buf, 0);
01096 wpabuf_put_u8(msg->buf, attr);
01097 wpabuf_put_u8(msg->buf, attr_len / 4);
01098 wpabuf_put_be16(msg->buf, value);
01099 if (data)
01100 wpabuf_put_data(msg->buf, data, len);
01101 else
01102 wpabuf_put(msg->buf, len);
01103 if (pad_len)
01104 os_memset(wpabuf_put(msg->buf, pad_len), 0, pad_len);
01105 return start;
01106 }
01107
01108
01109 u8 * eap_sim_msg_add_mac(struct eap_sim_msg *msg, u8 attr)
01110 {
01111 u8 *pos = eap_sim_msg_add(msg, attr, 0, NULL, EAP_SIM_MAC_LEN);
01112 if (pos)
01113 msg->mac = (pos - wpabuf_head_u8(msg->buf)) + 4;
01114 return pos;
01115 }
01116
01117
01118 int eap_sim_msg_add_encr_start(struct eap_sim_msg *msg, u8 attr_iv,
01119 u8 attr_encr)
01120 {
01121 u8 *pos = eap_sim_msg_add(msg, attr_iv, 0, NULL, EAP_SIM_IV_LEN);
01122 if (pos == NULL)
01123 return -1;
01124 msg->iv = (pos - wpabuf_head_u8(msg->buf)) + 4;
01125 if (os_get_random(wpabuf_mhead_u8(msg->buf) + msg->iv,
01126 EAP_SIM_IV_LEN)) {
01127 msg->iv = 0;
01128 return -1;
01129 }
01130
01131 pos = eap_sim_msg_add(msg, attr_encr, 0, NULL, 0);
01132 if (pos == NULL) {
01133 msg->iv = 0;
01134 return -1;
01135 }
01136 msg->encr = pos - wpabuf_head_u8(msg->buf);
01137
01138 return 0;
01139 }
01140
01141
01142 int eap_sim_msg_add_encr_end(struct eap_sim_msg *msg, u8 *k_encr, int attr_pad)
01143 {
01144 size_t encr_len;
01145
01146 if (msg == NULL || k_encr == NULL || msg->iv == 0 || msg->encr == 0)
01147 return -1;
01148
01149 encr_len = wpabuf_len(msg->buf) - msg->encr - 4;
01150 if (encr_len % 16) {
01151 u8 *pos;
01152 int pad_len = 16 - (encr_len % 16);
01153 if (pad_len < 4) {
01154 wpa_printf(MSG_WARNING, "EAP-SIM: "
01155 "eap_sim_msg_add_encr_end - invalid pad_len"
01156 " %d", pad_len);
01157 return -1;
01158 }
01159 wpa_printf(MSG_DEBUG, " *AT_PADDING");
01160 pos = eap_sim_msg_add(msg, attr_pad, 0, NULL, pad_len - 4);
01161 if (pos == NULL)
01162 return -1;
01163 os_memset(pos + 4, 0, pad_len - 4);
01164 encr_len += pad_len;
01165 }
01166 wpa_printf(MSG_DEBUG, " (AT_ENCR_DATA data len %lu)",
01167 (unsigned long) encr_len);
01168 wpabuf_mhead_u8(msg->buf)[msg->encr + 1] = encr_len / 4 + 1;
01169 return aes_128_cbc_encrypt(k_encr, wpabuf_head_u8(msg->buf) + msg->iv,
01170 wpabuf_mhead_u8(msg->buf) + msg->encr + 4,
01171 encr_len);
01172 }
01173
01174
01175 void eap_sim_report_notification(void *msg_ctx, int notification, int aka)
01176 {
01177 #ifndef CONFIG_NO_STDOUT_DEBUG
01178 const char *type = aka ? "AKA" : "SIM";
01179 #endif
01180
01181 switch (notification) {
01182 case EAP_SIM_GENERAL_FAILURE_AFTER_AUTH:
01183 wpa_printf(MSG_WARNING, "EAP-%s: General failure "
01184 "notification (after authentication)", type);
01185 break;
01186 case EAP_SIM_TEMPORARILY_DENIED:
01187 wpa_printf(MSG_WARNING, "EAP-%s: Failure notification: "
01188 "User has been temporarily denied access to the "
01189 "requested service", type);
01190 break;
01191 case EAP_SIM_NOT_SUBSCRIBED:
01192 wpa_printf(MSG_WARNING, "EAP-%s: Failure notification: "
01193 "User has not subscribed to the requested service",
01194 type);
01195 break;
01196 case EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH:
01197 wpa_printf(MSG_WARNING, "EAP-%s: General failure "
01198 "notification (before authentication)", type);
01199 break;
01200 case EAP_SIM_SUCCESS:
01201 wpa_printf(MSG_INFO, "EAP-%s: Successful authentication "
01202 "notification", type);
01203 break;
01204 default:
01205 if (notification >= 32768) {
01206 wpa_printf(MSG_INFO, "EAP-%s: Unrecognized "
01207 "non-failure notification %d",
01208 type, notification);
01209 } else {
01210 wpa_printf(MSG_WARNING, "EAP-%s: Unrecognized "
01211 "failure notification %d",
01212 type, notification);
01213 }
01214 }
01215 }
01216