Make hash functions return error value
authorJouni Malinen <j@w1.fi>
Sun, 16 Aug 2009 11:06:00 +0000 (14:06 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 16 Aug 2009 11:06:00 +0000 (14:06 +0300)
Some crypto libraries can return in these functions (e.g., if a specific
hash function is disabled), so we better provide the caller a chance to
check whether the call failed. The return values are not yet used
anywhere, but they will be needed for future changes.

16 files changed:
src/crypto/crypto.h
src/crypto/crypto_cryptoapi.c
src/crypto/crypto_gnutls.c
src/crypto/crypto_libtomcrypt.c
src/crypto/crypto_none.c
src/crypto/crypto_openssl.c
src/crypto/md4-internal.c
src/crypto/md5-internal.c
src/crypto/md5.c
src/crypto/md5.h
src/crypto/sha1-internal.c
src/crypto/sha1-pbkdf2.c
src/crypto/sha1-tprf.c
src/crypto/sha1.c
src/crypto/sha1.h
src/crypto/sha256-internal.c

index a5129bb..e2d2112 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant / wrapper functions for crypto libraries
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2009, 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
@@ -33,8 +33,9 @@
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash
+ * Returns: 0 on success, -1 on failure
  */
-void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
 
 /**
  * md5_vector - MD5 hash for data vector
@@ -42,8 +43,9 @@ void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash
+ * Returns: 0 on success, -1 on failure
  */
-void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
 
 /**
  * sha1_vector - SHA-1 hash for data vector
@@ -51,9 +53,10 @@ void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash
+ * Returns: 0 on success, -1 on failure
  */
-void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
-                u8 *mac);
+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
+               u8 *mac);
 
 /**
  * fips186_2-prf - NIST FIPS Publication 186-2 change notice 1 PRF
@@ -76,9 +79,10 @@ int __must_check fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x,
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash
+ * Returns: 0 on success, -1 on failure
  */
-void sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
-                  u8 *mac);
+int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
+                 u8 *mac);
 
 /**
  * des_encrypt - Encrypt one block with DES
index bb05730..2746b1d 100644 (file)
@@ -167,9 +167,9 @@ int cryptoapi_hash_vector(ALG_ID alg, size_t hash_len, size_t num_elem,
 }
 
 
-void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
-       cryptoapi_hash_vector(CALG_MD4, 16, num_elem, addr, len, mac);
+       return cryptoapi_hash_vector(CALG_MD4, 16, num_elem, addr, len, mac);
 }
 
 
@@ -239,15 +239,15 @@ void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
 
 
 #ifdef EAP_TLS_FUNCS
-void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
-       cryptoapi_hash_vector(CALG_MD5, 16, num_elem, addr, len, mac);
+       return cryptoapi_hash_vector(CALG_MD5, 16, num_elem, addr, len, mac);
 }
 
 
-void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
-       cryptoapi_hash_vector(CALG_SHA, 20, num_elem, addr, len, mac);
+       return cryptoapi_hash_vector(CALG_SHA, 20, num_elem, addr, len, mac);
 }
 
 
index 1d658bd..0998cca 100644 (file)
 #include "common.h"
 #include "crypto.h"
 
-void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        gcry_md_hd_t hd;
        unsigned char *p;
        size_t i;
 
        if (gcry_md_open(&hd, GCRY_MD_MD4, 0) != GPG_ERR_NO_ERROR)
-               return;
+               return -1;
        for (i = 0; i < num_elem; i++)
                gcry_md_write(hd, addr[i], len[i]);
        p = gcry_md_read(hd, GCRY_MD_MD4);
        if (p)
                memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD4));
        gcry_md_close(hd);
+       return 0;
 }
 
 
@@ -57,37 +58,39 @@ void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
 }
 
 
-void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        gcry_md_hd_t hd;
        unsigned char *p;
        size_t i;
 
        if (gcry_md_open(&hd, GCRY_MD_MD5, 0) != GPG_ERR_NO_ERROR)
-               return;
+               return -1;
        for (i = 0; i < num_elem; i++)
                gcry_md_write(hd, addr[i], len[i]);
        p = gcry_md_read(hd, GCRY_MD_MD5);
        if (p)
                memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD5));
        gcry_md_close(hd);
+       return 0;
 }
 
 
-void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        gcry_md_hd_t hd;
        unsigned char *p;
        size_t i;
 
        if (gcry_md_open(&hd, GCRY_MD_SHA1, 0) != GPG_ERR_NO_ERROR)
-               return;
+               return -1;
        for (i = 0; i < num_elem; i++)
                gcry_md_write(hd, addr[i], len[i]);
        p = gcry_md_read(hd, GCRY_MD_SHA1);
        if (p)
                memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_SHA1));
        gcry_md_close(hd);
+       return 0;
 }
 
 
index 1c97443..2ccf46d 100644 (file)
@@ -29,7 +29,7 @@
 #endif
 
 
-void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        hash_state md;
        size_t i;
@@ -38,6 +38,7 @@ void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
        for (i = 0; i < num_elem; i++)
                md4_process(&md, addr[i], len[i]);
        md4_done(&md, mac);
+       return 0;
 }
 
 
@@ -63,7 +64,7 @@ void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
 
 
 #ifdef EAP_TLS_FUNCS
-void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        hash_state md;
        size_t i;
@@ -72,10 +73,11 @@ void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
        for (i = 0; i < num_elem; i++)
                md5_process(&md, addr[i], len[i]);
        md5_done(&md, mac);
+       return 0;
 }
 
 
-void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        hash_state md;
        size_t i;
@@ -84,6 +86,7 @@ void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
        for (i = 0; i < num_elem; i++)
                sha1_process(&md, addr[i], len[i]);
        sha1_done(&md, mac);
+       return 0;
 }
 
 
index f18c2a8..9f43775 100644 (file)
@@ -18,8 +18,9 @@
 #include "crypto.h"
 
 
-void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
+       return 0;
 }
 
 
index 09f94a0..7cb9424 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant / wrapper functions for libcrypto
- * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2009, 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
 #endif /* openssl < 0.9.7 */
 
 
-void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        MD4_CTX ctx;
        size_t i;
 
-       MD4_Init(&ctx);
+       if (!MD4_Init(&ctx))
+               return -1;
        for (i = 0; i < num_elem; i++)
-               MD4_Update(&ctx, addr[i], len[i]);
-       MD4_Final(mac, &ctx);
+               if (!MD4_Update(&ctx, addr[i], len[i]))
+                       return -1;
+       if (!MD4_Final(mac, &ctx))
+               return -1;
+       return 0;
 }
 
 
@@ -67,29 +71,38 @@ void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
 }
 
 
-void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        MD5_CTX ctx;
        size_t i;
 
-       MD5_Init(&ctx);
+       if (!MD5_Init(&ctx))
+               return -1;
        for (i = 0; i < num_elem; i++)
-               MD5_Update(&ctx, addr[i], len[i]);
-       MD5_Final(mac, &ctx);
+               if (!MD5_Update(&ctx, addr[i], len[i]))
+                       return -1;
+       if (!MD5_Final(mac, &ctx))
+               return -1;
+       return 0;
 }
 
 
-void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        SHA_CTX ctx;
        size_t i;
 
-       SHA1_Init(&ctx);
+       if (!SHA1_Init(&ctx))
+               return -1;
        for (i = 0; i < num_elem; i++)
-               SHA1_Update(&ctx, addr[i], len[i]);
-       SHA1_Final(mac, &ctx);
+               if (!SHA1_Update(&ctx, addr[i], len[i]))
+                       return -1;
+       if (!SHA1_Final(mac, &ctx))
+               return -1;
+       return 0;
 }
 
