aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2013-01-01 11:07:56 (GMT)
committerJouni Malinen <j@w1.fi>2013-01-12 15:51:53 (GMT)
commitbf14657b9ffd8f46a46879708619b91a160f9967 (patch)
tree6feab15c3c9a030516b18c0ee5a8922f8656a57b
parentcbf9f4c642fae8aeed44b64e25ebaf3f37f97e00 (diff)
downloadhostap-bf14657b9ffd8f46a46879708619b91a160f9967.zip
hostap-bf14657b9ffd8f46a46879708619b91a160f9967.tar.gz
hostap-bf14657b9ffd8f46a46879708619b91a160f9967.tar.bz2
SAE: Add support for additional ECC groups
In addition to the mandatory group 19 (256-bit random ECP group) add support for groups 20 (384-bit), 25 (192-bit), and 26 (224-bit). Signed-hostap: Jouni Malinen <j@w1.fi>
-rw-r--r--src/common/sae.h2
-rw-r--r--src/crypto/crypto_openssl.c34
2 files changed, 26 insertions, 10 deletions
diff --git a/src/common/sae.h b/src/common/sae.h
index e8e65b7..0a9881b 100644
--- a/src/common/sae.h
+++ b/src/common/sae.h
@@ -13,7 +13,7 @@
#define SAE_PMK_LEN 32
#define SAE_PMKID_LEN 16
#define SAE_KEYSEED_KEY_LEN 32
-#define SAE_MAX_PRIME_LEN 32
+#define SAE_MAX_PRIME_LEN 48
#define SAE_COMMIT_MAX_LEN (2 + 3 * SAE_MAX_PRIME_LEN)
#define SAE_CONFIRM_MAX_LEN (2 + SAE_MAX_PRIME_LEN)
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 7f64ac1..a2b5c5f 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -900,7 +900,6 @@ int crypto_bignum_mod(const struct crypto_bignum *a,
struct crypto_ec {
EC_GROUP *group;
BN_CTX *bnctx;
- size_t prime_len;
BIGNUM *prime;
BIGNUM *order;
};
@@ -908,17 +907,32 @@ struct crypto_ec {
struct crypto_ec * crypto_ec_init(int group)
{
struct crypto_ec *e;
+ int nid;
- if (group != 19)
+ /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
+ switch (group) {
+ case 19:
+ nid = NID_X9_62_prime256v1;
+ break;
+ case 20:
+ nid = NID_secp384r1;
+ break;
+ case 25:
+ nid = NID_X9_62_prime192v1;
+ break;
+ case 26:
+ nid = NID_secp224r1;
+ break;
+ default:
return NULL;
+ }
e = os_zalloc(sizeof(*e));
if (e == NULL)
return NULL;
- e->prime_len = 32;
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);
e->prime = BN_new();
e->order = BN_new();
if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
@@ -954,7 +968,7 @@ struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
size_t crypto_ec_prime_len(struct crypto_ec *e)
{
- return e->prime_len;
+ return BN_num_bytes(e->prime);
}
@@ -984,6 +998,7 @@ int crypto_ec_point_to_bin(struct crypto_ec *e,
{
BIGNUM *x_bn, *y_bn;
int ret = -1;
+ int len = BN_num_bytes(e->prime);
x_bn = BN_new();
y_bn = BN_new();
@@ -993,11 +1008,11 @@ int crypto_ec_point_to_bin(struct crypto_ec *e,
x_bn, y_bn, e->bnctx)) {
if (x) {
crypto_bignum_to_bin((struct crypto_bignum *) x_bn,
- x, e->prime_len, e->prime_len);
+ x, len, len);
}
if (y) {
crypto_bignum_to_bin((struct crypto_bignum *) y_bn,
- y, e->prime_len, e->prime_len);
+ y, len, len);
}
ret = 0;
}
@@ -1013,9 +1028,10 @@ struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
{
BIGNUM *x, *y;
EC_POINT *elem;
+ int len = BN_num_bytes(e->prime);
- x = BN_bin2bn(val, e->prime_len, NULL);
- y = BN_bin2bn(val + e->prime_len, e->prime_len, NULL);
+ x = BN_bin2bn(val, len, NULL);
+ y = BN_bin2bn(val + len, len, NULL);
elem = EC_POINT_new(e->group);
if (x == NULL || y == NULL || elem == NULL) {
BN_free(x);