Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / src / crypto / sha256.c
index 7f320f9..b55e976 100644 (file)
@@ -1,15 +1,9 @@
 /*
  * SHA-256 hash implementation and interface functions
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
  */
 
 #include "includes.h"
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash (32 bytes)
+ * Returns: 0 on success, -1 on failure
  */
-void 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_vector(const u8 *key, size_t key_len, size_t num_elem,
+                      const u8 *addr[], const size_t *len, u8 *mac)
 {
        unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
        unsigned char tk[32];
@@ -41,12 +36,13 @@ void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
                 * Fixed limit on the number of fragments to avoid having to
                 * allocate memory (which could fail).
                 */
-               return;
+               return -1;
        }
 
         /* if key is longer than 64 bytes reset it to key = SHA256(key) */
         if (key_len > 64) {
-               sha256_vector(1, &key, &key_len, tk);
+               if (sha256_vector(1, &key, &key_len, tk) < 0)
+                       return -1;
                key = tk;
                key_len = 32;
         }
@@ -74,7 +70,8 @@ void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
                _addr[i + 1] = addr[i];
                _len[i + 1] = len[i];
        }
-       sha256_vector(1 + num_elem, _addr, _len, mac);
+       if (sha256_vector(1 + num_elem, _addr, _len, mac) < 0)
+               return -1;
 
        os_memset(k_pad, 0, sizeof(k_pad));
        os_memcpy(k_pad, key, key_len);
@@ -87,7 +84,7 @@ void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
        _len[0] = 64;
        _addr[1] = mac;
        _len[1] = SHA256_MAC_LEN;
-       sha256_vector(2, _addr, _len, mac);
+       return sha256_vector(2, _addr, _len, mac);
 }
 
 
@@ -97,61 +94,11 @@ void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
  * @key_len: Length of the key in bytes
  * @data: Pointers to the data area
  * @data_len: Length of the data area
- * @mac: Buffer for the hash (20 bytes)
- */
-void hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
-                size_t data_len, u8 *mac)
-{
-       hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
-}
-
-
-/**
- * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)
- * @key: Key for PRF
- * @key_len: Length of the key in bytes
- * @label: A unique label for each purpose of the PRF
- * @data: Extra data to bind into the key
- * @data_len: Length of the data
- * @buf: Buffer for the generated pseudo-random key
- * @buf_len: Number of bytes of key to generate
- *
- * This function is used to derive new, cryptographically separate keys from a
- * given key.
+ * @mac: Buffer for the hash (32 bytes)
+ * Returns: 0 on success, -1 on failure
  */
-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)
+int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
+               size_t data_len, u8 *mac)
 {
-       u16 counter = 1;
-       size_t pos, plen;
-       u8 hash[SHA256_MAC_LEN];
-       const u8 *addr[4];
-       size_t len[4];
-       u8 counter_le[2], length_le[2];
-
-       addr[0] = counter_le;
-       len[0] = 2;
-       addr[1] = (u8 *) label;
-       len[1] = os_strlen(label);
-       addr[2] = data;
-       len[2] = data_len;
-       addr[3] = length_le;
-       len[3] = sizeof(length_le);
-
-       WPA_PUT_LE16(length_le, buf_len * 8);
-       pos = 0;
-       while (pos < buf_len) {
-               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]);
-                       pos += SHA256_MAC_LEN;
-               } else {
-                       hmac_sha256_vector(key, key_len, 4, addr, len, hash);
-                       os_memcpy(&buf[pos], hash, plen);
-                       break;
-               }
-               counter++;
-       }
+       return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
 }