12
12
* See README and COPYING for more details.
19
17
#include "common.h"
22
21
#include "aes_wrap.h"
23
22
#include "eap_sim_common.h"
30
static void eap_sim_prf(const u8 *key, u8 *x, size_t xlen)
38
/* FIPS 186-2 + change notice 1 */
40
memcpy(xkey, key, EAP_SIM_MK_LEN);
41
memset(xkey + EAP_SIM_MK_LEN, 0, 64 - EAP_SIM_MK_LEN);
49
for (j = 0; j < m; j++) {
51
for (i = 0; i < 2; i++) {
52
/* XVAL = (XKEY + XSEED_j) mod 2^b */
54
/* w_i = G(t, XVAL) */
56
sha1_transform((u8 *) _t, xkey);
57
_t[0] = host_to_be32(_t[0]);
58
_t[1] = host_to_be32(_t[1]);
59
_t[2] = host_to_be32(_t[2]);
60
_t[3] = host_to_be32(_t[3]);
61
_t[4] = host_to_be32(_t[4]);
64
/* XKEY = (1 + XKEY + w_i) mod 2^b */
66
for (k = 19; k >= 0; k--) {
67
carry += xkey[k] + xpos[k];
68
xkey[k] = carry & 0xff;
79
void eap_sim_derive_keys(const u8 *mk, u8 *k_encr, u8 *k_aut, u8 *msk)
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)
82
eap_sim_prf(mk, buf, 120);
83
if (eap_sim_prf(mk, buf, 120) < 0) {
84
wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys");
84
88
memcpy(k_encr, pos, EAP_SIM_K_ENCR_LEN);
85
89
pos += EAP_SIM_K_ENCR_LEN;
86
90
memcpy(k_aut, pos, EAP_SIM_K_AUT_LEN);
87
91
pos += EAP_SIM_K_AUT_LEN;
88
92
memcpy(msk, pos, EAP_SIM_KEYING_DATA_LEN);
91
94
wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_encr",
92
95
k_encr, EAP_SIM_K_ENCR_LEN);
93
96
wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: K_aut",
94
97
k_aut, EAP_SIM_K_ENCR_LEN);
95
wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: MSK",
97
wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Ext. MSK",
98
msk + MSK_LEN, EMSK_LEN);
99
98
wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: keying material",
100
msk, EAP_SIM_KEYING_DATA_LEN);
99
msk, EAP_SIM_KEYING_DATA_LEN);
104
void eap_sim_derive_keys_reauth(unsigned int _counter,
105
const u8 *identity, size_t identity_len,
106
const u8 *nonce_s, const u8 *mk, u8 *msk)
105
int eap_sim_derive_keys_reauth(u16 _counter,
106
const u8 *identity, size_t identity_len,
107
const u8 *nonce_s, const u8 *mk, u8 *msk)
108
109
u8 xkey[SHA1_MAC_LEN];
134
134
sha1_vector(4, addr, len, xkey);
135
135
wpa_hexdump(MSG_DEBUG, "EAP-SIM: XKEY'", xkey, SHA1_MAC_LEN);
137
eap_sim_prf(xkey, msk, EAP_SIM_KEYING_DATA_LEN);
138
wpa_hexdump(MSG_DEBUG, "EAP-SIM: MSK", msk, MSK_LEN);
139
wpa_hexdump(MSG_DEBUG, "EAP-SIM: Ext. MSK", msk + MSK_LEN, EMSK_LEN);
137
if (eap_sim_prf(xkey, msk, EAP_SIM_KEYING_DATA_LEN) < 0) {
138
wpa_printf(MSG_ERROR, "EAP-SIM: Failed to derive keys");
140
141
wpa_hexdump(MSG_DEBUG, "EAP-SIM: keying material",
141
142
msk, EAP_SIM_KEYING_DATA_LEN);
145
int eap_sim_verify_mac(const u8 *k_aut, u8 *req, size_t req_len, u8 *mac,
146
u8 *extra, size_t extra_len)
148
int eap_sim_verify_mac(const u8 *k_aut, const u8 *req, size_t req_len,
149
const u8 *mac, const u8 *extra, size_t extra_len)
148
151
unsigned char hmac[SHA1_MAC_LEN];
149
152
const u8 *addr[2];
151
u8 rx_mac[EAP_SIM_MAC_LEN];
156
if (mac == NULL || req_len < EAP_SIM_MAC_LEN || mac < req ||
157
mac > req + req_len - EAP_SIM_MAC_LEN)
160
tmp = malloc(req_len);
157
165
len[0] = req_len;
159
167
len[1] = extra_len;
161
169
/* HMAC-SHA1-128 */
162
memcpy(rx_mac, mac, EAP_SIM_MAC_LEN);
163
memset(mac, 0, EAP_SIM_MAC_LEN);
170
memcpy(tmp, req, req_len);
171
memset(tmp + (mac - req), 0, EAP_SIM_MAC_LEN);
164
172
hmac_sha1_vector(k_aut, EAP_SIM_K_AUT_LEN, 2, addr, len, hmac);
165
memcpy(mac, rx_mac, EAP_SIM_MAC_LEN);
167
175
return (memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
476
int eap_sim_parse_encr(const u8 *k_encr, u8 *encr_data, size_t encr_data_len,
477
const u8 *iv, struct eap_sim_attrs *attr, int aka)
513
u8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data,
514
size_t encr_data_len, const u8 *iv,
515
struct eap_sim_attrs *attr, int aka)
480
520
wpa_printf(MSG_INFO, "EAP-SIM: Encrypted data, but no IV");
483
aes_128_cbc_decrypt(k_encr, iv, encr_data, encr_data_len);
524
decrypted = malloc(encr_data_len);
525
if (decrypted == NULL)
527
memcpy(decrypted, encr_data, encr_data_len);
529
aes_128_cbc_decrypt(k_encr, iv, decrypted, encr_data_len);
484
530
wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Decrypted AT_ENCR_DATA",
485
encr_data, encr_data_len);
531
decrypted, encr_data_len);
487
if (eap_sim_parse_attr(encr_data, encr_data + encr_data_len, attr,
533
if (eap_sim_parse_attr(decrypted, decrypted + encr_data_len, attr,
489
535
wpa_printf(MSG_INFO, "EAP-SIM: (encr) Failed to parse "
490
536
"decrypted AT_ENCR_DATA");
751
#ifdef TEST_MAIN_EAP_SIM_COMMON
752
static int test_eap_sim_prf(void)
754
/* http://csrc.nist.gov/encryption/dss/Examples-1024bit.pdf */
756
0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b,
757
0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f,
758
0xeb, 0x5a, 0x38, 0xb6
761
0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f,
762
0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49,
763
0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba,
764
0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
765
0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16
769
printf("Testing EAP-SIM PRF (FIPS 186-2 + change notice 1)\n");
770
eap_sim_prf(xkey, buf, sizeof(buf));
771
if (memcmp(w, buf, sizeof(w) != 0)) {
772
printf("eap_sim_prf failed\n");
780
int main(int argc, char *argv[])
784
errors += test_eap_sim_prf();
788
#endif /* TEST_MAIN_EAP_SIM_COMMON */