+
 void * aes_encrypt_init(const u8 *key, size_t len)
 {
        AES_KEY *ak;
index 872872d..d9f499f 100644 (file)
@@ -32,7 +32,7 @@ static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len);
 static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx);
 
 
-void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        MD4_CTX ctx;
        size_t i;
@@ -41,6 +41,7 @@ void md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
        for (i = 0; i < num_elem; i++)
                MD4Update(&ctx, addr[i], len[i]);
        MD4Final(mac, &ctx);
+       return 0;
 }
 
 
index 411757b..d58bbde 100644 (file)
@@ -37,8 +37,9 @@ typedef struct MD5Context MD5_CTX;
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash
+ * Returns: 0 on success, -1 of failure
  */
-void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        MD5_CTX ctx;
        size_t i;
@@ -47,6 +48,7 @@ void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
        for (i = 0; i < num_elem; i++)
                MD5Update(&ctx, addr[i], len[i]);
        MD5Final(mac, &ctx);
+       return 0;
 }
 
 
index 12f2d83..7f14e9b 100644 (file)
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash (16 bytes)
+ * Returns: 0 on success, -1 on failure
  */
-void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
-                    const u8 *addr[], const size_t *len, u8 *mac)
+int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
+                   const u8 *addr[], const size_t *len, u8 *mac)
 {
        u8 k_pad[64]; /* padding - key XORd with ipad/opad */
        u8 tk[16];
@@ -41,12 +42,13 @@ void hmac_md5_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 = MD5(key) */
         if (key_len > 64) {
-               md5_vector(1, &key, &key_len, tk);
+               if (md5_vector(1, &key, &key_len, tk))
+                       return -1;
                key = tk;
                key_len = 16;
         }
@@ -75,7 +77,8 @@ void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
                _addr[i + 1] = addr[i];
                _len[i + 1] = len[i];
        }
-       md5_vector(1 + num_elem, _addr, _len, mac);
+       if (md5_vector(1 + num_elem, _addr, _len, mac))
+               return -1;
 
        os_memset(k_pad, 0, sizeof(k_pad));
        os_memcpy(k_pad, key, key_len);
@@ -88,7 +91,7 @@ void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
        _len[0] = 64;
        _addr[1] = mac;
        _len[1] = MD5_MAC_LEN;
-       md5_vector(2, _addr, _len, mac);
+       return md5_vector(2, _addr, _len, mac);
 }
 
 
@@ -99,9 +102,10 @@ void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
  * @data: Pointers to the data area
  * @data_len: Length of the data area
  * @mac: Buffer for the hash (16 bytes)
+ * Returns: 0 on success, -1 on failure
  */
-void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
              u8 *mac)
 {
-       hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
+       return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
 }
index 480a2f4..40ab630 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * MD5 hash implementation and interface functions
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2009, 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
@@ -17,8 +17,9 @@
 
 #define MD5_MAC_LEN 16
 
-void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
-                    const u8 *addr[], const size_t *len, u8 *mac);
-void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
-             u8 *mac);
+int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
+                   const u8 *addr[], const size_t *len, u8 *mac);
+int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+            u8 *mac);
+
 #endif /* MD5_H */
index 1f66e92..dfe8940 100644 (file)
@@ -37,9 +37,9 @@ void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash
+ * Returns: 0 on success, -1 of failure
  */
-void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
-                u8 *mac)
+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
        SHA1_CTX ctx;
        size_t i;
@@ -48,6 +48,7 @@ void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
        for (i = 0; i < num_elem; i++)
                SHA1Update(&ctx, addr[i], len[i]);
        SHA1Final(mac, &ctx);
+       return 0;
 }
 
 
index a3f2ea9..11323de 100644 (file)
@@ -19,9 +19,9 @@
 #include "md5.h"
 #include "crypto.h"
 
