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

eap-pwd: mitigate potential timing attacks in EAP-PWD

Similar to SAE, EAP-PWD derives an ECC point (PWE). It is possible
for information to be gathered from the timing of this derivation,
which could be used to to recover the password.

This change adapts EAP-PWD to use the same mitigation technique as
SAE where we continue to derive ECC points even after we have found
a valid point. This derivation loop continues for a set number of
iterations (20 in this case), so anyone timing it will always see
the same timings for every run of the protocol.
This commit is contained in:
James Prestwood 2019-03-18 09:23:04 -07:00 committed by Denis Kenzior
parent 58522fe98f
commit 3863fa3670

View File

@ -229,12 +229,13 @@ static void eap_pwd_handle_id(struct eap_state *eap,
uint8_t rand_fn;
uint8_t prf;
uint32_t token;
uint8_t counter = 1;
uint8_t counter = 0;
uint8_t resp[15 + strlen(pwd->identity)];
uint8_t *pos;
uint8_t pwd_seed[32];
uint8_t pwd_value[L_ECC_SCALAR_MAX_BYTES]; /* used as X value */
size_t nbytes;
bool found = false;
/*
* Group desc (2) + Random func (1) + prf (1) + token (4) + prep (1) +
@ -292,6 +293,10 @@ static void eap_pwd_handle_id(struct eap_state *eap,
nbytes = l_ecc_curve_get_scalar_bytes(pwd->curve);
while (counter < 20) {
struct l_ecc_point *pwe = NULL;
counter++;
/* pwd-seed = H(token|peer-ID|server-ID|password|counter) */
hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 5, pwd_seed, &token, 4,
pwd->identity, strlen(pwd->identity), pkt + 9,
@ -307,18 +312,22 @@ static void eap_pwd_handle_id(struct eap_state *eap,
pwd_value, nbytes);
if (!(pwd_seed[31] & 1))
pwd->pwe = l_ecc_point_from_data(pwd->curve,
pwe = l_ecc_point_from_data(pwd->curve,
L_ECC_POINT_TYPE_COMPRESSED_BIT1,
pwd_value, nbytes);
else
pwd->pwe = l_ecc_point_from_data(pwd->curve,
pwe = l_ecc_point_from_data(pwd->curve,
L_ECC_POINT_TYPE_COMPRESSED_BIT0,
pwd_value, nbytes);
if (pwd->pwe)
break;
if (!pwe)
continue;
counter++;
if (!found) {
found = true;
pwd->pwe = pwe;
} else
l_ecc_point_free(pwe);
}
pos = resp + 5; /* header */