Branch data Line data Source code
1 : : /*
2 : : * MD5 hash implementation and interface functions
3 : : * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
4 : : *
5 : : * This software may be distributed under the terms of the BSD license.
6 : : * See README for more details.
7 : : */
8 : :
9 : : #include "includes.h"
10 : :
11 : : #include "common.h"
12 : : #include "md5.h"
13 : : #include "crypto.h"
14 : :
15 : :
16 : : /**
17 : : * hmac_md5_vector - HMAC-MD5 over data vector (RFC 2104)
18 : : * @key: Key for HMAC operations
19 : : * @key_len: Length of the key in bytes
20 : : * @num_elem: Number of elements in the data vector
21 : : * @addr: Pointers to the data areas
22 : : * @len: Lengths of the data blocks
23 : : * @mac: Buffer for the hash (16 bytes)
24 : : * Returns: 0 on success, -1 on failure
25 : : */
26 : 546 : int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
27 : : const u8 *addr[], const size_t *len, u8 *mac)
28 : : {
29 : : u8 k_pad[64]; /* padding - key XORd with ipad/opad */
30 : : u8 tk[16];
31 : : const u8 *_addr[6];
32 : : size_t i, _len[6];
33 : :
34 [ - + ]: 546 : if (num_elem > 5) {
35 : : /*
36 : : * Fixed limit on the number of fragments to avoid having to
37 : : * allocate memory (which could fail).
38 : : */
39 : 0 : return -1;
40 : : }
41 : :
42 : : /* if key is longer than 64 bytes reset it to key = MD5(key) */
43 [ - + ]: 546 : if (key_len > 64) {
44 [ # # ]: 0 : if (md5_vector(1, &key, &key_len, tk))
45 : 0 : return -1;
46 : 0 : key = tk;
47 : 0 : key_len = 16;
48 : : }
49 : :
50 : : /* the HMAC_MD5 transform looks like:
51 : : *
52 : : * MD5(K XOR opad, MD5(K XOR ipad, text))
53 : : *
54 : : * where K is an n byte key
55 : : * ipad is the byte 0x36 repeated 64 times
56 : : * opad is the byte 0x5c repeated 64 times
57 : : * and text is the data being protected */
58 : :
59 : : /* start out by storing key in ipad */
60 : 546 : os_memset(k_pad, 0, sizeof(k_pad));
61 : 546 : os_memcpy(k_pad, key, key_len);
62 : :
63 : : /* XOR key with ipad values */
64 [ + + ]: 35490 : for (i = 0; i < 64; i++)
65 : 34944 : k_pad[i] ^= 0x36;
66 : :
67 : : /* perform inner MD5 */
68 : 546 : _addr[0] = k_pad;
69 : 546 : _len[0] = 64;
70 [ + + ]: 1130 : for (i = 0; i < num_elem; i++) {
71 : 584 : _addr[i + 1] = addr[i];
72 : 584 : _len[i + 1] = len[i];
73 : : }
74 [ - + ]: 546 : if (md5_vector(1 + num_elem, _addr, _len, mac))
75 : 0 : return -1;
76 : :
77 : 546 : os_memset(k_pad, 0, sizeof(k_pad));
78 : 546 : os_memcpy(k_pad, key, key_len);
79 : : /* XOR key with opad values */
80 [ + + ]: 35490 : for (i = 0; i < 64; i++)
81 : 34944 : k_pad[i] ^= 0x5c;
82 : :
83 : : /* perform outer MD5 */
84 : 546 : _addr[0] = k_pad;
85 : 546 : _len[0] = 64;
86 : 546 : _addr[1] = mac;
87 : 546 : _len[1] = MD5_MAC_LEN;
88 : 546 : return md5_vector(2, _addr, _len, mac);
89 : : }
90 : :
91 : :
92 : : /**
93 : : * hmac_md5 - HMAC-MD5 over data buffer (RFC 2104)
94 : : * @key: Key for HMAC operations
95 : : * @key_len: Length of the key in bytes
96 : : * @data: Pointers to the data area
97 : : * @data_len: Length of the data area
98 : : * @mac: Buffer for the hash (16 bytes)
99 : : * Returns: 0 on success, -1 on failure
100 : : */
101 : 526 : int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
102 : : u8 *mac)
103 : : {
104 : 526 : return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
105 : : }
|