~ubuntu-branches/ubuntu/gutsy/wpasupplicant/gutsy

« back to all changes in this revision

Viewing changes to sha1.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler, Alexander Sack
  • Date: 2007-08-26 16:06:57 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070826160657-2m8pxoweuxe8f93t
Tags: 0.6.0+0.5.8-0ubuntu1
* New upstream release
* remove patch 11_erroneous_manpage_ref, applied upstream
* remove patch 25_wpas_dbus_unregister_iface_fix, applied upstream

[ Alexander Sack ]
* bumping upstream version to replace development version 0.6.0 with
  this package from stable release branch.
* attempt to fix wierd timeout and high latency issues by going
  back to stable upstream version (0.5.9) (LP: #140763,
  LP: #141233).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SHA1 hash implementation and interface functions
 
3
 * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
 
4
 *
 
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.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
 
 
17
#include "common.h"
 
18
#include "sha1.h"
 
19
#include "md5.h"
 
20
#include "crypto.h"
 
21
 
 
22
 
 
23
/**
 
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)
 
31
 */
 
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)
 
34
{
 
35
        unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
 
36
        unsigned char tk[20];
 
37
        const u8 *_addr[6];
 
38
        size_t _len[6], i;
 
39
 
 
40
        if (num_elem > 5) {
 
41
                /*
 
42
                 * Fixed limit on the number of fragments to avoid having to
 
43
                 * allocate memory (which could fail).
 
44
                 */
 
45
                return;
 
46
        }
 
47
 
 
48
        /* if key is longer than 64 bytes reset it to key = SHA1(key) */
 
49
        if (key_len > 64) {
 
50
                sha1_vector(1, &key, &key_len, tk);
 
51
                key = tk;
 
52
                key_len = 20;
 
53
        }
 
54
 
 
55
        /* the HMAC_SHA1 transform looks like:
 
56
         *
 
57
         * SHA1(K XOR opad, SHA1(K XOR ipad, text))
 
58
         *
 
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 */
 
63
 
 
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++)
 
69
                k_pad[i] ^= 0x36;
 
70
 
 
71
        /* perform inner SHA1 */
 
72
        _addr[0] = k_pad;
 
73
        _len[0] = 64;
 
74
        for (i = 0; i < num_elem; i++) {
 
75
                _addr[i + 1] = addr[i];
 
76
                _len[i + 1] = len[i];
 
77
        }
 
78
        sha1_vector(1 + num_elem, _addr, _len, mac);
 
79
 
 
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++)
 
84
                k_pad[i] ^= 0x5c;
 
85
 
 
86
        /* perform outer SHA1 */
 
87
        _addr[0] = k_pad;
 
88
        _len[0] = 64;
 
89
        _addr[1] = mac;
 
90
        _len[1] = SHA1_MAC_LEN;
 
91
        sha1_vector(2, _addr, _len, mac);
 
92
}
 
93
 
 
94
 
 
95
/**
 
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)
 
102
 */
 
103
void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
 
104
               u8 *mac)
 
105
{
 
106
        hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
 
107
}
 
108
 
 
109
 
 
110
/**
 
111
 * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
 
112
 * @key: Key for PRF
 
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
 
119
 *
 
120
 * This function is used to derive new, cryptographically separate keys from a
 
121
 * given key (e.g., PMK in IEEE 802.11i).
 
122
 */
 
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)
 
125
{
 
126
        u8 zero = 0, counter = 0;
 
127
        size_t pos, plen;
 
128
        u8 hash[SHA1_MAC_LEN];
 
129
        size_t label_len = os_strlen(label);
 
130
        const unsigned char *addr[4];
 
131
        size_t len[4];
 
132
 
 
133
        addr[0] = (u8 *) label;
 
134
        len[0] = label_len;
 
135
        addr[1] = &zero;
 
136
        len[1] = 1;
 
137
        addr[2] = data;
 
138
        len[2] = data_len;
 
139
        addr[3] = &counter;
 
140
        len[3] = 1;
 
141
 
 
142
        pos = 0;
 
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,
 
147
                                         &buf[pos]);
 
148
                        pos += SHA1_MAC_LEN;
 
149
                } else {
 
150
                        hmac_sha1_vector(key, key_len, 4, addr, len,
 
151
                                         hash);
 
152
                        os_memcpy(&buf[pos], hash, plen);
 
153
                        break;
 
154
                }
 
155
                counter++;
 
156
        }
 
157
}
 
158
 
 
159
 
 
160
/**
 
161
 * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF)
 
162
 * @key: Key for 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
 
169
 *
 
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.
 
173
 */
 
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)
 
