SAE: Store the group order in EC context data

This makes the SAE implementation a bit simpler by not having to build
the bignum for group order during execution.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2013-01-01 11:54:54 +02:00
parent 4925b303db
commit ce46ec8df0
3 changed files with 24 additions and 13 deletions

View file

@ -227,7 +227,7 @@ static int sae_derive_pwe(struct sae_data *sae, const u8 *addr1,
static int sae_derive_commit(struct sae_data *sae, struct crypto_ec_point *pwe) static int sae_derive_commit(struct sae_data *sae, struct crypto_ec_point *pwe)
{ {
struct crypto_bignum *x, *bn_rand, *bn_mask, *order; struct crypto_bignum *x, *bn_rand, *bn_mask;
struct crypto_ec_point *elem; struct crypto_ec_point *elem;
u8 mask[SAE_MAX_PRIME_LEN]; u8 mask[SAE_MAX_PRIME_LEN];
int ret = -1; int ret = -1;
@ -241,15 +241,13 @@ static int sae_derive_commit(struct sae_data *sae, struct crypto_ec_point *pwe)
x = crypto_bignum_init(); x = crypto_bignum_init();
bn_rand = crypto_bignum_init_set(sae->sae_rand, sae->prime_len); bn_rand = crypto_bignum_init_set(sae->sae_rand, sae->prime_len);
bn_mask = crypto_bignum_init_set(mask, sizeof(mask)); bn_mask = crypto_bignum_init_set(mask, sizeof(mask));
order = crypto_bignum_init_set(group19_order, sizeof(group19_order));
elem = crypto_ec_point_init(sae->ec); elem = crypto_ec_point_init(sae->ec);
if (x == NULL || bn_rand == NULL || bn_mask == NULL || order == NULL || if (x == NULL || bn_rand == NULL || bn_mask == NULL || elem == NULL)
elem == NULL)
goto fail; goto fail;
/* commit-scalar = (rand + mask) modulo r */ /* commit-scalar = (rand + mask) modulo r */
crypto_bignum_add(bn_rand, bn_mask, x); crypto_bignum_add(bn_rand, bn_mask, x);
crypto_bignum_mod(x, order, x); crypto_bignum_mod(x, crypto_ec_get_order(sae->ec), x);
crypto_bignum_to_bin(x, sae->own_commit_scalar, crypto_bignum_to_bin(x, sae->own_commit_scalar,
sizeof(sae->own_commit_scalar), sae->prime_len); sizeof(sae->own_commit_scalar), sae->prime_len);
wpa_hexdump(MSG_DEBUG, "SAE: commit-scalar", wpa_hexdump(MSG_DEBUG, "SAE: commit-scalar",
@ -271,7 +269,6 @@ static int sae_derive_commit(struct sae_data *sae, struct crypto_ec_point *pwe)
ret = 0; ret = 0;
fail: fail:
crypto_ec_point_deinit(elem, 0); crypto_ec_point_deinit(elem, 0);
crypto_bignum_deinit(order, 0);
crypto_bignum_deinit(bn_mask, 1); crypto_bignum_deinit(bn_mask, 1);
os_memset(mask, 0, sizeof(mask)); os_memset(mask, 0, sizeof(mask));
crypto_bignum_deinit(bn_rand, 1); crypto_bignum_deinit(bn_rand, 1);
@ -378,17 +375,15 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
u8 null_key[SAE_KEYSEED_KEY_LEN], val[SAE_MAX_PRIME_LEN]; u8 null_key[SAE_KEYSEED_KEY_LEN], val[SAE_MAX_PRIME_LEN];
u8 keyseed[SHA256_MAC_LEN]; u8 keyseed[SHA256_MAC_LEN];
u8 keys[SAE_KCK_LEN + SAE_PMK_LEN]; u8 keys[SAE_KCK_LEN + SAE_PMK_LEN];
struct crypto_bignum *order, *own_scalar, *peer_scalar, *tmp; struct crypto_bignum *own_scalar, *peer_scalar, *tmp;
int ret = -1; int ret = -1;
order = crypto_bignum_init_set(group19_order, sizeof(group19_order));
own_scalar = crypto_bignum_init_set(sae->own_commit_scalar, own_scalar = crypto_bignum_init_set(sae->own_commit_scalar,
sae->prime_len); sae->prime_len);
peer_scalar = crypto_bignum_init_set(sae->peer_commit_scalar, peer_scalar = crypto_bignum_init_set(sae->peer_commit_scalar,
sae->prime_len); sae->prime_len);
tmp = crypto_bignum_init(); tmp = crypto_bignum_init();
if (order == NULL || own_scalar == NULL || peer_scalar == NULL || if (own_scalar == NULL || peer_scalar == NULL || tmp == NULL)
tmp == NULL)
goto fail; goto fail;
/* keyseed = H(<0>32, k) /* keyseed = H(<0>32, k)
@ -402,7 +397,7 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
wpa_hexdump_key(MSG_DEBUG, "SAE: keyseed", keyseed, sizeof(keyseed)); wpa_hexdump_key(MSG_DEBUG, "SAE: keyseed", keyseed, sizeof(keyseed));
crypto_bignum_add(own_scalar, peer_scalar, tmp); crypto_bignum_add(own_scalar, peer_scalar, tmp);
crypto_bignum_mod(tmp, order, tmp); crypto_bignum_mod(tmp, crypto_ec_get_order(sae->ec), tmp);
crypto_bignum_to_bin(tmp, val, sizeof(val), sae->prime_len); crypto_bignum_to_bin(tmp, val, sizeof(val), sae->prime_len);
wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN); wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN);
sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK", sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK",
@ -417,7 +412,6 @@ fail:
crypto_bignum_deinit(tmp, 0); crypto_bignum_deinit(tmp, 0);
crypto_bignum_deinit(peer_scalar, 0); crypto_bignum_deinit(peer_scalar, 0);
crypto_bignum_deinit(own_scalar, 0); crypto_bignum_deinit(own_scalar, 0);
crypto_bignum_deinit(order, 0);
return ret; return ret;
} }

View file

@ -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_order - Get order of an EC group
* @e: EC context from crypto_ec_init()
* Returns: Order (bignum) of the group
*/
const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e);
/** /**
* struct crypto_ec_point - Elliptic curve point * struct crypto_ec_point - Elliptic curve point
* *

View file

@ -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 *order;
}; };
struct crypto_ec * crypto_ec_init(int group) struct crypto_ec * crypto_ec_init(int group)
@ -917,7 +918,9 @@ 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);
if (e->group == NULL || e->bnctx == NULL) { e->order = BN_new();
if (e->group == NULL || e->bnctx == NULL || e->order == NULL ||
!EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
crypto_ec_deinit(e); crypto_ec_deinit(e);
e = NULL; e = NULL;
} }
@ -930,6 +933,7 @@ void crypto_ec_deinit(struct crypto_ec *e)
{ {
if (e == NULL) if (e == NULL)
return; return;
BN_free(e->order);
EC_GROUP_free(e->group); EC_GROUP_free(e->group);
BN_CTX_free(e->bnctx); BN_CTX_free(e->bnctx);
os_free(e); os_free(e);
@ -950,6 +954,12 @@ size_t crypto_ec_prime_len(struct crypto_ec *e)
} }
const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
{
return (const struct crypto_bignum *) e->order;
}
void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear) void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
{ {
if (clear) if (clear)