3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-22 23:09:34 +01:00

eap-pwd: Update EAP-PWD to allow larger ECC groups

Most of this work was already done after moving ECC into ELL, but
there were still a few places where the 256-bit group was assumed.
This allows the 384-bit group to be used, and theoretically any
other group added to ELL in the future.
This commit is contained in:
James Prestwood 2019-01-31 10:11:13 -08:00 committed by Denis Kenzior
parent 025ca0d4d3
commit bb28351c93

View File

@ -233,7 +233,8 @@ static void eap_pwd_handle_id(struct eap_state *eap,
uint8_t resp[15 + strlen(pwd->identity)]; uint8_t resp[15 + strlen(pwd->identity)];
uint8_t *pos; uint8_t *pos;
uint8_t pwd_seed[32]; uint8_t pwd_seed[32];
uint8_t pwd_value[32]; /* used as X value */ uint8_t pwd_value[L_ECC_SCALAR_MAX_BYTES]; /* used as X value */
size_t nbytes;
/* /*
* Group desc (2) + Random func (1) + prf (1) + token (4) + prep (1) + * Group desc (2) + Random func (1) + prf (1) + token (4) + prep (1) +
@ -252,9 +253,6 @@ static void eap_pwd_handle_id(struct eap_state *eap,
pwd->state = EAP_PWD_STATE_ID; pwd->state = EAP_PWD_STATE_ID;
group = l_get_be16(pkt); group = l_get_be16(pkt);
/* TODO: for now, lets only allow group 19 */
if (group != EAP_PWD_GROUP_DESC)
goto error;
pwd->curve = l_ecc_curve_get_ike_group(group); pwd->curve = l_ecc_curve_get_ike_group(group);
if (!pwd->curve) { if (!pwd->curve) {
@ -291,6 +289,8 @@ static void eap_pwd_handle_id(struct eap_state *eap,
goto error; goto error;
} }
nbytes = l_ecc_curve_get_scalar_bytes(pwd->curve);
while (counter < 20) { while (counter < 20) {
/* pwd-seed = H(token|peer-ID|server-ID|password|counter) */ /* pwd-seed = H(token|peer-ID|server-ID|password|counter) */
hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 5, pwd_seed, &token, 4, hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 5, pwd_seed, &token, 4,
@ -304,16 +304,16 @@ static void eap_pwd_handle_id(struct eap_state *eap,
*/ */
kdf(pwd_seed, 32, "EAP-pwd Hunting And Pecking", kdf(pwd_seed, 32, "EAP-pwd Hunting And Pecking",
strlen("EAP-pwd Hunting And Pecking"), strlen("EAP-pwd Hunting And Pecking"),
pwd_value, 32); pwd_value, nbytes);
if (!(pwd_seed[31] & 1)) if (!(pwd_seed[31] & 1))
pwd->pwe = l_ecc_point_from_data(pwd->curve, pwd->pwe = l_ecc_point_from_data(pwd->curve,
L_ECC_POINT_TYPE_COMPRESSED_BIT1, L_ECC_POINT_TYPE_COMPRESSED_BIT1,
pwd_value, 32); pwd_value, nbytes);
else else
pwd->pwe = l_ecc_point_from_data(pwd->curve, pwd->pwe = l_ecc_point_from_data(pwd->curve,
L_ECC_POINT_TYPE_COMPRESSED_BIT0, L_ECC_POINT_TYPE_COMPRESSED_BIT0,
pwd_value, 32); pwd_value, nbytes);
if (pwd->pwe) if (pwd->pwe)
break; break;
@ -345,13 +345,16 @@ static void eap_pwd_handle_commit(struct eap_state *eap,
const uint8_t *pkt, size_t len) const uint8_t *pkt, size_t len)
{ {
struct eap_pwd_handle *pwd = eap_get_data(eap); struct eap_pwd_handle *pwd = eap_get_data(eap);
uint8_t resp[102]; uint8_t resp[L_ECC_POINT_MAX_BYTES + L_ECC_SCALAR_MAX_BYTES + 6];
uint8_t *pos; uint8_t *pos;
struct l_ecc_scalar *p_mask; struct l_ecc_scalar *p_mask;
struct l_ecc_scalar *order; struct l_ecc_scalar *order;
size_t nbytes = l_ecc_curve_get_scalar_bytes(pwd->curve);
if (len != 96) { /* [Element (nbytes * 2)][Scalar (nbytes)] */
l_error("bad packet length, expected 96, got %zu", len); if (len != nbytes + nbytes * 2) {
l_error("bad packet length, expected %zu, got %zu",
nbytes + nbytes * 2, len);
goto error; goto error;
} }
@ -363,17 +366,16 @@ static void eap_pwd_handle_commit(struct eap_state *eap,
pwd->state = EAP_PWD_STATE_COMMIT; pwd->state = EAP_PWD_STATE_COMMIT;
/* /*
* RFC 5114 Section 2.6 - 256-bit Random ECP Group * Commit contains Element_S (nbytes * 2) then Scalar_s (nbytes)
* Prime p is 32 bytes in length, therefore x and y will also each be
* 32 bytes in length (total of 64), leaving the remainder for the
* scalar value (32).
*/ */
pwd->element_s = l_ecc_point_from_data(pwd->curve, pwd->element_s = l_ecc_point_from_data(pwd->curve,
L_ECC_POINT_TYPE_FULL, pkt, 64); L_ECC_POINT_TYPE_FULL,
pkt, nbytes * 2);
if (!pwd->element_s) if (!pwd->element_s)
goto invalid_point; goto invalid_point;
pwd->scalar_s = l_ecc_scalar_new(pwd->curve, (uint8_t *)pkt + 64, 32); pwd->scalar_s = l_ecc_scalar_new(pwd->curve,
(uint8_t *)pkt + (nbytes * 2), nbytes);
pwd->p_rand = l_ecc_scalar_new_random(pwd->curve); pwd->p_rand = l_ecc_scalar_new_random(pwd->curve);
p_mask = l_ecc_scalar_new_random(pwd->curve); p_mask = l_ecc_scalar_new_random(pwd->curve);
@ -397,8 +399,8 @@ static void eap_pwd_handle_commit(struct eap_state *eap,
/* send element_p and scalar_p */ /* send element_p and scalar_p */
pos = resp + 5; /* header */ pos = resp + 5; /* header */
*pos++ = EAP_PWD_EXCH_COMMIT; *pos++ = EAP_PWD_EXCH_COMMIT;
pos += l_ecc_point_get_data(pwd->element_p, pos, 64); pos += l_ecc_point_get_data(pwd->element_p, pos, nbytes * 2);
pos += l_ecc_scalar_get_data(pwd->scalar_p, pos, 32); pos += l_ecc_scalar_get_data(pwd->scalar_p, pos, nbytes);
eap_pwd_send_response(eap, resp, pos - resp); eap_pwd_send_response(eap, resp, pos - resp);