176
{
 
177
        unsigned char counter = 0;
 
178
        size_t pos, plen;
 
179
        u8 hash[SHA1_MAC_LEN];
 
180
        size_t label_len = os_strlen(label);
 
181
        u8 output_len[2];
 
182
        const unsigned char *addr[5];
 
183
        size_t len[5];
 
184
 
 
185
        addr[0] = hash;
 
186
        len[0] = 0;
 
187
        addr[1] = (unsigned char *) label;
 
188
        len[1] = label_len + 1;
 
189
        addr[2] = seed;
 
190
        len[2] = seed_len;
 
191
        addr[3] = output_len;
 
192
        len[3] = 2;
 
193
        addr[4] = &counter;
 
194
        len[4] = 1;
 
195
 
 
196
        output_len[0] = (buf_len >> 8) & 0xff;
 
197
        output_len[1] = buf_len & 0xff;
 
198
        pos = 0;
 
199
        while (pos < buf_len) {
 
200
                counter++;
 
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);
 
205
                        pos += SHA1_MAC_LEN;
 
206
                } else {
 
207
                        os_memcpy(&buf[pos], hash, plen);
 
208
                        break;
 
209
                }
 
210
                len[0] = SHA1_MAC_LEN;
 
211
        }
 
212
}
 
213
 
 
214
 
 
215
/**
 
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.
 
225
 *
 
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.
 
228
 */
 
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)
 
231
{
 
232
        size_t L_S1, L_S2, i;
 
233
        const u8 *S1, *S2;
 
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];
 
238
        size_t MD5_len[3];
 
239
        const unsigned char *SHA1_addr[3];
 
240
        size_t SHA1_len[3];
 
241
 
 
242
        if (secret_len & 1)
 
243
                return -1;
 
244
 
 
245
        MD5_addr[0] = A_MD5;
 
246
        MD5_len[0] = MD5_MAC_LEN;
 
247
        MD5_addr[1] = (unsigned char *) label;
 
248
        MD5_len[1] = os_strlen(label);
 
249
        MD5_addr[2] = seed;
 
250
        MD5_len[2] = seed_len;
 
251
 
 
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);
 
256
        SHA1_addr[2] = seed;
 
257
        SHA1_len[2] = seed_len;
 
258
 
 
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)
 
263
         */
 
264
 
 
265
        L_S1 = L_S2 = (secret_len + 1) / 2;
 
266
        S1 = secret;
 
267
        S2 = secret + L_S1;
 
268
 
 
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);
 
271
 
 
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);
 
277
                        MD5_pos = 0;
 
278
                        hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
 
279
                }
 
280
                if (SHA1_pos == SHA1_MAC_LEN) {
 
281
                        hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
 
282
                                         P_SHA1);
 
283
                        SHA1_pos = 0;
 
284
                        hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
 
285
                }
 
286
 
 
287
                out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
 
288
 
 
289
                MD5_pos++;
 
290
                SHA1_pos++;
 
291
        }
 
292
 
 
293
        return 0;
 
294
}
 
295
 
 
296
 
 
297
static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
 
298
                          size_t ssid_len, int iterations, unsigned int count,
 
299
                          u8 *digest)
 
300
{
 
301
        unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
 
302
        int i, j;
 
303
        unsigned char count_buf[4];
 
304
        const u8 *addr[2];
 
305
        size_t len[2];
 
306
        size_t passphrase_len = os_strlen(passphrase);
 
307
 
 
308
        addr[0] = (u8 *) ssid;
 
309
        len[0] = ssid_len;
 
310
        addr[1] = count_buf;
 
311
        len[1] = 4;
 
312
 
 
313
        /* F(P, S, c, i) = U1 xor U2 xor ... Uc
 
314
         * U1 = PRF(P, S || i)
 
315
         * U2 = PRF(P, U1)
 
316
         * Uc = PRF(P, Uc-1)
 
317
         */
 
318
 
 
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);
 
325
 
 
326
        for (i = 1; i < iterations; i++) {
 
327
                hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
 
328
                          tmp2);
 
329
                os_memcpy(tmp, tmp2, SHA1_MAC_LEN);
 
330
                for (j = 0; j < SHA1_MAC_LEN; j++)
 
331
                        digest[j] ^= tmp2[j];
 
332
        }
 
333
}
 
334
 
 
335
 
 
336
/**
 
337
 * pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
 
338
 * @passphrase: ASCII passphrase
 
339
 * @ssid: SSID
 
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
 
344
 *
 
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.
 
348
 */
 
349
void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
 
350
                 int iterations, u8 *buf, size_t buflen)
 
