diff --git a/src/common/dragonfly.c b/src/common/dragonfly.c index 1e8040465..334f492d4 100644 --- a/src/common/dragonfly.c +++ b/src/common/dragonfly.c @@ -10,6 +10,7 @@ #include "utils/includes.h" #include "utils/common.h" +#include "crypto/crypto.h" #include "dragonfly.h" @@ -25,3 +26,35 @@ int dragonfly_suitable_group(int group, int ecc_only) (!ecc_only && (group == 15 || group == 16 || group == 17 || group == 18)); } + + +int dragonfly_get_random_qr_qnr(const struct crypto_bignum *prime, + struct crypto_bignum **qr, + struct crypto_bignum **qnr) +{ + *qr = *qnr = NULL; + + while (!(*qr) || !(*qnr)) { + struct crypto_bignum *tmp; + int res; + + tmp = crypto_bignum_init(); + if (!tmp || crypto_bignum_rand(tmp, prime) < 0) + break; + + res = crypto_bignum_legendre(tmp, prime); + if (res == 1 && !(*qr)) + *qr = tmp; + else if (res == -1 && !(*qnr)) + *qnr = tmp; + else + crypto_bignum_deinit(tmp, 0); + } + + if (*qr && *qnr) + return 0; + crypto_bignum_deinit(*qr, 0); + crypto_bignum_deinit(*qnr, 0); + *qr = *qnr = NULL; + return -1; +} diff --git a/src/common/dragonfly.h b/src/common/dragonfly.h index 9f3c4289d..99a185159 100644 --- a/src/common/dragonfly.h +++ b/src/common/dragonfly.h @@ -10,6 +10,11 @@ #ifndef DRAGONFLY_H #define DRAGONFLY_H +struct crypto_bignum; + int dragonfly_suitable_group(int group, int ecc_only); +int dragonfly_get_random_qr_qnr(const struct crypto_bignum *prime, + struct crypto_bignum **qr, + struct crypto_bignum **qnr); #endif /* DRAGONFLY_H */ diff --git a/src/common/sae.c b/src/common/sae.c index 205395868..67d83edd0 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -401,42 +401,6 @@ fail: } -static int get_random_qr_qnr(const u8 *prime, size_t prime_len, - const struct crypto_bignum *prime_bn, - size_t prime_bits, struct crypto_bignum **qr, - struct crypto_bignum **qnr) -{ - *qr = NULL; - *qnr = NULL; - - while (!(*qr) || !(*qnr)) { - u8 tmp[SAE_MAX_ECC_PRIME_LEN]; - struct crypto_bignum *q; - int res; - - if (random_get_bytes(tmp, prime_len) < 0) - break; - if (prime_bits % 8) - buf_shift_right(tmp, prime_len, 8 - prime_bits % 8); - if (os_memcmp(tmp, prime, prime_len) >= 0) - continue; - q = crypto_bignum_init_set(tmp, prime_len); - if (!q) - break; - res = crypto_bignum_legendre(q, prime_bn); - - if (res == 1 && !(*qr)) - *qr = q; - else if (res == -1 && !(*qnr)) - *qnr = q; - else - crypto_bignum_deinit(q, 0); - } - - return (*qr && *qnr) ? 0 : -1; -} - - static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1, const u8 *addr2, const u8 *password, size_t password_len, const char *identifier) @@ -455,7 +419,6 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1, u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN]; u8 qr_bin[SAE_MAX_ECC_PRIME_LEN]; u8 qnr_bin[SAE_MAX_ECC_PRIME_LEN]; - size_t bits; int res = -1; u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_* * mask */ @@ -472,14 +435,12 @@ static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1, if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime), prime_len) < 0) goto fail; - bits = crypto_ec_prime_len_bits(sae->tmp->ec); /* * Create a random quadratic residue (qr) and quadratic non-residue * (qnr) modulo p for blinding purposes during the loop. */ - if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits, - &qr, &qnr) < 0 || + if (dragonfly_get_random_qr_qnr(sae->tmp->prime, &qr, &qnr) < 0 || crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin), prime_len) < 0 || crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin), prime_len) < 0) goto fail; diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c index abee3daa9..45ccff455 100644 --- a/src/eap_common/eap_pwd_common.c +++ b/src/eap_common/eap_pwd_common.c @@ -168,21 +168,8 @@ int compute_password_element(EAP_PWD_group *grp, u16 num, goto fail; /* get a random quadratic residue and nonresidue */ - while (!qr || !qnr) { - if (crypto_bignum_rand(tmp1, prime) < 0) - goto fail; - res = crypto_bignum_legendre(tmp1, prime); - if (!qr && res == 1) { - qr = tmp1; - tmp1 = crypto_bignum_init(); - } else if (!qnr && res == -1) { - qnr = tmp1; - tmp1 = crypto_bignum_init(); - } - if (!tmp1) - goto fail; - } - if (crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin), + if (dragonfly_get_random_qr_qnr(prime, &qr, &qnr) < 0 || + crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin), primebytelen) < 0 || crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin), primebytelen) < 0)