SAE: Use EC group context to get the group prime
Do not use the hardcoded group19_prime buffer for this to allow group negotiation. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
09200a1166
commit
a55f2eef71
3 changed files with 36 additions and 23 deletions
|
@ -16,14 +16,6 @@
|
||||||
#include "sae.h"
|
#include "sae.h"
|
||||||
|
|
||||||
|
|
||||||
static const u8 group19_prime[] = {
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int sae_set_group(struct sae_data *sae, int group)
|
int sae_set_group(struct sae_data *sae, int group)
|
||||||
{
|
{
|
||||||
crypto_ec_deinit(sae->ec);
|
crypto_ec_deinit(sae->ec);
|
||||||
|
@ -125,20 +117,23 @@ static void sae_pwd_seed_key(const u8 *addr1, const u8 *addr2, u8 *key)
|
||||||
static int sae_test_pwd_seed(struct sae_data *sae, const u8 *pwd_seed,
|
static int sae_test_pwd_seed(struct sae_data *sae, const u8 *pwd_seed,
|
||||||
struct crypto_ec_point *pwe, u8 *pwe_bin)
|
struct crypto_ec_point *pwe, u8 *pwe_bin)
|
||||||
{
|
{
|
||||||
u8 pwd_value[SAE_MAX_PRIME_LEN];
|
u8 pwd_value[SAE_MAX_PRIME_LEN], prime[SAE_MAX_PRIME_LEN];
|
||||||
struct crypto_bignum *x;
|
struct crypto_bignum *x;
|
||||||
int y_bit;
|
int y_bit;
|
||||||
|
|
||||||
|
if (crypto_bignum_to_bin(crypto_ec_get_prime(sae->ec),
|
||||||
|
prime, sizeof(prime), sae->prime_len) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
|
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
|
||||||
|
|
||||||
/* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
|
/* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
|
||||||
sha256_prf(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
|
sha256_prf(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
|
||||||
group19_prime, sizeof(group19_prime),
|
prime, sae->prime_len, pwd_value, sizeof(pwd_value));
|
||||||
pwd_value, sizeof(pwd_value));
|
|
||||||
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
|
wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
|
||||||
pwd_value, sizeof(pwd_value));
|
pwd_value, sizeof(pwd_value));
|
||||||
|
|
||||||
if (os_memcmp(pwd_value, group19_prime, sizeof(group19_prime)) >= 0)
|
if (os_memcmp(pwd_value, prime, sae->prime_len) >= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
y_bit = pwd_seed[SHA256_MAC_LEN - 1] & 0x01;
|
y_bit = pwd_seed[SHA256_MAC_LEN - 1] & 0x01;
|
||||||
|
@ -308,10 +303,12 @@ int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
|
||||||
|
|
||||||
static int sae_check_peer_commit(struct sae_data *sae)
|
static int sae_check_peer_commit(struct sae_data *sae)
|
||||||
{
|
{
|
||||||
u8 order[SAE_MAX_PRIME_LEN];
|
u8 order[SAE_MAX_PRIME_LEN], prime[SAE_MAX_PRIME_LEN];
|
||||||
|
|
||||||
if (crypto_bignum_to_bin(crypto_ec_get_order(sae->ec),
|
if (crypto_bignum_to_bin(crypto_ec_get_order(sae->ec),
|
||||||
order, sizeof(order), sae->prime_len) < 0)
|
order, sizeof(order), sae->prime_len) < 0 ||
|
||||||
|
crypto_bignum_to_bin(crypto_ec_get_prime(sae->ec),
|
||||||
|
prime, sizeof(prime), sae->prime_len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* 0 < scalar < r */
|
/* 0 < scalar < r */
|
||||||
|
@ -322,10 +319,9 @@ static int sae_check_peer_commit(struct sae_data *sae)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* element x and y coordinates < p */
|
/* element x and y coordinates < p */
|
||||||
if (os_memcmp(sae->peer_commit_element, group19_prime,
|
if (os_memcmp(sae->peer_commit_element, prime, sae->prime_len) >= 0 ||
|
||||||
sizeof(group19_prime)) >= 0 ||
|
os_memcmp(sae->peer_commit_element + sae->prime_len, prime,
|
||||||
os_memcmp(sae->peer_commit_element + sae->prime_len, group19_prime,
|
sae->prime_len) >= 0) {
|
||||||
sizeof(group19_prime)) >= 0) {
|
|
||||||
wpa_printf(MSG_DEBUG, "SAE: Invalid coordinates in peer "
|
wpa_printf(MSG_DEBUG, "SAE: Invalid coordinates in peer "
|
||||||
"element");
|
"element");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant / wrapper functions for crypto libraries
|
* Wrapper functions for crypto libraries
|
||||||
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -549,6 +549,13 @@ void crypto_ec_deinit(struct crypto_ec *e);
|
||||||
*/
|
*/
|
||||||
size_t crypto_ec_prime_len(struct crypto_ec *e);
|
size_t crypto_ec_prime_len(struct crypto_ec *e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crypto_ec_get_prime - Get prime defining an EC group
|
||||||
|
* @e: EC context from crypto_ec_init()
|
||||||
|
* Returns: Prime (bignum) defining the group
|
||||||
|
*/
|
||||||
|
const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_ec_get_order - Get order of an EC group
|
* crypto_ec_get_order - Get order of an EC group
|
||||||
* @e: EC context from crypto_ec_init()
|
* @e: EC context from crypto_ec_init()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant / wrapper functions for libcrypto
|
* Wrapper functions for OpenSSL libcrypto
|
||||||
* Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -901,6 +901,7 @@ struct crypto_ec {
|
||||||
EC_GROUP *group;
|
EC_GROUP *group;
|
||||||
BN_CTX *bnctx;
|
BN_CTX *bnctx;
|
||||||
size_t prime_len;
|
size_t prime_len;
|
||||||
|
BIGNUM *prime;
|
||||||
BIGNUM *order;
|
BIGNUM *order;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -918,8 +919,11 @@ struct crypto_ec * crypto_ec_init(int group)
|
||||||
e->prime_len = 32;
|
e->prime_len = 32;
|
||||||
e->bnctx = BN_CTX_new();
|
e->bnctx = BN_CTX_new();
|
||||||
e->group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
|
e->group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
|
||||||
|
e->prime = BN_new();
|
||||||
e->order = BN_new();
|
e->order = BN_new();
|
||||||
if (e->group == NULL || e->bnctx == NULL || e->order == NULL ||
|
if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
|
||||||
|
e->order == NULL ||
|
||||||
|
!EC_GROUP_get_curve_GFp(e->group, e->prime, NULL, NULL, e->bnctx) ||
|
||||||
!EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
|
!EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
|
||||||
crypto_ec_deinit(e);
|
crypto_ec_deinit(e);
|
||||||
e = NULL;
|
e = NULL;
|
||||||
|
@ -954,6 +958,12 @@ size_t crypto_ec_prime_len(struct crypto_ec *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
|
||||||
|
{
|
||||||
|
return (const struct crypto_bignum *) e->prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
|
const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
|
||||||
{
|
{
|
||||||
return (const struct crypto_bignum *) e->order;
|
return (const struct crypto_bignum *) e->order;
|
||||||
|
|
Loading…
Reference in a new issue