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 <jouni@codeaurora.org>
This commit is contained in:
parent
c3805fb623
commit
73338db029
4 changed files with 57 additions and 104 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue