Browse Source

Make hash functions return error value

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.
Jouni Malinen 15 years ago
parent
commit
0a5d68aba5

+ 11 - 7
src/crypto/crypto.h

@@ -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

+ 6 - 6
src/crypto/crypto_cryptoapi.c

@@ -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);
 }
 
 

+ 9 - 6
src/crypto/crypto_gnutls.c

@@ -18,20 +18,21 @@
 #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;
 }
 
 

+ 6 - 3
src/crypto/crypto_libtomcrypt.c

@@ -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;
 }
 
 

+ 2 - 1
src/crypto/crypto_none.c

@@ -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;
 }
 
 

+ 26 - 13
src/crypto/crypto_openssl.c

@@ -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
@@ -34,15 +34,19 @@
 #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;

+ 2 - 1
src/crypto/md4-internal.c

@@ -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;
 }
 
 

+ 3 - 1
src/crypto/md5-internal.c

@@ -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;
 }
 
 

+ 12 - 8
src/crypto/md5.c

@@ -27,9 +27,10 @@
  * @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);
 }

+ 6 - 5
src/crypto/md5.h

@@ -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 */

+ 3 - 2
src/crypto/sha1-internal.c

@@ -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;
 }
 
 

+ 19 - 10
src/crypto/sha1-pbkdf2.c

@@ -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;
 }

+ 7 - 3
src/crypto/sha1-tprf.c

@@ -27,12 +27,13 @@
  * @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;
 }

+ 23 - 14
src/crypto/sha1.c

@@ -27,9 +27,10 @@
  * @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;
 }

+ 10 - 10
src/crypto/sha1.h

@@ -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
@@ -17,17 +17,17 @@
 
 #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 */

+ 8 - 4
src/crypto/sha256-internal.c

@@ -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;
 }