351
{
 
352
        unsigned int count = 0;
 
353
        unsigned char *pos = buf;
 
354
        size_t left = buflen, plen;
 
355
        unsigned char digest[SHA1_MAC_LEN];
 
356
 
 
357
        while (left > 0) {
 
358
                count++;
 
359
                pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
 
360
                              digest);
 
361
                plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
 
362
                os_memcpy(pos, digest, plen);
 
363
                pos += plen;
 
364
                left -= plen;
 
365
        }
 
366
}
 
367
 
 
368
 
 
369
#ifdef INTERNAL_SHA1
 
370
 
 
371
struct SHA1Context {
 
372
        u32 state[5];
 
373
        u32 count[2];
 
374
        unsigned char buffer[64];
 
375
};
 
376
 
 
377
typedef struct SHA1Context SHA1_CTX;
 
378
 
 
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]);
 
385
 
 
386
 
 
387
/**
 
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
 
393
 */
 
394
void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 
395
                 u8 *mac)
 
396
{
 
397
        SHA1_CTX ctx;
 
398
        size_t i;
 
399
 
 
400
        SHA1Init(&ctx);
 
401
        for (i = 0; i < num_elem; i++)
 
402
                SHA1Update(&ctx, addr[i], len[i]);
 
403
        SHA1Final(mac, &ctx);
 
404
}
 
405
 
 
406
 
 
407
int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
 
408
{
 
409
        u8 xkey[64];
 
410
        u32 t[5], _t[5];
 
411
        int i, j, m, k;
 
412
        u8 *xpos = x;
 
413
        u32 carry;
 
414
 
 
415
        if (seed_len > sizeof(xkey))
 
416
                seed_len = sizeof(xkey);
 
417
 
 
418
        /* FIPS 186-2 + change notice 1 */
 
419
 
 
420
        os_memcpy(xkey, seed, seed_len);
 
421
        os_memset(xkey + seed_len, 0, 64 - seed_len);
 
422
        t[0] = 0x67452301;
 
423
        t[1] = 0xEFCDAB89;
 
424
        t[2] = 0x98BADCFE;
 
425
        t[3] = 0x10325476;
 
426
        t[4] = 0xC3D2E1F0;
 
427
 
 
428
        m = xlen / 40;
 
429
        for (j = 0; j < m; j++) {
 
430
                /* XSEED_j = 0 */
 
431
                for (i = 0; i < 2; i++) {
 
432
                        /* XVAL = (XKEY + XSEED_j) mod 2^b */
 
433
 
 
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);
 
443
 
 
444
                        /* XKEY = (1 + XKEY + w_i) mod 2^b */
 
445
                        carry = 1;
 
446
                        for (k = 19; k >= 0; k--) {
 
447
                                carry += xkey[k] + xpos[k];
 
448
                                xkey[k] = carry & 0xff;
 
449
                                carry >>= 8;
 
450
                        }
 
451
 
 
452
                        xpos += SHA1_MAC_LEN;
 
453
                }
 
454
                /* x_j = w_0|w_1 */
 
455
        }
 
456
 
 
457
        return 0;
 
458
}
 
459
 
 
460
 
 
461
/* ===== start - public domain SHA1 implementation ===== */
 
462
 
 
463
/*
 
464
SHA-1 in C
 
465
By Steve Reid <sreid@sea-to-sky.net>
 
466
100% Public Domain
 
467
 
 
468
-----------------
 
469
Modified 7/98 
 
470
By James H. Brown <jbrown@burgoyne.com>
 
471
Still 100% Public Domain
 
472
 
 
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
 
476
len)
 
477
to
 
478
        void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
 
479
long len)
 
480
 
 
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
 
483
against
 
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().
 
486
 
 
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
 
489
"a"s).
 
490
 
 
491
I also changed the declaration of variables i & j in SHA1Update to 
 
492
unsigned long from unsigned int for the same reason.
 
493
 
 
494
These changes should make no difference to any 32 bit implementations since
 
495
an
 
496
int and a long are the same size in those environments.
 
497
 
 
498
--
 
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.
 
503
 
 
504
ALL changes I made can be located by searching for comments containing 'JHB'
 
505
-----------------
 
506
Modified 8/98
 
507
By Steve Reid <sreid@sea-to-sky.net>
 
508
Still 100% public domain
 
509
 
 
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
 
513
 
 
514
-----------------
 
515
Modified 4/01
 
516
By Saul Kravitz <Saul.Kravitz@celera.com>
 
517
Still 100% PD
 
518
Modified to run on Compaq Alpha hardware.  
 
519
 
 
520
-----------------
 
521
Modified 4/01
 
522
By Jouni Malinen <j@w1.fi>
 
523
Minor changes to match the coding style used in Dynamics.
 
524
 
 
525
Modified September 24, 2004
 
526
By Jouni Malinen <j@w1.fi>
 
527
Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
 
528
 
 
529
*/
 
