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)
126
u8 zero = 0, counter = 0;
128
u8 hash[SHA1_MAC_LEN];
129
size_t label_len = os_strlen(label);
130
const unsigned char *addr[4];
133
addr[0] = (u8 *) label;
143
while (pos < buf_len) {
144
plen = buf_len - pos;
145
if (plen >= SHA1_MAC_LEN) {
146
hmac_sha1_vector(key, key_len, 4, addr, len,
150
hmac_sha1_vector(key, key_len, 4, addr, len,
152
os_memcpy(&buf[pos], hash, plen);
161
* sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF)
163
* @key_len: Length of the key in bytes
164
* @label: A unique label for each purpose of the PRF
165
* @seed: Seed value to bind into the key
166
* @seed_len: Length of the seed
167
* @buf: Buffer for the generated pseudo-random key
168
* @buf_len: Number of bytes of key to generate
170
* This function is used to derive new, cryptographically separate keys from a
171
* given key for EAP-FAST. T-PRF is defined in
172
* draft-cam-winget-eap-fast-02.txt, Appendix B.
174
void sha1_t_prf(const u8 *key, size_t key_len, const char *label,
175
const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
177
unsigned char counter = 0;
179
u8 hash[SHA1_MAC_LEN];
180
size_t label_len = os_strlen(label);
182
const unsigned char *addr[5];
187
addr[1] = (unsigned char *) label;
188
len[1] = label_len + 1;
191
addr[3] = output_len;
196
output_len[0] = (buf_len >> 8) & 0xff;
197
output_len[1] = buf_len & 0xff;
199
while (pos < buf_len) {
201
plen = buf_len - pos;
202
hmac_sha1_vector(key, key_len, 5, addr, len, hash);
203
if (plen >= SHA1_MAC_LEN) {
204
os_memcpy(&buf[pos], hash, SHA1_MAC_LEN);
207
os_memcpy(&buf[pos], hash, plen);
210
len[0] = SHA1_MAC_LEN;
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;
269
hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
270
hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
272
MD5_pos = MD5_MAC_LEN;
273
SHA1_pos = SHA1_MAC_LEN;
274
for (i = 0; i < outlen; i++) {
275
if (MD5_pos == MD5_MAC_LEN) {
276
hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
278
hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
280
if (SHA1_pos == SHA1_MAC_LEN) {
281
hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
284
hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
287
out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
297
static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
298
size_t ssid_len, int iterations, unsigned int count,
301
unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
303
unsigned char count_buf[4];
306
size_t passphrase_len = os_strlen(passphrase);
308
addr[0] = (u8 *) ssid;
313
/* F(P, S, c, i) = U1 xor U2 xor ... Uc
314
* U1 = PRF(P, S || i)
319
count_buf[0] = (count >> 24) & 0xff;
320
count_buf[1] = (count >> 16) & 0xff;
321
count_buf[2] = (count >> 8) & 0xff;
322
count_buf[3] = count & 0xff;
323
hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp);
324
os_memcpy(digest, tmp, SHA1_MAC_LEN);
326
for (i = 1; i < iterations; i++) {
327
hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
329
os_memcpy(tmp, tmp2, SHA1_MAC_LEN);
330
for (j = 0; j < SHA1_MAC_LEN; j++)
331
digest[j] ^= tmp2[j];
337
* pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
338
* @passphrase: ASCII passphrase
340
* @ssid_len: SSID length in bytes
341
* @interations: Number of iterations to run
342
* @buf: Buffer for the generated key
343
* @buflen: Length of the buffer in bytes
345
* This function is used to derive PSK for WPA-PSK. For this protocol,
346
* iterations is set to 4096 and buflen to 32. This function is described in
347
* IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0.
349
void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
350
int iterations, u8 *buf, size_t buflen)
352
unsigned int count = 0;
353
unsigned char *pos = buf;
354
size_t left = buflen, plen;
355
unsigned char digest[SHA1_MAC_LEN];
359
pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
361
plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
362
os_memcpy(pos, digest, plen);
374
unsigned char buffer[64];
377
typedef struct SHA1Context SHA1_CTX;
379
#ifndef CONFIG_CRYPTO_INTERNAL
380
static void SHA1Init(struct SHA1Context *context);
381
static void SHA1Update(struct SHA1Context *context, const void *data, u32 len);
382
static void SHA1Final(unsigned char digest[20], struct SHA1Context *context);
383
#endif /* CONFIG_CRYPTO_INTERNAL */
384
static void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
388
* sha1_vector - SHA-1 hash for data vector
389
* @num_elem: Number of elements in the data vector
390
* @addr: Pointers to the data areas
391
* @len: Lengths of the data blocks
392
* @mac: Buffer for the hash
394
void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
401
for (i = 0; i < num_elem; i++)
402
SHA1Update(&ctx, addr[i], len[i]);
403
SHA1Final(mac, &ctx);
407
int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
415
if (seed_len > sizeof(xkey))
416
seed_len = sizeof(xkey);
418
/* FIPS 186-2 + change notice 1 */
420
os_memcpy(xkey, seed, seed_len);
421
os_memset(xkey + seed_len, 0, 64 - seed_len);
429
for (j = 0; j < m; j++) {
431
for (i = 0; i < 2; i++) {
432
/* XVAL = (XKEY + XSEED_j) mod 2^b */
434
/* w_i = G(t, XVAL) */
435
os_memcpy(_t, t, 20);
436
SHA1Transform(_t, xkey);
437
_t[0] = host_to_be32(_t[0]);
438
_t[1] = host_to_be32(_t[1]);
439
_t[2] = host_to_be32(_t[2]);
440
_t[3] = host_to_be32(_t[3]);
441
_t[4] = host_to_be32(_t[4]);
442
os_memcpy(xpos, _t, 20);
444
/* XKEY = (1 + XKEY + w_i) mod 2^b */
446
for (k = 19; k >= 0; k--) {
447
carry += xkey[k] + xpos[k];
448
xkey[k] = carry & 0xff;
452
xpos += SHA1_MAC_LEN;
461
/* ===== start - public domain SHA1 implementation ===== */
465
By Steve Reid <sreid@sea-to-sky.net>
470
By James H. Brown <jbrown@burgoyne.com>
471
Still 100% Public Domain
473
Corrected a problem which generated improper hash values on 16 bit machines
474
Routine SHA1Update changed from
475
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
478
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
481
The 'len' parameter was declared an int which works fine on 32 bit machines.
482
However, on 16 bit machines an int is too small for the shifts being done
484
it. This caused the hash function to generate incorrect values if len was
485
greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
487
Since the file IO in main() reads 16K at a time, any file 8K or larger would
488
be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
491
I also changed the declaration of variables i & j in SHA1Update to
492
unsigned long from unsigned int for the same reason.
494
These changes should make no difference to any 32 bit implementations since
496
int and a long are the same size in those environments.
499
I also corrected a few compiler warnings generated by Borland C.
500
1. Added #include <process.h> for exit() prototype
501
2. Removed unused variable 'j' in SHA1Final
502
3. Changed exit(0) to return(0) at end of main.
504
ALL changes I made can be located by searching for comments containing 'JHB'
507
By Steve Reid <sreid@sea-to-sky.net>
508
Still 100% public domain
510
1- Removed #include <process.h> and used return() instead of exit()
511
2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
512
3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
516
By Saul Kravitz <Saul.Kravitz@celera.com>
518
Modified to run on Compaq Alpha hardware.
522
By Jouni Malinen <j@w1.fi>
523
Minor changes to match the coding style used in Dynamics.
525
Modified September 24, 2004
526
By Jouni Malinen <j@w1.fi>
527
Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
532
Test Vectors (from FIPS PUB 180-1)
534
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
535
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
536
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
537
A million repetitions of "a"
538
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
543
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
545
/* blk0() and blk() perform the initial expand. */
546
/* I got the idea of expanding during the round function from SSLeay */
547
#ifndef WORDS_BIGENDIAN
548
#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
549
(rol(block->l[i], 8) & 0x00FF00FF))
551
#define blk0(i) block->l[i]
553
#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
554
block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
556
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
557
#define R0(v,w,x,y,z,i) \
558
z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
560
#define R1(v,w,x,y,z,i) \
561
z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
563
#define R2(v,w,x,y,z,i) \
564
z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
565
#define R3(v,w,x,y,z,i) \
566
z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
568
#define R4(v,w,x,y,z,i) \
569
z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
573
#ifdef VERBOSE /* SAK */
574
void SHAPrintContext(SHA1_CTX *context, char *msg)
576
printf("%s (%d,%d) %x %x %x %x %x\n",
578
context->count[0], context->count[1],
587
/* Hash a single 512-bit block. This is the core of the algorithm. */
589
static void SHA1Transform(u32 state[5], const unsigned char buffer[64])
599
block = (CHAR64LONG16 *) workspace;
600
os_memcpy(block, buffer, 64);
602
block = (CHAR64LONG16 *) buffer;
604
/* Copy context->state[] to working vars */
610
/* 4 rounds of 20 operations each. Loop unrolled. */
611
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
612
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
613
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
614
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
615
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
616
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
617
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
618
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
619
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
620
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
621
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
622
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
623
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
624
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
625
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
626
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
627
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
628
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
629
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
630
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
631
/* Add the working vars back into context.state[] */
638
a = b = c = d = e = 0;
640
os_memset(block, 0, 64);
645
/* SHA1Init - Initialize new context */
647
void SHA1Init(SHA1_CTX* context)
649
/* SHA1 initialization constants */
650
context->state[0] = 0x67452301;
651
context->state[1] = 0xEFCDAB89;
652
context->state[2] = 0x98BADCFE;
653
context->state[3] = 0x10325476;
654
context->state[4] = 0xC3D2E1F0;
655
context->count[0] = context->count[1] = 0;
659
/* Run your data through this. */
661
void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
664
const unsigned char *data = _data;
667
SHAPrintContext(context, "before");
669
j = (context->count[0] >> 3) & 63;
670
if ((context->count[0] += len << 3) < (len << 3))
672
context->count[1] += (len >> 29);
673
if ((j + len) > 63) {
674
os_memcpy(&context->buffer[j], data, (i = 64-j));
675
SHA1Transform(context->state, context->buffer);
676
for ( ; i + 63 < len; i += 64) {
677
SHA1Transform(context->state, &data[i]);
682
os_memcpy(&context->buffer[j], &data[i], len - i);
684
SHAPrintContext(context, "after ");
689
/* Add padding and return the message digest. */
691
void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
694
unsigned char finalcount[8];
696
for (i = 0; i < 8; i++) {
697
finalcount[i] = (unsigned char)
698
((context->count[(i >= 4 ? 0 : 1)] >>
699
((3-(i & 3)) * 8) ) & 255); /* Endian independent */
701
SHA1Update(context, (unsigned char *) "\200", 1);
702
while ((context->count[0] & 504) != 448) {
703
SHA1Update(context, (unsigned char *) "\0", 1);
705
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform()
707
for (i = 0; i < 20; i++) {
708
digest[i] = (unsigned char)
709
((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
714
os_memset(context->buffer, 0, 64);
715
os_memset(context->state, 0, 20);
716
os_memset(context->count, 0, 8);
717
os_memset(finalcount, 0, 8);
720
/* ===== end - public domain SHA1 implementation ===== */
722
#endif /* INTERNAL_SHA1 */