/*
* 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
* @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
* @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
* @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
* @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
}
-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);
}
#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);
}
#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;
}
}
-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;
}
#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;
for (i = 0; i < num_elem; i++)
md4_process(&md, addr[i], len[i]);
md4_done(&md, mac);
+ return 0;
}
#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;
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;
for (i = 0; i < num_elem; i++)
sha1_process(&md, addr[i], len[i]);
sha1_done(&md, mac);
+ return 0;
}
#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;
}
/*
* 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;
}
}
-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;
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;
for (i = 0; i < num_elem; i++)
MD4Update(&ctx, addr[i], len[i]);
MD4Final(mac, &ctx);
+ return 0;
}
* @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;
for (i = 0; i < num_elem; i++)
MD5Update(&ctx, addr[i], len[i]);
MD5Final(mac, &ctx);
+ return 0;
}
* @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];
* 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;
}
_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);
_len[0] = 64;
_addr[1] = mac;
_len[1] = MD5_MAC_LEN;
- md5_vector(2, _addr, _len, mac);
+ return md5_vector(2, _addr, _len, mac);
}
* @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);
}
/*
* 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
#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 */
* @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;
for (i = 0; i < num_elem; i++)
SHA1Update(&ctx, addr[i], len[i]);
SHA1Final(mac, &ctx);
+ return 0;
}
#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;
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;
}
* @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;
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;
}
* @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;
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;
}
len[0] = SHA1_MAC_LEN;
}
+
+ return 0;
}
* @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];
* 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;
}
_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);
_len[0] = 64;
_addr[1] = mac;
_len[1] = SHA1_MAC_LEN;
- sha1_vector(2, _addr, _len, mac);
+ return sha1_vector(2, _addr, _len, mac);
}
* @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);
}
* @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;
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;
}
/*
* 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 */
* @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;
}