SAE: Use more generic random bignum generation
authorJouni Malinen <j@w1.fi>
Sun, 6 Jan 2013 13:47:37 +0000 (15:47 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 12 Jan 2013 15:51:54 +0000 (17:51 +0200)
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 <j@w1.fi>

src/common/sae.c
src/crypto/crypto.h
src/crypto/crypto_openssl.c

index a1445bb..e492253 100644 (file)
@@ -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;
index 7c19d2b..9170a0f 100644 (file)
@@ -590,6 +590,22 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
                         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
  *
  * Internal data structure for EC implementation. The contents is specific
index 80bc50f..eeda57d 100644 (file)
@@ -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 {