From 73338db029de6ef3accc019ae0479c618c967ad5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 26 Apr 2019 17:33:44 +0300 Subject: [PATCH] Share common SAE and EAP-pwd functionality: own scalar generation Use a shared helper function for deriving rand, mask, and own scalar. Signed-off-by: Jouni Malinen --- src/common/dragonfly.c | 36 ++++++++++++ src/common/dragonfly.h | 4 ++ src/common/sae.c | 98 +++++---------------------------- src/eap_common/eap_pwd_common.c | 23 +------- 4 files changed, 57 insertions(+), 104 deletions(-) diff --git a/src/common/dragonfly.c b/src/common/dragonfly.c index f6ecf43a3..10d968ac4 100644 --- a/src/common/dragonfly.c +++ b/src/common/dragonfly.c @@ -154,3 +154,39 @@ fail: crypto_bignum_deinit(qr_or_qnr, 1); return res; } + + +static int dragonfly_get_rand_2_to_r_1(struct crypto_bignum *val, + const struct crypto_bignum *order) +{ + return crypto_bignum_rand(val, order) == 0 && + !crypto_bignum_is_zero(val) && + !crypto_bignum_is_one(val); +} + + +int dragonfly_generate_scalar(const struct crypto_bignum *order, + struct crypto_bignum *_rand, + struct crypto_bignum *_mask, + struct crypto_bignum *scalar) +{ + int count; + + /* Select two random values rand,mask such that 1 < rand,mask < r and + * rand + mask mod r > 1. */ + for (count = 0; count < 100; count++) { + if (dragonfly_get_rand_2_to_r_1(_rand, order) && + dragonfly_get_rand_2_to_r_1(_mask, order) && + crypto_bignum_add(_rand, _mask, scalar) == 0 && + crypto_bignum_mod(scalar, order, scalar) == 0 && + !crypto_bignum_is_zero(scalar) && + !crypto_bignum_is_one(scalar)) + return 0; + } + + /* This should not be reachable in practice if the random number + * generation is working. */ + wpa_printf(MSG_INFO, + "dragonfly: Unable to get randomness for own scalar"); + return -1; +} diff --git a/src/common/dragonfly.h b/src/common/dragonfly.h index 1ec17a45c..e7627ef06 100644 --- a/src/common/dragonfly.h +++ b/src/common/dragonfly.h @@ -22,5 +22,9 @@ int dragonfly_get_random_qr_qnr(const struct crypto_bignum *prime, int dragonfly_is_quadratic_residue_blind(struct crypto_ec *ec, const u8 *qr, const u8 *qnr, const struct crypto_bignum *val); +int dragonfly_generate_scalar(const struct crypto_bignum *order, + struct crypto_bignum *_rand, + struct crypto_bignum *_mask, + struct crypto_bignum *scalar); #endif /* DRAGONFLY_H */ diff --git a/src/common/sae.c b/src/common/sae.c index 634c6a358..c1c80710c 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -121,49 +121,6 @@ void sae_clear_data(struct sae_data *sae) } -static struct crypto_bignum * sae_get_rand(struct sae_data *sae) -{ - u8 val[SAE_MAX_PRIME_LEN]; - int iter = 0; - struct crypto_bignum *bn = NULL; - int order_len_bits = crypto_bignum_bits(sae->tmp->order); - size_t order_len = (order_len_bits + 7) / 8; - - if (order_len > sizeof(val)) - return NULL; - - for (;;) { - if (iter++ > 100 || random_get_bytes(val, order_len) < 0) - return NULL; - if (order_len_bits % 8) - buf_shift_right(val, order_len, 8 - order_len_bits % 8); - bn = crypto_bignum_init_set(val, order_len); - if (bn == NULL) - return NULL; - if (crypto_bignum_is_zero(bn) || - crypto_bignum_is_one(bn) || - crypto_bignum_cmp(bn, sae->tmp->order) >= 0) { - crypto_bignum_deinit(bn, 0); - continue; - } - break; - } - - os_memset(val, 0, order_len); - return bn; -} - - -static struct crypto_bignum * sae_get_rand_and_mask(struct sae_data *sae) -{ - crypto_bignum_deinit(sae->tmp->sae_rand, 1); - sae->tmp->sae_rand = sae_get_rand(sae); - if (sae->tmp->sae_rand == NULL) - return NULL; - return sae_get_rand(sae); -} - - static void sae_pwd_seed_key(const u8 *addr1, const u8 *addr2, u8 *key) { wpa_printf(MSG_DEBUG, "SAE: PWE derivation - addr1=" MACSTR @@ -611,48 +568,23 @@ static int sae_derive_commit_element_ffc(struct sae_data *sae, static int sae_derive_commit(struct sae_data *sae) { struct crypto_bignum *mask; - int ret = -1; - unsigned int counter = 0; + int ret; - do { - counter++; - if (counter > 100) { - /* - * This cannot really happen in practice if the random - * number generator is working. Anyway, to avoid even a - * theoretical infinite loop, break out after 100 - * attemps. - */ - return -1; - } - - mask = sae_get_rand_and_mask(sae); - if (mask == NULL) { - wpa_printf(MSG_DEBUG, "SAE: Could not get rand/mask"); - return -1; - } - - /* commit-scalar = (rand + mask) modulo r */ - if (!sae->tmp->own_commit_scalar) { - sae->tmp->own_commit_scalar = crypto_bignum_init(); - if (!sae->tmp->own_commit_scalar) - goto fail; - } - crypto_bignum_add(sae->tmp->sae_rand, mask, - sae->tmp->own_commit_scalar); - crypto_bignum_mod(sae->tmp->own_commit_scalar, sae->tmp->order, - sae->tmp->own_commit_scalar); - } while (crypto_bignum_is_zero(sae->tmp->own_commit_scalar) || - crypto_bignum_is_one(sae->tmp->own_commit_scalar)); - - if ((sae->tmp->ec && sae_derive_commit_element_ecc(sae, mask) < 0) || - (sae->tmp->dh && sae_derive_commit_element_ffc(sae, mask) < 0)) - goto fail; - - ret = 0; -fail: + mask = crypto_bignum_init(); + if (!sae->tmp->sae_rand) + sae->tmp->sae_rand = crypto_bignum_init(); + if (!sae->tmp->own_commit_scalar) + sae->tmp->own_commit_scalar = crypto_bignum_init(); + ret = !mask || !sae->tmp->sae_rand || !sae->tmp->own_commit_scalar || + dragonfly_generate_scalar(sae->tmp->order, sae->tmp->sae_rand, + mask, + sae->tmp->own_commit_scalar) < 0 || + (sae->tmp->ec && + sae_derive_commit_element_ecc(sae, mask) < 0) || + (sae->tmp->dh && + sae_derive_commit_element_ffc(sae, mask) < 0); crypto_bignum_deinit(mask, 1); - return ret; + return ret ? -1 : 0; } diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c index 72aef4984..5b4f55c28 100644 --- a/src/eap_common/eap_pwd_common.c +++ b/src/eap_common/eap_pwd_common.c @@ -436,25 +436,6 @@ int eap_pwd_get_rand_mask(EAP_PWD_group *group, struct crypto_bignum *_rand, struct crypto_bignum *_mask, struct crypto_bignum *scalar) { - const struct crypto_bignum *order; - int count; - - order = crypto_ec_get_order(group->group); - - /* Select two random values rand,mask such that 1 < rand,mask < r and - * rand + mask mod r > 1. */ - for (count = 0; count < 100; count++) { - if (crypto_bignum_rand(_rand, order) == 0 && - !crypto_bignum_is_zero(_rand) && - crypto_bignum_rand(_mask, order) == 0 && - !crypto_bignum_is_zero(_mask) && - crypto_bignum_add(_rand, _mask, scalar) == 0 && - crypto_bignum_mod(scalar, order, scalar) == 0 && - !crypto_bignum_is_zero(scalar) && - !crypto_bignum_is_one(scalar)) - return 0; - } - - wpa_printf(MSG_INFO, "EAP-pwd: unable to get randomness"); - return -1; + return dragonfly_generate_scalar(crypto_ec_get_order(group->group), + _rand, _mask, scalar); }