]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Use EC group context to get the group prime
authorJouni Malinen <j@w1.fi>
Tue, 1 Jan 2013 10:27:00 +0000 (12:27 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 12 Jan 2013 15:51:53 +0000 (17:51 +0200)
Do not use the hardcoded group19_prime buffer for this to allow group
negotiation.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/common/sae.c
src/crypto/crypto.h
src/crypto/crypto_openssl.c

index efa85f067207b388226ec8bb812681e169ae5798..0bd89547145cefe4f4c421070760948474d764a8 100644 (file)
 #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)
 {
        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,
                             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;
        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);
 
        /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
        sha256_prf(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
-                  group19_prime, sizeof(group19_prime),
-                  pwd_value, sizeof(pwd_value));
+                  prime, sae->prime_len, pwd_value, sizeof(pwd_value));
        wpa_hexdump_key(MSG_DEBUG, "SAE: 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;
 
        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)
 {
-       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),
-                                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;
 
        /* 0 < scalar < r */
@@ -322,10 +319,9 @@ static int sae_check_peer_commit(struct sae_data *sae)
        }
 
        /* element x and y coordinates < p */
-       if (os_memcmp(sae->peer_commit_element, group19_prime,
-                     sizeof(group19_prime)) >= 0 ||
-           os_memcmp(sae->peer_commit_element + sae->prime_len, group19_prime,
-                     sizeof(group19_prime)) >= 0) {
+       if (os_memcmp(sae->peer_commit_element, prime, sae->prime_len) >= 0 ||
+           os_memcmp(sae->peer_commit_element + sae->prime_len, prime,
+                     sae->prime_len) >= 0) {
                wpa_printf(MSG_DEBUG, "SAE: Invalid coordinates in peer "
                           "element");
                return -1;
index 63c2fa1389a985f28783f6f7a907fbb88cc69bfc..d33ccb196c14ba52ac08ddcc05c4728b73c66242 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * WPA Supplicant / wrapper functions for crypto libraries
- * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
+ * Wrapper functions for crypto libraries
+ * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * 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);
 
+/**
+ * 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
  * @e: EC context from crypto_ec_init()
index c6b5d933afcb7786b0c7653c637e7760edc2cb8a..7f64ac149eb938c6d9970f7f6bd69a8cb6592067 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * WPA Supplicant / wrapper functions for libcrypto
- * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
+ * Wrapper functions for OpenSSL libcrypto
+ * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -901,6 +901,7 @@ struct crypto_ec {
        EC_GROUP *group;
        BN_CTX *bnctx;
        size_t prime_len;
+       BIGNUM *prime;
        BIGNUM *order;
 };
 
@@ -918,8 +919,11 @@ struct crypto_ec * crypto_ec_init(int group)
        e->prime_len = 32;
        e->bnctx = BN_CTX_new();
        e->group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+       e->prime = 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)) {
                crypto_ec_deinit(e);
                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)
 {
        return (const struct crypto_bignum *) e->order;