-static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
-                         size_t ssid_len, int iterations, unsigned int count,
-                         u8 *digest)
+static int pbkdf2_sha1_f(const char *passphrase, const char *ssid,
+                        size_t ssid_len, int iterations, unsigned int count,
+                        u8 *digest)
 {
        unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
        int i, j;
@@ -45,16 +45,21 @@ static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
        count_buf[1] = (count >> 16) & 0xff;
        count_buf[2] = (count >> 8) & 0xff;
        count_buf[3] = count & 0xff;
-       hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp);
+       if (hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len,
+                            tmp))
+               return -1;
        os_memcpy(digest, tmp, SHA1_MAC_LEN);
 
        for (i = 1; i < iterations; i++) {
-               hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
-                         tmp2);
+               if (hmac_sha1((u8 *) passphrase, passphrase_len, tmp,
+                             SHA1_MAC_LEN, tmp2))
+                       return -1;
                os_memcpy(tmp, tmp2, SHA1_MAC_LEN);
                for (j = 0; j < SHA1_MAC_LEN; j++)
                        digest[j] ^= tmp2[j];
        }
+
+       return 0;
 }
 
 
@@ -66,13 +71,14 @@ static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
  * @iterations: Number of iterations to run
  * @buf: Buffer for the generated key
  * @buflen: Length of the buffer in bytes
+ * Returns: 0 on success, -1 of failure
  *
  * This function is used to derive PSK for WPA-PSK. For this protocol,
  * iterations is set to 4096 and buflen to 32. This function is described in
  * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0.
  */
-void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
-                int iterations, u8 *buf, size_t buflen)
+int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
+               int iterations, u8 *buf, size_t buflen)
 {
        unsigned int count = 0;
        unsigned char *pos = buf;
@@ -81,11 +87,14 @@ void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
 
        while (left > 0) {
                count++;
-               pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
-                             digest);
+               if (pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations,
+                                 count, digest))
+                       return -1;
                plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
                os_memcpy(pos, digest, plen);
                pos += plen;
                left -= plen;
        }
+
+       return 0;
 }
index cb05440..4a80e96 100644 (file)
  * @seed_len: Length of the seed
  * @buf: Buffer for the generated pseudo-random key
  * @buf_len: Number of bytes of key to generate
+ * Returns: 0 on success, -1 of failure
  *
  * This function is used to derive new, cryptographically separate keys from a
  * given key for EAP-FAST. T-PRF is defined in RFC 4851, Section 5.5.
  */
-void sha1_t_prf(const u8 *key, size_t key_len, const char *label,
-               const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
+int sha1_t_prf(const u8 *key, size_t key_len, const char *label,
+              const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
 {
        unsigned char counter = 0;
        size_t pos, plen;
@@ -59,7 +60,8 @@ void sha1_t_prf(const u8 *key, size_t key_len, const char *label,
        while (pos < buf_len) {
                counter++;
                plen = buf_len - pos;
-               hmac_sha1_vector(key, key_len, 5, addr, len, hash);
+               if (hmac_sha1_vector(key, key_len, 5, addr, len, hash))
+                       return -1;
                if (plen >= SHA1_MAC_LEN) {
                        os_memcpy(&buf[pos], hash, SHA1_MAC_LEN);
                        pos += SHA1_MAC_LEN;
@@ -69,4 +71,6 @@ void sha1_t_prf(const u8 *key, size_t key_len, const char *label,
                }
                len[0] = SHA1_MAC_LEN;
        }
+
+       return 0;
 }
index 83d619e..fe00bdb 100644 (file)
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash (20 bytes)
+ * Returns: 0 on success, -1 on failure
  */
-void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
-                     const u8 *addr[], const size_t *len, u8 *mac)
+int hmac_sha1_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[20];
@@ -41,12 +42,13 @@ void hmac_sha1_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 = SHA1(key) */
         if (key_len > 64) {
-               sha1_vector(1, &key, &key_len, tk);
+               if (sha1_vector(1, &key, &key_len, tk))
+                       return -1;
                key = tk;
                key_len = 20;
         }
@@ -74,7 +76,8 @@ void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
                _addr[i + 1] = addr[i];
                _len[i + 1] = len[i];
        }
-       sha1_vector(1 + num_elem, _addr, _len, mac);
+       if (sha1_vector(1 + num_elem, _addr, _len, mac))
+               return -1;
 
        os_memset(k_pad, 0, sizeof(k_pad));
        os_memcpy(k_pad, key, key_len);
@@ -87,7 +90,7 @@ void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
        _len[0] = 64;
        _addr[1] = mac;
        _len[1] = SHA1_MAC_LEN;
-       sha1_vector(2, _addr, _len, mac);
+       return sha1_vector(2, _addr, _len, mac);
 }
 
 
@@ -98,11 +101,12 @@ void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
  * @data: Pointers to the data area
  * @data_len: Length of the data area
  * @mac: Buffer for the hash (20 bytes)
+ * Returns: 0 on success, -1 of failure
  */
-void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
               u8 *mac)
 {
-       hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
+       return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
 }
 
 
