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.
This commit is contained in:
Jouni Malinen 2009-08-16 14:06:00 +03:00
parent e1ffdfc18b
commit 0a5d68aba5
16 changed files with 153 additions and 94 deletions

View 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

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

View file

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

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

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

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

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

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

View file

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

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

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

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

View file

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

View file

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

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

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