]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Check SHA256-PRF operation result
authorJouni Malinen <j@w1.fi>
Sun, 27 Mar 2016 18:43:24 +0000 (21:43 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 27 Mar 2016 18:44:49 +0000 (21:44 +0300)
While this is mostly theoretical, check explicitly that SHA256
operations in sha256_prf*() succeed.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/common/sae.c
src/crypto/sha256-prf.c
src/crypto/sha256.h

index f78437b130b4e530c004cb789649c2f4610b6df6..9f70f036ba7635c9fb6776f74528a13cfdac191f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Simultaneous authentication of equals
- * Copyright (c) 2012-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2012-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -275,8 +275,9 @@ static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed,
 
        /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
        bits = crypto_ec_prime_len_bits(sae->tmp->ec);
-       sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
-                       prime, sae->tmp->prime_len, pwd_value, bits);
+       if (sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
+                           prime, sae->tmp->prime_len, pwd_value, bits) < 0)
+               return -1;
        if (bits % 8)
                buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8);
        wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
@@ -318,9 +319,10 @@ static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed,
        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_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
-                       sae->tmp->dh->prime, sae->tmp->prime_len, pwd_value,
-                       bits);
+       if (sha256_prf_bits(pwd_seed, SHA256_MAC_LEN, "SAE Hunting and Pecking",
+                           sae->tmp->dh->prime, sae->tmp->prime_len, pwd_value,
+                           bits) < 0)
+               return -1;
        wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", pwd_value,
                        sae->tmp->prime_len);
 
@@ -809,8 +811,9 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
        crypto_bignum_mod(tmp, sae->tmp->order, tmp);
        crypto_bignum_to_bin(tmp, val, sizeof(val), sae->tmp->prime_len);
        wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN);
-       sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK",
-                  val, sae->tmp->prime_len, keys, sizeof(keys));
+       if (sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK",
+                      val, sae->tmp->prime_len, keys, sizeof(keys)) < 0)
+               goto fail;
        os_memset(keyseed, 0, sizeof(keyseed));
        os_memcpy(sae->tmp->kck, keys, SAE_KCK_LEN);
        os_memcpy(sae->pmk, keys + SAE_KCK_LEN, SAE_PMK_LEN);
index 79791c06cf0bb1e63a06d9cdd6f2184adbdcabaf..722cad6bdeb4d1e25837a676ed681422f704b0a0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * SHA256-based PRF (IEEE 802.11r)
- * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
  * @data_len: Length of the data
  * @buf: Buffer for the generated pseudo-random key
  * @buf_len: Number of bytes of key to generate
+ * Returns: 0 on success, -1 on failure
  *
  * This function is used to derive new, cryptographically separate keys from a
  * given key.
  */
-void sha256_prf(const u8 *key, size_t key_len, const char *label,
+int sha256_prf(const u8 *key, size_t key_len, const char *label,
                const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
 {
-       sha256_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8);
+       return sha256_prf_bits(key, key_len, label, data, data_len, buf,
+                              buf_len * 8);
 }
 
 
@@ -42,15 +44,16 @@ void sha256_prf(const u8 *key, size_t key_len, const char *label,
  * @data_len: Length of the data
  * @buf: Buffer for the generated pseudo-random key
  * @buf_len: Number of bits of key to generate
+ * Returns: 0 on success, -1 on failure
  *
  * This function is used to derive new, cryptographically separate keys from a
  * given key. If the requested buf_len is not divisible by eight, the least
  * significant 1-7 bits of the last octet in the output are not part of the
  * requested output.
  */
-void sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
-                    const u8 *data, size_t data_len, u8 *buf,
-                    size_t buf_len_bits)
+int sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
+                   const u8 *data, size_t data_len, u8 *buf,
+                   size_t buf_len_bits)
 {
        u16 counter = 1;
        size_t pos, plen;
@@ -75,11 +78,14 @@ void sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
                plen = buf_len - pos;
                WPA_PUT_LE16(counter_le, counter);
                if (plen >= SHA256_MAC_LEN) {
-                       hmac_sha256_vector(key, key_len, 4, addr, len,
-                                          &buf[pos]);
+                       if (hmac_sha256_vector(key, key_len, 4, addr, len,
+                                              &buf[pos]) < 0)
+                               return -1;
                        pos += SHA256_MAC_LEN;
                } else {
-                       hmac_sha256_vector(key, key_len, 4, addr, len, hash);
+                       if (hmac_sha256_vector(key, key_len, 4, addr, len,
+                                              hash) < 0)
+                               return -1;
                        os_memcpy(&buf[pos], hash, plen);
                        pos += plen;
                        break;
@@ -97,4 +103,6 @@ void sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
        }
 
        os_memset(hash, 0, sizeof(hash));
+
+       return 0;
 }
index b15f51158f3262e6fac9e564f3ac05869ae06d6e..5219022edd7d636f4ff6d5abb603585bc6177a2a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * SHA256 hash implementation and interface functions
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -15,11 +15,11 @@ int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
                       const u8 *addr[], const size_t *len, u8 *mac);
 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
                size_t data_len, u8 *mac);
-void sha256_prf(const u8 *key, size_t key_len, const char *label,
-             const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
-void sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
-                    const u8 *data, size_t data_len, u8 *buf,
-                    size_t buf_len_bits);
+int sha256_prf(const u8 *key, size_t key_len, const char *label,
+              const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
+int sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
+                   const u8 *data, size_t data_len, u8 *buf,
+                   size_t buf_len_bits);
 void tls_prf_sha256(const u8 *secret, size_t secret_len,
                    const char *label, const u8 *seed, size_t seed_len,
                    u8 *out, size_t outlen);