aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/sae.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/sae.c')
-rw-r--r--src/common/sae.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/src/common/sae.c b/src/common/sae.c
index fcca157..d9d6467 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -63,15 +63,27 @@ static int val_zero(const u8 *val, size_t len)
}
-static int sae_get_rand(const u8 *order, size_t prime_len, u8 *val)
+static void buf_shift_right(u8 *buf, size_t len, size_t bits)
+{
+ size_t i;
+ for (i = len - 1; i > 0; i--)
+ buf[i] = (buf[i - 1] << (8 - bits)) | (buf[i] >> bits);
+ buf[0] >>= bits;
+}
+
+
+static int sae_get_rand(const u8 *order, size_t prime_len_bits, u8 *val)
{
int iter = 0;
+ size_t prime_len = (prime_len_bits + 7) / 8;
do {
- if (random_get_bytes(val, prime_len) < 0)
- return -1;
if (iter++ > 100)
return -1;
+ if (random_get_bytes(val, prime_len) < 0)
+ return -1;
+ if (prime_len_bits % 8)
+ buf_shift_right(val, prime_len, 8 - prime_len_bits % 8);
} while (os_memcmp(val, order, prime_len) >= 0 ||
val_zero_or_one(val, prime_len));
@@ -83,13 +95,14 @@ static struct crypto_bignum * sae_get_rand_and_mask(struct sae_data *sae)
{
u8 mask[SAE_MAX_PRIME_LEN], order[SAE_MAX_PRIME_LEN];
struct crypto_bignum *bn;
+ size_t prime_len_bits = crypto_ec_prime_len_bits(sae->ec);
if (crypto_bignum_to_bin(crypto_ec_get_order(sae->ec),
order, sizeof(order), sae->prime_len) < 0)
return NULL;
- if (sae_get_rand(order, sae->prime_len, sae->sae_rand) < 0 ||
- sae_get_rand(order, sae->prime_len, mask) < 0)
+ if (sae_get_rand(order, prime_len_bits, sae->sae_rand) < 0 ||
+ sae_get_rand(order, prime_len_bits, mask) < 0)
return NULL;
wpa_hexdump_key(MSG_DEBUG, "SAE: rand",
sae->sae_rand, sae->prime_len);
@@ -120,6 +133,7 @@ static int sae_test_pwd_seed(struct sae_data *sae, const u8 *pwd_seed,
u8 pwd_value[SAE_MAX_PRIME_LEN], prime[SAE_MAX_PRIME_LEN];
struct crypto_bignum *x;
int y_bit;
+ size_t bits;
if (crypto_bignum_to_bin(crypto_ec_get_prime(sae->ec),
prime, sizeof(prime), sae->prime_len) < 0)
@@ -128,8 +142,11 @@ static int sae_test_pwd_seed(struct sae_data *sae, const u8 *pwd_seed,
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
/* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
- sha256_prf(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
- prime, sae->prime_len, pwd_value, sae->prime_len);
+ bits = crypto_ec_prime_len_bits(sae->ec);
+ sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
+ prime, sae->prime_len, pwd_value, bits);
+ if (bits % 8)
+ buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8);
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
pwd_value, sae->prime_len);
@@ -241,8 +258,10 @@ static int sae_derive_commit(struct sae_data *sae, struct crypto_ec_point *pwe)
int ret = -1;
mask = sae_get_rand_and_mask(sae);
- if (mask == NULL)
+ if (mask == NULL) {
+ wpa_printf(MSG_DEBUG, "SAE: Could not get rand/mask");
return -1;
+ }
x = crypto_bignum_init();
bn_rand = crypto_bignum_init_set(sae->sae_rand, sae->prime_len);
@@ -263,8 +282,10 @@ static int sae_derive_commit(struct sae_data *sae, struct crypto_ec_point *pwe)
crypto_ec_point_invert(sae->ec, elem) < 0 ||
crypto_ec_point_to_bin(sae->ec, elem, sae->own_commit_element,
sae->own_commit_element + sae->prime_len) <
- 0)
+ 0) {
+ wpa_printf(MSG_DEBUG, "SAE: Could not compute commit-element");
goto fail;
+ }
wpa_hexdump(MSG_DEBUG, "SAE: commit-element x",
sae->own_commit_element, sae->prime_len);