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:
Jouni Malinen 2013-01-01 12:27:00 +02:00
parent 09200a1166
commit a55f2eef71
3 changed files with 36 additions and 23 deletions

View file

@ -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;

View file

@ -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()

View file

@ -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;