From bf14657b9ffd8f46a46879708619b91a160f9967 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 1 Jan 2013 13:07:56 +0200 Subject: [PATCH] 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 --- src/common/sae.h | 2 +- src/crypto/crypto_openssl.c | 34 +++++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/common/sae.h b/src/common/sae.h index e8e65b7ca..0a9881b93 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 7f64ac149..a2b5c5f0e 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);