From b1677c393beea89fe0c43aa9c5ca1f7d21747b72 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 6 Jan 2013 15:47:37 +0200 Subject: [PATCH] SAE: Use more generic random bignum generation Move the bignum comparison part into the bignum library to allow a single implementation of rand generation for both ECC and FCC based groups. Signed-hostap: Jouni Malinen --- src/common/sae.c | 43 ++++++++++++++----------------------- src/crypto/crypto.h | 16 ++++++++++++++ src/crypto/crypto_openssl.c | 13 +++++++++++ 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/common/sae.c b/src/common/sae.c index a1445bb15..e49225341 100644 --- a/src/common/sae.c +++ b/src/common/sae.c @@ -123,28 +123,34 @@ static void buf_shift_right(u8 *buf, size_t len, size_t bits) } -static struct crypto_bignum * sae_get_rand(const u8 *order, - size_t order_len_bits) +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->order); size_t order_len = (order_len_bits + 7) / 8; - struct crypto_bignum *bn; if (order_len > sizeof(val)) return NULL; - do { + for (;;) { if (iter++ > 100) return NULL; if (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); - } while (os_memcmp(val, order, order_len) >= 0 || - val_zero_or_one(val, order_len)); + if (val_zero_or_one(val, order_len)) + continue; + bn = crypto_bignum_init_set(val, order_len); + if (bn == NULL) + return NULL; + if (crypto_bignum_cmp(bn, sae->order) >= 0) + continue; + break; + } - bn = crypto_bignum_init_set(val, order_len); os_memset(val, 0, order_len); return bn; } @@ -152,28 +158,11 @@ static struct crypto_bignum * sae_get_rand(const u8 *order, static struct crypto_bignum * sae_get_rand_and_mask(struct sae_data *sae) { - u8 order[SAE_MAX_PRIME_LEN]; - size_t prime_len_bits = crypto_ec_prime_len_bits(sae->ec); - - if (crypto_bignum_to_bin(sae->order, order, sizeof(order), - sae->prime_len) < 0) - return NULL; - crypto_bignum_deinit(sae->sae_rand, 1); - sae->sae_rand = sae_get_rand(order, prime_len_bits); + sae->sae_rand = sae_get_rand(sae); if (sae->sae_rand == NULL) return NULL; - return sae_get_rand(order, prime_len_bits); -} - - -static struct crypto_bignum * sae_get_rand_and_mask_dh(struct sae_data *sae) -{ - crypto_bignum_deinit(sae->sae_rand, 1); - sae->sae_rand = sae_get_rand(sae->dh->order, sae->dh->order_len * 8); - if (sae->sae_rand == NULL) - return NULL; - return sae_get_rand(sae->dh->order, sae->dh->order_len * 8); + return sae_get_rand(sae); } @@ -521,7 +510,7 @@ static int sae_derive_commit_dh(struct sae_data *sae, struct crypto_bignum *pwe) struct crypto_bignum *x, *mask, *elem; int ret = -1; - mask = sae_get_rand_and_mask_dh(sae); + mask = sae_get_rand_and_mask(sae); if (mask == NULL) { wpa_printf(MSG_DEBUG, "SAE: Could not get rand/mask"); return -1; diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 7c19d2b81..9170a0f3b 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -589,6 +589,22 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a, const struct crypto_bignum *c, struct crypto_bignum *d); +/** + * crypto_bignum_cmp - Compare two bignums + * @a: Bignum + * @b: Bignum + * Returns: -1 if a < b, 0 if a == b, or 1 if a > b + */ +int crypto_bignum_cmp(const struct crypto_bignum *a, + const struct crypto_bignum *b); + +/** + * crypto_bignum_bits - Get size of a bignum in bits + * @a: Bignum + * Returns: Number of bits in the bignum + */ +int crypto_bignum_bits(const struct crypto_bignum *a); + /** * struct crypto_ec - Elliptic curve context * diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index 80bc50fab..eeda57dea 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -987,6 +987,19 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a, } +int crypto_bignum_cmp(const struct crypto_bignum *a, + const struct crypto_bignum *b) +{ + return BN_cmp((const BIGNUM *) a, (const BIGNUM *) b); +} + + +int crypto_bignum_bits(const struct crypto_bignum *a) +{ + return BN_num_bits((const BIGNUM *) a); +} + + #ifdef CONFIG_ECC struct crypto_ec {