EAP-pwd: Fix some interoperability issues
The changes are: 1. the word "and" in the hunting-and-pecking string passed to the KDF should be capitalized. 2. the primebitlen used in the KDF should be a short not an int. 3. the computation of MK in hostap is based on an older version of the draft and is not the way it's specified in the RFC. 4. the group being passed into computation of the Commit was not in network order.
This commit is contained in:
parent
b13d3d63d5
commit
e4d7b22a53
4 changed files with 30 additions and 54 deletions
|
@ -184,8 +184,8 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
|
|||
BN_bin2bn(pwe_digest, SHA256_DIGEST_LENGTH, rnd);
|
||||
|
||||
eap_pwd_kdf(pwe_digest, SHA256_DIGEST_LENGTH,
|
||||
(unsigned char *) "EAP-pwd Hunting and Pecking",
|
||||
os_strlen("EAP-pwd Hunting and Pecking"),
|
||||
(unsigned char *) "EAP-pwd Hunting And Pecking",
|
||||
os_strlen("EAP-pwd Hunting And Pecking"),
|
||||
prfbuf, primebitlen);
|
||||
|
||||
BN_bin2bn(prfbuf, primebytelen, x_candidate);
|
||||
|
@ -264,22 +264,16 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
|
|||
|
||||
|
||||
int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, BIGNUM *k,
|
||||
EC_POINT *server_element, EC_POINT *peer_element,
|
||||
BIGNUM *server_scalar, BIGNUM *peer_scalar, u32 *ciphersuite,
|
||||
u8 *msk, u8 *emsk)
|
||||
BIGNUM *peer_scalar, BIGNUM *server_scalar,
|
||||
u8 *commit_peer, u8 *commit_server,
|
||||
u32 *ciphersuite, u8 *msk, u8 *emsk)
|
||||
{
|
||||
BIGNUM *scalar_sum, *x;
|
||||
EC_POINT *element_sum;
|
||||
HMAC_CTX ctx;
|
||||
u8 mk[SHA256_DIGEST_LENGTH], *cruft;
|
||||
u8 session_id[SHA256_DIGEST_LENGTH + 1];
|
||||
u8 msk_emsk[EAP_MSK_LEN + EAP_EMSK_LEN];
|
||||
int ret = -1;
|
||||
|
||||
if (((cruft = os_malloc(BN_num_bytes(grp->prime))) == NULL) ||
|
||||
((x = BN_new()) == NULL) ||
|
||||
((scalar_sum = BN_new()) == NULL) ||
|
||||
((element_sum = EC_POINT_new(grp->group)) == NULL))
|
||||
if ((cruft = os_malloc(BN_num_bytes(grp->prime))) == NULL)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
|
@ -295,34 +289,13 @@ int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, BIGNUM *k,
|
|||
H_Update(&ctx, cruft, BN_num_bytes(grp->order));
|
||||
H_Final(&ctx, &session_id[1]);
|
||||
|
||||
/*
|
||||
* then compute MK = H(k | F(elem_p + elem_s) |
|
||||
* (scal_p + scal_s) mod r)
|
||||
*/
|
||||
/* then compute MK = H(k | commit-peer | commit-server) */
|
||||
H_Init(&ctx);
|
||||
|
||||
/* k */
|
||||
os_memset(cruft, 0, BN_num_bytes(grp->prime));
|
||||
BN_bn2bin(k, cruft);
|
||||
H_Update(&ctx, cruft, BN_num_bytes(grp->prime));
|
||||
|
||||
/* x = F(elem_p + elem_s) */
|
||||
if ((!EC_POINT_add(grp->group, element_sum, server_element,
|
||||
peer_element, bnctx)) ||
|
||||
(!EC_POINT_get_affine_coordinates_GFp(grp->group, element_sum, x,
|
||||
NULL, bnctx)))
|
||||
goto fail;
|
||||
|
||||
os_memset(cruft, 0, BN_num_bytes(grp->prime));
|
||||
BN_bn2bin(x, cruft);
|
||||
H_Update(&ctx, cruft, BN_num_bytes(grp->prime));
|
||||
|
||||
/* (scal_p + scal_s) mod r */
|
||||
BN_add(scalar_sum, server_scalar, peer_scalar);
|
||||
BN_mod(scalar_sum, scalar_sum, grp->order, bnctx);
|
||||
os_memset(cruft, 0, BN_num_bytes(grp->prime));
|
||||
BN_bn2bin(scalar_sum, cruft);
|
||||
H_Update(&ctx, cruft, BN_num_bytes(grp->order));
|
||||
H_Update(&ctx, commit_peer, SHA256_DIGEST_LENGTH);
|
||||
H_Update(&ctx, commit_server, SHA256_DIGEST_LENGTH);
|
||||
H_Final(&ctx, mk);
|
||||
|
||||
/* stretch the mk with the session-id to get MSK | EMSK */
|
||||
|
@ -333,13 +306,7 @@ int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, BIGNUM *k,
|
|||
os_memcpy(msk, msk_emsk, EAP_MSK_LEN);
|
||||
os_memcpy(emsk, msk_emsk + EAP_MSK_LEN, EAP_EMSK_LEN);
|
||||
|
||||
ret = 1;
|
||||
|
||||
fail:
|
||||
BN_free(x);
|
||||
BN_free(scalar_sum);
|
||||
EC_POINT_free(element_sum);
|
||||
os_free(cruft);
|
||||
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -70,8 +70,8 @@ struct eap_pwd_id {
|
|||
/* common routines */
|
||||
int compute_password_element(EAP_PWD_group *, u16, u8 *, int, u8 *, int, u8 *,
|
||||
int, u8 *);
|
||||
int compute_keys(EAP_PWD_group *, BN_CTX *, BIGNUM *, EC_POINT *, EC_POINT *,
|
||||
BIGNUM *, BIGNUM *, u32 *, u8 *, u8 *);
|
||||
int compute_keys(EAP_PWD_group *, BN_CTX *, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
u8 *, u8 *, u32 *, u8 *, u8 *);
|
||||
void H_Init(HMAC_CTX *);
|
||||
void H_Update(HMAC_CTX *, const u8 *, int);
|
||||
void H_Final(HMAC_CTX *, u8 *);
|
||||
|
|
|
@ -463,14 +463,16 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|||
BIGNUM *x = NULL, *y = NULL;
|
||||
HMAC_CTX ctx;
|
||||
u32 cs;
|
||||
u16 grp;
|
||||
u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
|
||||
|
||||
/*
|
||||
* first build up the ciphersuite which is group | random_function |
|
||||
* prf
|
||||
*/
|
||||
grp = htons(data->group_num);
|
||||
ptr = (u8 *) &cs;
|
||||
os_memcpy(ptr, &data->group_num, sizeof(u16));
|
||||
os_memcpy(ptr, &grp, sizeof(u16));
|
||||
ptr += sizeof(u16);
|
||||
*ptr = EAP_PWD_DEFAULT_RAND_FUNC;
|
||||
ptr += sizeof(u8);
|
||||
|
@ -620,9 +622,9 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
|
|||
wpabuf_put_u8(resp, EAP_PWD_OPCODE_CONFIRM_EXCH);
|
||||
wpabuf_put_data(resp, conf, SHA256_DIGEST_LENGTH);
|
||||
|
||||
if (compute_keys(data->grp, data->bnctx, data->k, data->server_element,
|
||||
data->my_element, data->server_scalar,
|
||||
data->my_scalar, &cs, data->msk, data->emsk) < 0) {
|
||||
if (compute_keys(data->grp, data->bnctx, data->k,
|
||||
data->my_scalar, data->server_scalar, conf, ptr,
|
||||
&cs, data->msk, data->emsk) < 0) {
|
||||
wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute MSK | "
|
||||
"EMSK");
|
||||
goto fin;
|
||||
|
|
|
@ -40,6 +40,8 @@ struct eap_pwd_data {
|
|||
EC_POINT *my_element;
|
||||
EC_POINT *peer_element;
|
||||
|
||||
u8 my_confirm[SHA256_DIGEST_LENGTH];
|
||||
|
||||
u8 msk[EAP_MSK_LEN];
|
||||
u8 emsk[EAP_EMSK_LEN];
|
||||
|
||||
|
@ -286,6 +288,7 @@ eap_pwd_build_confirm_req(struct eap_sm *sm, struct eap_pwd_data *data, u8 id)
|
|||
BIGNUM *x = NULL, *y = NULL;
|
||||
HMAC_CTX ctx;
|
||||
u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
|
||||
u16 grp;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-pwd: Confirm/Request");
|
||||
|
||||
|
@ -356,9 +359,10 @@ eap_pwd_build_confirm_req(struct eap_sm *sm, struct eap_pwd_data *data, u8 id)
|
|||
H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
|
||||
|
||||
/* ciphersuite */
|
||||
grp = htons(data->group_num);
|
||||
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
|
||||
ptr = cruft;
|
||||
os_memcpy(ptr, &data->group_num, sizeof(u16));
|
||||
os_memcpy(ptr, &grp, sizeof(u16));
|
||||
ptr += sizeof(u16);
|
||||
*ptr = EAP_PWD_DEFAULT_RAND_FUNC;
|
||||
ptr += sizeof(u8);
|
||||
|
@ -368,6 +372,7 @@ eap_pwd_build_confirm_req(struct eap_sm *sm, struct eap_pwd_data *data, u8 id)
|
|||
|
||||
/* all done with the random function */
|
||||
H_Final(&ctx, conf);
|
||||
os_memcpy(data->my_confirm, conf, SHA256_DIGEST_LENGTH);
|
||||
|
||||
req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD,
|
||||
sizeof(struct eap_pwd_hdr) + SHA256_DIGEST_LENGTH,
|
||||
|
@ -617,11 +622,13 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
|
|||
BIGNUM *x = NULL, *y = NULL;
|
||||
HMAC_CTX ctx;
|
||||
u32 cs;
|
||||
u16 grp;
|
||||
u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
|
||||
|
||||
/* build up the ciphersuite: group | random_function | prf */
|
||||
grp = htons(data->group_num);
|
||||
ptr = (u8 *) &cs;
|
||||
os_memcpy(ptr, &data->group_num, sizeof(u16));
|
||||
os_memcpy(ptr, &grp, sizeof(u16));
|
||||
ptr += sizeof(u16);
|
||||
*ptr = EAP_PWD_DEFAULT_RAND_FUNC;
|
||||
ptr += sizeof(u8);
|
||||
|
@ -701,9 +708,9 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
|
|||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-pwd (server): confirm verified");
|
||||
if (compute_keys(data->grp, data->bnctx, data->k, data->my_element,
|
||||
data->peer_element, data->my_scalar,
|
||||
data->peer_scalar, &cs, data->msk, data->emsk) < 0)
|
||||
if (compute_keys(data->grp, data->bnctx, data->k,
|
||||
data->peer_scalar, data->my_scalar, conf,
|
||||
data->my_confirm, &cs, data->msk, data->emsk) < 0)
|
||||
eap_pwd_state(data, FAILURE);
|
||||
else
|
||||
eap_pwd_state(data, SUCCESS);
|
||||
|
|
Loading…
Reference in a new issue