int eap_sim_derive_keys(const u8 *mk, u8 *k_encr, u8 *k_aut, u8 *msk, u8 *emsk) { u8 buf[EAP_SIM_K_ENCR_LEN + EAP_SIM_K_AUT_LEN + EAP_SIM_KEYING_DATA_LEN + EAP_EMSK_LEN], *pos; if (eap_sim_prf(mk, buf, sizeof(buf)) < 0) { wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys"); return -1; } pos = buf; os_memcpy(k_encr, pos, EAP_SIM_K_ENCR_LEN); pos += EAP_SIM_K_ENCR_LEN; os_memcpy(k_aut, pos, EAP_SIM_K_AUT_LEN); pos += EAP_SIM_K_AUT_LEN; os_memcpy(msk, pos, EAP_SIM_KEYING_DATA_LEN); pos += EAP_SIM_KEYING_DATA_LEN; os_memcpy(emsk, pos, EAP_EMSK_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_encr", k_encr, EAP_SIM_K_ENCR_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_aut", k_aut, EAP_SIM_K_AUT_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: keying material (MSK)", msk, EAP_SIM_KEYING_DATA_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: EMSK", emsk, EAP_EMSK_LEN); os_memset(buf, 0, sizeof(buf)); return 0; }
static int test_eap_sim_prf(void) { /* http://csrc.nist.gov/encryption/dss/Examples-1024bit.pdf */ u8 xkey[] = { 0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b, 0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f, 0xeb, 0x5a, 0x38, 0xb6 }; u8 w[] = { 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f, 0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49, 0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba, 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78, 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16 }; u8 buf[40]; printf("Testing EAP-SIM PRF (FIPS 186-2 + change notice 1)\n"); eap_sim_prf(xkey, buf, sizeof(buf)); if (memcmp(w, buf, sizeof(w) != 0)) { printf("eap_sim_prf failed\n"); return 1; } return 0; }
int eap_sim_derive_keys_reauth(u16 _counter, const u8 *identity, size_t identity_len, const u8 *nonce_s, const u8 *mk, u8 *msk, u8 *emsk) { u8 xkey[SHA1_MAC_LEN]; u8 buf[EAP_SIM_KEYING_DATA_LEN + EAP_EMSK_LEN + 32]; u8 counter[2]; const u8 *addr[4]; size_t len[4]; while (identity_len > 0 && identity[identity_len - 1] == 0) { wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop null " "character from the end of identity"); identity_len--; } addr[0] = identity; len[0] = identity_len; addr[1] = counter; len[1] = 2; addr[2] = nonce_s; len[2] = EAP_SIM_NONCE_S_LEN; addr[3] = mk; len[3] = EAP_SIM_MK_LEN; WPA_PUT_BE16(counter, _counter); wpa_printf(MSG_DEBUG, "EAP-SIM: Deriving keying data from reauth"); wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity", identity, identity_len); wpa_hexdump(MSG_DEBUG, "EAP-SIM: counter", counter, 2); wpa_hexdump(MSG_DEBUG, "EAP-SIM: NONCE_S", nonce_s, EAP_SIM_NONCE_S_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: MK", mk, EAP_SIM_MK_LEN); /* XKEY' = SHA1(Identity|counter|NONCE_S|MK) */ sha1_vector(4, addr, len, xkey); wpa_hexdump(MSG_DEBUG, "EAP-SIM: XKEY'", xkey, SHA1_MAC_LEN); if (eap_sim_prf(xkey, buf, sizeof(buf)) < 0) { wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys"); return -1; } if (msk) { os_memcpy(msk, buf, EAP_SIM_KEYING_DATA_LEN); wpa_hexdump(MSG_DEBUG, "EAP-SIM: keying material (MSK)", msk, EAP_SIM_KEYING_DATA_LEN); } if (emsk) { os_memcpy(emsk, buf + EAP_SIM_KEYING_DATA_LEN, EAP_EMSK_LEN); wpa_hexdump(MSG_DEBUG, "EAP-SIM: EMSK", emsk, EAP_EMSK_LEN); } os_memset(buf, 0, sizeof(buf)); return 0; }