530
 
 
531
/*
 
532
Test Vectors (from FIPS PUB 180-1)
 
533
"abc"
 
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
 
539
*/
 
540
 
 
541
#define SHA1HANDSOFF
 
542
 
 
543
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
 
544
 
 
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))
 
550
#else
 
551
#define blk0(i) block->l[i]
 
552
#endif
 
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))
 
555
 
 
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); \
 
559
        w = rol(w, 30);
 
560
#define R1(v,w,x,y,z,i) \
 
561
        z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
 
562
        w = rol(w, 30);
 
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); \
 
567
        w = rol(w, 30);
 
568
#define R4(v,w,x,y,z,i) \
 
569
        z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
 
570
        w=rol(w, 30);
 
571
 
 
572
 
 
573
#ifdef VERBOSE  /* SAK */
 
574
void SHAPrintContext(SHA1_CTX *context, char *msg)
 
575
{
 
576
        printf("%s (%d,%d) %x %x %x %x %x\n",
 
577
               msg,
 
578
               context->count[0], context->count[1], 
 
579
               context->state[0],
 
580
               context->state[1],
 
581
               context->state[2],
 
582
               context->state[3],
 
583
               context->state[4]);
 
584
}
 
585
#endif
 
586
 
 
587
/* Hash a single 512-bit block. This is the core of the algorithm. */
 
588
 
 
589
static void SHA1Transform(u32 state[5], const unsigned char buffer[64])
 
590
{
 
591
        u32 a, b, c, d, e;
 
592
        typedef union {
 
593
                unsigned char c[64];
 
594
                u32 l[16];
 
595
        } CHAR64LONG16;
 
596
        CHAR64LONG16* block;
 
597
#ifdef SHA1HANDSOFF
 
598
        u32 workspace[16];
 
599
        block = (CHAR64LONG16 *) workspace;
 
600
        os_memcpy(block, buffer, 64);
 
601
#else
 
602
        block = (CHAR64LONG16 *) buffer;
 
603
#endif
 
604
        /* Copy context->state[] to working vars */
 
605
        a = state[0];
 
606
        b = state[1];
 
607
        c = state[2];
 
608
        d = state[3];
 
609
        e = state[4];
 
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[] */
 
632
        state[0] += a;
 
633
        state[1] += b;
 
634
        state[2] += c;
 
635
        state[3] += d;
 
636
        state[4] += e;
 
637
        /* Wipe variables */
 
638
        a = b = c = d = e = 0;
 
639
#ifdef SHA1HANDSOFF
 
640
        os_memset(block, 0, 64);
 
641
#endif
 
642
}
 
643
 
 
644
 
 
645
/* SHA1Init - Initialize new context */
 
646
 
 
647
void SHA1Init(SHA1_CTX* context)
 
648
{
 
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;
 
656
}
 
657
 
 
658
 
 
659
/* Run your data through this. */
 
660
 
 
661
void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
 
662
{
 
663
        u32 i, j;
 
664
        const unsigned char *data = _data;
 
665
 
 
666
#ifdef VERBOSE
 
667
        SHAPrintContext(context, "before");
 
668
#endif
 
669
        j = (context->count[0] >> 3) & 63;
 
670
        if ((context->count[0] += len << 3) < (len << 3))
 
671
                context->count[1]++;
 
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]);
 
678
                }
 
679
                j = 0;
 
680
        }
 
681
        else i = 0;
 
682
        os_memcpy(&context->buffer[j], &data[i], len - i);
 
683
#ifdef VERBOSE
 
684
        SHAPrintContext(context, "after ");
 
685
#endif
 
686
}
 
687
 
 
688
 
 
689
/* Add padding and return the message digest. */
 
690
 
 
691
void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
 
692
{
 
693
        u32 i;
 
694
        unsigned char finalcount[8];
 
695
 
 
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 */
 
700
        }
 
701
        SHA1Update(context, (unsigned char *) "\200", 1);
 
702
        while ((context->count[0] & 504) != 448) {
 
703
                SHA1Update(context, (unsigned char *) "\0", 1);
 
704
        }
 
705
        SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform()
 
706
                                              */
 
707
        for (i = 0; i < 20; i++) {
 
708
                digest[i] = (unsigned char)
 
709
                        ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
 
710
                         255);
 
711
        }
 
712
        /* Wipe variables */
 
713
        i = 0;
 
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);
 
718
}
 
719
 
 
720
/* ===== end - public domain SHA1 implementation ===== */
 
721
 
 
722
#endif /* INTERNAL_SHA1 */