aboutsummaryrefslogtreecommitdiff
path: root/contrib/wpa_supplicant/md5.c
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2006-03-07 05:26:33 +0000
committerSam Leffler <sam@FreeBSD.org>2006-03-07 05:26:33 +0000
commit4e0922e888407f6dd91546a040e26125317fcfd8 (patch)
tree0c0ff34569d807e7bceb062a6210ce68490a8764 /contrib/wpa_supplicant/md5.c
parente00d94fa7cb16ece7a61c444a75fef8ff3926446 (diff)
downloadsrc-4e0922e888407f6dd91546a040e26125317fcfd8.tar.gz
src-4e0922e888407f6dd91546a040e26125317fcfd8.zip
Import of WPA supplicant 0.4.8
Notes
Notes: svn path=/vendor/wpa_supplicant/dist/; revision=156369
Diffstat (limited to 'contrib/wpa_supplicant/md5.c')
-rw-r--r--contrib/wpa_supplicant/md5.c146
1 files changed, 93 insertions, 53 deletions
diff --git a/contrib/wpa_supplicant/md5.c b/contrib/wpa_supplicant/md5.c
index 1564e8f64797..82388e086766 100644
--- a/contrib/wpa_supplicant/md5.c
+++ b/contrib/wpa_supplicant/md5.c
@@ -1,6 +1,6 @@
/*
* MD5 hash implementation and interface functions
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.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
@@ -18,36 +18,38 @@
#include "common.h"
#include "md5.h"
+#include "crypto.h"
-void md5_mac(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
- u8 *mac)
-{
- MD5_CTX context;
- MD5Init(&context);
- MD5Update(&context, key, key_len);
- MD5Update(&context, data, data_len);
- MD5Update(&context, key, key_len);
- MD5Final(mac, &context);
-}
-
-
-/* HMAC code is based on RFC 2104 */
+/**
+ * hmac_md5_vector - HMAC-MD5 over data vector (RFC 2104)
+ * @key: Key for HMAC operations
+ * @key_len: Length of the key in bytes
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
+ * @mac: Buffer for the hash (16 bytes)
+ */
void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
- MD5_CTX context;
- u8 k_ipad[65]; /* inner padding - key XORd with ipad */
- u8 k_opad[65]; /* outer padding - key XORd with opad */
+ u8 k_pad[64]; /* padding - key XORd with ipad/opad */
u8 tk[16];
int i;
+ const u8 *_addr[6];
+ size_t _len[6];
+
+ if (num_elem > 5) {
+ /*
+ * Fixed limit on the number of fragments to avoid having to
+ * allocate memory (which could fail).
+ */
+ return;
+ }
/* if key is longer than 64 bytes reset it to key = MD5(key) */
if (key_len > 64) {
- MD5Init(&context);
- MD5Update(&context, key, key_len);
- MD5Final(tk, &context);
-
+ md5_vector(1, &key, &key_len, tk);
key = tk;
key_len = 16;
}
@@ -61,35 +63,46 @@ void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
* opad is the byte 0x5c repeated 64 times
* and text is the data being protected */
- /* start out by storing key in pads */
- memset(k_ipad, 0, sizeof(k_ipad));
- memset(k_opad, 0, sizeof(k_opad));
- memcpy(k_ipad, key, key_len);
- memcpy(k_opad, key, key_len);
+ /* start out by storing key in ipad */
+ memset(k_pad, 0, sizeof(k_pad));
+ memcpy(k_pad, key, key_len);
- /* XOR key with ipad and opad values */
- for (i = 0; i < 64; i++) {
- k_ipad[i] ^= 0x36;
- k_opad[i] ^= 0x5c;
- }
+ /* XOR key with ipad values */
+ for (i = 0; i < 64; i++)
+ k_pad[i] ^= 0x36;
/* perform inner MD5 */
- MD5Init(&context); /* init context for 1st pass */
- MD5Update(&context, k_ipad, 64); /* start with inner pad */
- /* then text of datagram; all fragments */
+ _addr[0] = k_pad;
+ _len[0] = 64;
for (i = 0; i < num_elem; i++) {
- MD5Update(&context, addr[i], len[i]);
+ _addr[i + 1] = addr[i];
+ _len[i + 1] = len[i];
}
- MD5Final(mac, &context); /* finish up 1st pass */
+ md5_vector(1 + num_elem, _addr, _len, mac);
+
+ memset(k_pad, 0, sizeof(k_pad));
+ memcpy(k_pad, key, key_len);
+ /* XOR key with opad values */
+ for (i = 0; i < 64; i++)
+ k_pad[i] ^= 0x5c;
/* perform outer MD5 */
- MD5Init(&context); /* init context for 2nd pass */
- MD5Update(&context, k_opad, 64); /* start with outer pad */
- MD5Update(&context, mac, 16); /* then results of 1st hash */
- MD5Final(mac, &context); /* finish up 2nd pass */
+ _addr[0] = k_pad;
+ _len[0] = 64;
+ _addr[1] = mac;
+ _len[1] = MD5_MAC_LEN;
+ md5_vector(2, _addr, _len, mac);
}
+/**
+ * hmac_md5 - HMAC-MD5 over data buffer (RFC 2104)
+ * @key: Key for HMAC operations
+ * @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 (16 bytes)
+ */
void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
u8 *mac)
{
@@ -99,6 +112,40 @@ void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
#ifndef EAP_TLS_FUNCS
+struct MD5Context {
+ u32 buf[4];
+ u32 bits[2];
+ u8 in[64];
+};
+
+static void MD5Init(struct MD5Context *context);
+static void MD5Update(struct MD5Context *context, unsigned char const *buf,
+ unsigned len);
+static void MD5Final(unsigned char digest[16], struct MD5Context *context);
+static void MD5Transform(u32 buf[4], u32 const in[16]);
+
+typedef struct MD5Context MD5_CTX;
+
+
+/**
+ * md5_vector - MD5 hash for data vector
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
+ * @mac: Buffer for the hash
+ */
+void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+{
+ MD5_CTX ctx;
+ int i;
+
+ MD5Init(&ctx);
+ for (i = 0; i < num_elem; i++)
+ MD5Update(&ctx, addr[i], len[i]);
+ MD5Final(mac, &ctx);
+}
+
+
/* ===== start - public domain MD5 implementation ===== */
/*
* This code implements the MD5 message-digest algorithm.
@@ -120,13 +167,10 @@ void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
#ifndef WORDS_BIGENDIAN
#define byteReverse(buf, len) /* Nothing */
#else
-void byteReverse(unsigned char *buf, unsigned longs);
-
-#ifndef ASM_MD5
/*
* Note: this code is harmless on little-endian machines.
*/
-void byteReverse(unsigned char *buf, unsigned longs)
+static void byteReverse(unsigned char *buf, unsigned longs)
{
u32 t;
do {
@@ -137,13 +181,12 @@ void byteReverse(unsigned char *buf, unsigned longs)
} while (--longs);
}
#endif
-#endif
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
-void MD5Init(struct MD5Context *ctx)
+static void MD5Init(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
@@ -158,7 +201,8 @@ void MD5Init(struct MD5Context *ctx)
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
-void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+static void MD5Update(struct MD5Context *ctx, unsigned char const *buf,
+ unsigned len)
{
u32 t;
@@ -206,7 +250,7 @@ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
-void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+static void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
{
unsigned count;
unsigned char *p;
@@ -247,8 +291,6 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
}
-#ifndef ASM_MD5
-
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
@@ -266,7 +308,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
-void MD5Transform(u32 buf[4], u32 const in[16])
+static void MD5Transform(u32 buf[4], u32 const in[16])
{
register u32 a, b, c, d;
@@ -348,8 +390,6 @@ void MD5Transform(u32 buf[4], u32 const in[16])
buf[2] += c;
buf[3] += d;
}
-
-#endif
/* ===== end - public domain MD5 implementation ===== */
#endif /* !EAP_TLS_FUNCS */