2 * SHA1 hash implementation and interface functions
3 * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
24 * hmac_sha1_vector - HMAC-SHA1 over data vector (RFC 2104)
25 * @key: Key for HMAC operations
26 * @key_len: Length of the key in bytes
27 * @num_elem: Number of elements in the data vector
28 * @addr: Pointers to the data areas
29 * @len: Lengths of the data blocks
30 * @mac: Buffer for the hash (20 bytes)
32 void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
33 const u8 *addr[], const size_t *len, u8 *mac)
35 unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
42 * Fixed limit on the number of fragments to avoid having to
43 * allocate memory (which could fail).
48 /* if key is longer than 64 bytes reset it to key = SHA1(key) */
50 sha1_vector(1, &key, &key_len, tk);
55 /* the HMAC_SHA1 transform looks like:
57 * SHA1(K XOR opad, SHA1(K XOR ipad, text))
59 * where K is an n byte key
60 * ipad is the byte 0x36 repeated 64 times
61 * opad is the byte 0x5c repeated 64 times
62 * and text is the data being protected */
64 /* start out by storing key in ipad */
65 os_memset(k_pad, 0, sizeof(k_pad));
66 os_memcpy(k_pad, key, key_len);
67 /* XOR key with ipad values */
68 for (i = 0; i < 64; i++)
71 /* perform inner SHA1 */
74 for (i = 0; i < num_elem; i++) {
75 _addr[i + 1] = addr[i];
78 sha1_vector(1 + num_elem, _addr, _len, mac);
80 os_memset(k_pad, 0, sizeof(k_pad));
81 os_memcpy(k_pad, key, key_len);
82 /* XOR key with opad values */
83 for (i = 0; i < 64; i++)
86 /* perform outer SHA1 */
90 _len[1] = SHA1_MAC_LEN;
91 sha1_vector(2, _addr, _len, mac);
96 * hmac_sha1 - HMAC-SHA1 over data buffer (RFC 2104)
97 * @key: Key for HMAC operations
98 * @key_len: Length of the key in bytes
99 * @data: Pointers to the data area
100 * @data_len: Length of the data area
101 * @mac: Buffer for the hash (20 bytes)
103 void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
106 hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
111 * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
113 * @key_len: Length of the key in bytes
114 * @label: A unique label for each purpose of the PRF
115 * @data: Extra data to bind into the key
116 * @data_len: Length of the data
117 * @buf: Buffer for the generated pseudo-random key
118 * @buf_len: Number of bytes of key to generate
120 * This function is used to derive new, cryptographically separate keys from a
121 * given key (e.g., PMK in IEEE 802.11i).
123 void sha1_prf(const u8 *key, size_t key_len, const char *label,
124 const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
128 u8 hash[SHA1_MAC_LEN];
129 size_t label_len = os_strlen(label) + 1;
130 const unsigned char *addr[3];
133 addr[0] = (u8 *) label;
141 while (pos < buf_len) {
142 plen = buf_len - pos;
143 if (plen >= SHA1_MAC_LEN) {
144 hmac_sha1_vector(key, key_len, 3, addr, len,
148 hmac_sha1_vector(key, key_len, 3, addr, len,
150 os_memcpy(&buf[pos], hash, plen);
158 #ifndef CONFIG_NO_T_PRF
160 * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF)
162 * @key_len: Length of the key in bytes
163 * @label: A unique label for each purpose of the PRF
164 * @seed: Seed value to bind into the key
165 * @seed_len: Length of the seed
166 * @buf: Buffer for the generated pseudo-random key
167 * @buf_len: Number of bytes of key to generate
169 * This function is used to derive new, cryptographically separate keys from a
170 * given key for EAP-FAST. T-PRF is defined in RFC 4851, Section 5.5.
172 void sha1_t_prf(const u8 *key, size_t key_len, const char *label,
173 const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
175 unsigned char counter = 0;
177 u8 hash[SHA1_MAC_LEN];
178 size_t label_len = os_strlen(label);
180 const unsigned char *addr[5];
185 addr[1] = (unsigned char *) label;
186 len[1] = label_len + 1;
189 addr[3] = output_len;
194 output_len[0] = (buf_len >> 8) & 0xff;
195 output_len[1] = buf_len & 0xff;
197 while (pos < buf_len) {
199 plen = buf_len - pos;
200 hmac_sha1_vector(key, key_len, 5, addr, len, hash);
201 if (plen >= SHA1_MAC_LEN) {
202 os_memcpy(&buf[pos], hash, SHA1_MAC_LEN);
205 os_memcpy(&buf[pos], hash, plen);
208 len[0] = SHA1_MAC_LEN;
211 #endif /* CONFIG_NO_T_PRF */
214 #ifndef CONFIG_NO_TLS_PRF
216 * tls_prf - Pseudo-Random Function for TLS (TLS-PRF, RFC 2246)
217 * @secret: Key for PRF
218 * @secret_len: Length of the key in bytes
219 * @label: A unique label for each purpose of the PRF
220 * @seed: Seed value to bind into the key
221 * @seed_len: Length of the seed
222 * @out: Buffer for the generated pseudo-random key
223 * @outlen: Number of bytes of key to generate
224 * Returns: 0 on success, -1 on failure.
226 * This function is used to derive new, cryptographically separate keys from a
227 * given key in TLS. This PRF is defined in RFC 2246, Chapter 5.
229 int tls_prf(const u8 *secret, size_t secret_len, const char *label,
230 const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
232 size_t L_S1, L_S2, i;
234 u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN];
235 u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN];
236 int MD5_pos, SHA1_pos;
237 const u8 *MD5_addr[3];
239 const unsigned char *SHA1_addr[3];
246 MD5_len[0] = MD5_MAC_LEN;
247 MD5_addr[1] = (unsigned char *) label;
248 MD5_len[1] = os_strlen(label);
250 MD5_len[2] = seed_len;
252 SHA1_addr[0] = A_SHA1;
253 SHA1_len[0] = SHA1_MAC_LEN;
254 SHA1_addr[1] = (unsigned char *) label;
255 SHA1_len[1] = os_strlen(label);
257 SHA1_len[2] = seed_len;
259 /* RFC 2246, Chapter 5
260 * A(0) = seed, A(i) = HMAC(secret, A(i-1))
261 * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + ..
262 * PRF = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
265 L_S1 = L_S2 = (secret_len + 1) / 2;
268 if (secret_len & 1) {
269 /* The last byte of S1 will be shared with S2 */
273 hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
274 hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
276 MD5_pos = MD5_MAC_LEN;
277 SHA1_pos = SHA1_MAC_LEN;
278 for (i = 0; i < outlen; i++) {
279 if (MD5_pos == MD5_MAC_LEN) {
280 hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
282 hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
284 if (SHA1_pos == SHA1_MAC_LEN) {
285 hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
288 hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
291 out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
299 #endif /* CONFIG_NO_TLS_PRF */
302 #ifndef CONFIG_NO_PBKDF2
304 static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
305 size_t ssid_len, int iterations, unsigned int count,
308 unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
310 unsigned char count_buf[4];
313 size_t passphrase_len = os_strlen(passphrase);
315 addr[0] = (u8 *) ssid;
320 /* F(P, S, c, i) = U1 xor U2 xor ... Uc
321 * U1 = PRF(P, S || i)
326 count_buf[0] = (count >> 24) & 0xff;
327 count_buf[1] = (count >> 16) & 0xff;
328 count_buf[2] = (count >> 8) & 0xff;
329 count_buf[3] = count & 0xff;
330 hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp);
331 os_memcpy(digest, tmp, SHA1_MAC_LEN);
333 for (i = 1; i < iterations; i++) {
334 hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
336 os_memcpy(tmp, tmp2, SHA1_MAC_LEN);
337 for (j = 0; j < SHA1_MAC_LEN; j++)
338 digest[j] ^= tmp2[j];
344 * pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
345 * @passphrase: ASCII passphrase
347 * @ssid_len: SSID length in bytes
348 * @iterations: Number of iterations to run
349 * @buf: Buffer for the generated key
350 * @buflen: Length of the buffer in bytes
352 * This function is used to derive PSK for WPA-PSK. For this protocol,
353 * iterations is set to 4096 and buflen to 32. This function is described in
354 * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0.
356 void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
357 int iterations, u8 *buf, size_t buflen)
359 unsigned int count = 0;
360 unsigned char *pos = buf;
361 size_t left = buflen, plen;
362 unsigned char digest[SHA1_MAC_LEN];
366 pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
368 plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
369 os_memcpy(pos, digest, plen);
375 #endif /* CONFIG_NO_PBKDF2 */