diff --git a/src/eap-pwd.c b/src/eap-pwd.c index cd6684e7..5aa51668 100644 --- a/src/eap-pwd.c +++ b/src/eap-pwd.c @@ -320,7 +320,27 @@ static void eap_pwd_handle_id(struct eap_state *eap, strlen("EAP-pwd Hunting And Pecking"), pwd_value, nbytes); - if (!(pwd_seed[31] & 1)) + /* + * The RFC requires the point be solved unambiguously (since + * solving for Y results in two solutions). The correct Y value + * is chosen based on the LSB of the pwd-seed: + * + * if (LSB(y) == LSB(pwd-seed)) + * then + * PWE = (x, y) + * else + * PWE = (x, p-y) + * + * The ELL API (somewhat hidden from view here) automatically + * performs a subtraction (P - Y) when: + * - Y is even and BIT1 + * - Y is odd and BIT0 + * + * So we choose the point type which matches the parity of + * pwd-seed. This means a subtraction will be performed (P - Y) + * if the parity of pwd-seed and the computed Y do not match. + */ + if (pwd_seed[31] & 1) pwe = l_ecc_point_from_data(pwd->curve, L_ECC_POINT_TYPE_COMPRESSED_BIT1, pwd_value, nbytes);