@@ -115,12 +119,13 @@ void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
  * @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 of failure
  *
  * This function is used to derive new, cryptographically separate keys from a
  * given key (e.g., PMK in IEEE 802.11i).
  */
-void sha1_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 sha1_prf(const u8 *key, size_t key_len, const char *label,
+            const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
 {
        u8 counter = 0;
        size_t pos, plen;
@@ -140,15 +145,19 @@ void sha1_prf(const u8 *key, size_t key_len, const char *label,
        while (pos < buf_len) {
                plen = buf_len - pos;
                if (plen >= SHA1_MAC_LEN) {
-                       hmac_sha1_vector(key, key_len, 3, addr, len,
-                                        &buf[pos]);
+                       if (hmac_sha1_vector(key, key_len, 3, addr, len,
+                                            &buf[pos]))
+                               return -1;
                        pos += SHA1_MAC_LEN;
                } else {
-                       hmac_sha1_vector(key, key_len, 3, addr, len,
-                                        hash);
+                       if (hmac_sha1_vector(key, key_len, 3, addr, len,
+                                            hash))
+                               return -1;
                        os_memcpy(&buf[pos], hash, plen);
                        break;
                }
                counter++;
        }
+
+       return 0;
 }
index b1dc647..c1a6233 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * SHA1 hash implementation and interface functions
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2009, 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
 
 #define SHA1_MAC_LEN 20
 
-void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
-                     const u8 *addr[], const size_t *len, u8 *mac);
-void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
+                    const u8 *addr[], const size_t *len, u8 *mac);
+int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
               u8 *mac);
-void sha1_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 sha1_t_prf(const u8 *key, size_t key_len, const char *label,
-               const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len);
+int sha1_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 sha1_t_prf(const u8 *key, size_t key_len, const char *label,
+              const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len);
 int __must_check tls_prf(const u8 *secret, size_t secret_len,
                         const char *label, const u8 *seed, size_t seed_len,
                         u8 *out, size_t outlen);
-void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
-                int iterations, u8 *buf, size_t buflen);
+int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
+               int iterations, u8 *buf, size_t buflen);
 #endif /* SHA1_H */
index 3b33ace..b061373 100644 (file)
@@ -36,17 +36,21 @@ static int sha256_done(struct sha256_state *md, unsigned char *out);
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
  * @mac: Buffer for the hash
+ * Returns: 0 on success, -1 of failure
  */
-void sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
-                u8 *mac)
+int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
+                 u8 *mac)
 {
        struct sha256_state ctx;
        size_t i;
 
        sha256_init(&ctx);
        for (i = 0; i < num_elem; i++)
-               sha256_process(&ctx, addr[i], len[i]);
-       sha256_done(&ctx, mac);
+               if (sha256_process(&ctx, addr[i], len[i]))
+                       return -1;
+       if (sha256_done(&ctx, mac))
+               return -1;
+       return 0;
 }