sha1.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "sha1.h"
00020 #include "md5.h"
00021 #include "crypto.h"
00022 
00023 
00034 void hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
00035                       const u8 *addr[], const size_t *len, u8 *mac)
00036 {
00037         unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
00038         unsigned char tk[20];
00039         const u8 *_addr[6];
00040         size_t _len[6], i;
00041 
00042         if (num_elem > 5) {
00043                 /*
00044                  * Fixed limit on the number of fragments to avoid having to
00045                  * allocate memory (which could fail).
00046                  */
00047                 return;
00048         }
00049 
00050         /* if key is longer than 64 bytes reset it to key = SHA1(key) */
00051         if (key_len > 64) {
00052                 sha1_vector(1, &key, &key_len, tk);
00053                 key = tk;
00054                 key_len = 20;
00055         }
00056 
00057         /* the HMAC_SHA1 transform looks like:
00058          *
00059          * SHA1(K XOR opad, SHA1(K XOR ipad, text))
00060          *
00061          * where K is an n byte key
00062          * ipad is the byte 0x36 repeated 64 times
00063          * opad is the byte 0x5c repeated 64 times
00064          * and text is the data being protected */
00065 
00066         /* start out by storing key in ipad */
00067         os_memset(k_pad, 0, sizeof(k_pad));
00068         os_memcpy(k_pad, key, key_len);
00069         /* XOR key with ipad values */
00070         for (i = 0; i < 64; i++)
00071                 k_pad[i] ^= 0x36;
00072 
00073         /* perform inner SHA1 */
00074         _addr[0] = k_pad;
00075         _len[0] = 64;
00076         for (i = 0; i < num_elem; i++) {
00077                 _addr[i + 1] = addr[i];
00078                 _len[i + 1] = len[i];
00079         }
00080         sha1_vector(1 + num_elem, _addr, _len, mac);
00081 
00082         os_memset(k_pad, 0, sizeof(k_pad));
00083         os_memcpy(k_pad, key, key_len);
00084         /* XOR key with opad values */
00085         for (i = 0; i < 64; i++)
00086                 k_pad[i] ^= 0x5c;
00087 
00088         /* perform outer SHA1 */
00089         _addr[0] = k_pad;
00090         _len[0] = 64;
00091         _addr[1] = mac;
00092         _len[1] = SHA1_MAC_LEN;
00093         sha1_vector(2, _addr, _len, mac);
00094 }
00095 
00096 
00106 void hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
00107                u8 *mac)
00108 {
00109         hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
00110 }
00111 
00112 
00127 void sha1_prf(const u8 *key, size_t key_len, const char *label,
00128               const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
00129 {
00130         u8 zero = 0, counter = 0;
00131         size_t pos, plen;
00132         u8 hash[SHA1_MAC_LEN];
00133         size_t label_len = os_strlen(label);
00134         const unsigned char *addr[4];
00135         size_t len[4];
00136 
00137         addr[0] = (u8 *) label;
00138         len[0] = label_len;
00139         addr[1] = &zero;
00140         len[1] = 1;
00141         addr[2] = data;
00142         len[2] = data_len;
00143         addr[3] = &counter;
00144         len[3] = 1;
00145 
00146         pos = 0;
00147         while (pos < buf_len) {
00148                 plen = buf_len - pos;
00149                 if (plen >= SHA1_MAC_LEN) {
00150                         hmac_sha1_vector(key, key_len, 4, addr, len,
00151                                          &buf[pos]);
00152                         pos += SHA1_MAC_LEN;
00153                 } else {
00154                         hmac_sha1_vector(key, key_len, 4, addr, len,
00155                                          hash);
00156                         os_memcpy(&buf[pos], hash, plen);
00157                         break;
00158                 }
00159                 counter++;
00160         }
00161 }
00162 
00163 
00179 void sha1_t_prf(const u8 *key, size_t key_len, const char *label,
00180                 const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
00181 {
00182         unsigned char counter = 0;
00183         size_t pos, plen;
00184         u8 hash[SHA1_MAC_LEN];
00185         size_t label_len = os_strlen(label);
00186         u8 output_len[2];
00187         const unsigned char *addr[5];
00188         size_t len[5];
00189 
00190         addr[0] = hash;
00191         len[0] = 0;
00192         addr[1] = (unsigned char *) label;
00193         len[1] = label_len + 1;
00194         addr[2] = seed;
00195         len[2] = seed_len;
00196         addr[3] = output_len;
00197         len[3] = 2;
00198         addr[4] = &counter;
00199         len[4] = 1;
00200 
00201         output_len[0] = (buf_len >> 8) & 0xff;
00202         output_len[1] = buf_len & 0xff;
00203         pos = 0;
00204         while (pos < buf_len) {
00205                 counter++;
00206                 plen = buf_len - pos;
00207                 hmac_sha1_vector(key, key_len, 5, addr, len, hash);
00208                 if (plen >= SHA1_MAC_LEN) {
00209                         os_memcpy(&buf[pos], hash, SHA1_MAC_LEN);
00210                         pos += SHA1_MAC_LEN;
00211                 } else {
00212                         os_memcpy(&buf[pos], hash, plen);
00213                         break;
00214                 }
00215                 len[0] = SHA1_MAC_LEN;
00216         }
00217 }
00218 
00219 
00235 int tls_prf(const u8 *secret, size_t secret_len, const char *label,
00236             const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
00237 {
00238         size_t L_S1, L_S2, i;
00239         const u8 *S1, *S2;
00240         u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN];
00241         u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN];
00242         int MD5_pos, SHA1_pos;
00243         const u8 *MD5_addr[3];
00244         size_t MD5_len[3];
00245         const unsigned char *SHA1_addr[3];
00246         size_t SHA1_len[3];
00247 
00248         if (secret_len & 1)
00249                 return -1;
00250 
00251         MD5_addr[0] = A_MD5;
00252         MD5_len[0] = MD5_MAC_LEN;
00253         MD5_addr[1] = (unsigned char *) label;
00254         MD5_len[1] = os_strlen(label);
00255         MD5_addr[2] = seed;
00256         MD5_len[2] = seed_len;
00257 
00258         SHA1_addr[0] = A_SHA1;
00259         SHA1_len[0] = SHA1_MAC_LEN;
00260         SHA1_addr[1] = (unsigned char *) label;
00261         SHA1_len[1] = os_strlen(label);
00262         SHA1_addr[2] = seed;
00263         SHA1_len[2] = seed_len;
00264 
00265         /* RFC 2246, Chapter 5
00266          * A(0) = seed, A(i) = HMAC(secret, A(i-1))
00267          * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + ..
00268          * PRF = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
00269          */
00270 
00271         L_S1 = L_S2 = (secret_len + 1) / 2;
00272         S1 = secret;
00273         S2 = secret + L_S1;
00274 
00275         hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
00276         hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
00277 
00278         MD5_pos = MD5_MAC_LEN;
00279         SHA1_pos = SHA1_MAC_LEN;
00280         for (i = 0; i < outlen; i++) {
00281                 if (MD5_pos == MD5_MAC_LEN) {
00282                         hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
00283                         MD5_pos = 0;
00284                         hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
00285                 }
00286                 if (SHA1_pos == SHA1_MAC_LEN) {
00287                         hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
00288                                          P_SHA1);
00289                         SHA1_pos = 0;
00290                         hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
00291                 }
00292 
00293                 out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
00294 
00295                 MD5_pos++;
00296                 SHA1_pos++;
00297         }
00298 
00299         return 0;
00300 }
00301 
00302 
00303 static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
00304                           size_t ssid_len, int iterations, unsigned int count,
00305                           u8 *digest)
00306 {
00307         unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
00308         int i, j;
00309         unsigned char count_buf[4];
00310         const u8 *addr[2];
00311         size_t len[2];
00312         size_t passphrase_len = os_strlen(passphrase);
00313 
00314         addr[0] = (u8 *) ssid;
00315         len[0] = ssid_len;
00316         addr[1] = count_buf;
00317         len[1] = 4;
00318 
00319         /* F(P, S, c, i) = U1 xor U2 xor ... Uc
00320          * U1 = PRF(P, S || i)
00321          * U2 = PRF(P, U1)
00322          * Uc = PRF(P, Uc-1)
00323          */
00324 
00325         count_buf[0] = (count >> 24) & 0xff;
00326         count_buf[1] = (count >> 16) & 0xff;
00327         count_buf[2] = (count >> 8) & 0xff;
00328         count_buf[3] = count & 0xff;
00329         hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len, tmp);
00330         os_memcpy(digest, tmp, SHA1_MAC_LEN);
00331 
00332         for (i = 1; i < iterations; i++) {
00333                 hmac_sha1((u8 *) passphrase, passphrase_len, tmp, SHA1_MAC_LEN,
00334                           tmp2);
00335                 os_memcpy(tmp, tmp2, SHA1_MAC_LEN);
00336                 for (j = 0; j < SHA1_MAC_LEN; j++)
00337                         digest[j] ^= tmp2[j];
00338         }
00339 }
00340 
00341 
00356 void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,
00357                  int iterations, u8 *buf, size_t buflen)
00358 {
00359         unsigned int count = 0;
00360         unsigned char *pos = buf;
00361         size_t left = buflen, plen;
00362         unsigned char digest[SHA1_MAC_LEN];
00363 
00364         while (left > 0) {
00365                 count++;
00366                 pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations, count,
00367                               digest);
00368                 plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
00369                 os_memcpy(pos, digest, plen);
00370                 pos += plen;
00371                 left -= plen;
00372         }
00373 }
00374 
00375 
00376 #ifdef INTERNAL_SHA1
00377 
00378 struct SHA1Context {
00379         u32 state[5];
00380         u32 count[2];
00381         unsigned char buffer[64];
00382 };
00383 
00384 typedef struct SHA1Context SHA1_CTX;
00385 
00386 #ifndef CONFIG_CRYPTO_INTERNAL
00387 static void SHA1Init(struct SHA1Context *context);
00388 static void SHA1Update(struct SHA1Context *context, const void *data, u32 len);
00389 static void SHA1Final(unsigned char digest[20], struct SHA1Context *context);
00390 #endif /* CONFIG_CRYPTO_INTERNAL */
00391 static void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
00392 
00393 
00402 void sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
00403                  u8 *mac)
00404 {
00405         SHA1_CTX ctx;
00406         size_t i;
00407 
00408         SHA1Init(&ctx);
00409         for (i = 0; i < num_elem; i++)
00410                 SHA1Update(&ctx, addr[i], len[i]);
00411         SHA1Final(mac, &ctx);
00412 }
00413 
00414 
00415 int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
00416 {
00417         u8 xkey[64];
00418         u32 t[5], _t[5];
00419         int i, j, m, k;
00420         u8 *xpos = x;
00421         u32 carry;
00422 
00423         if (seed_len > sizeof(xkey))
00424                 seed_len = sizeof(xkey);
00425 
00426         /* FIPS 186-2 + change notice 1 */
00427 
00428         os_memcpy(xkey, seed, seed_len);
00429         os_memset(xkey + seed_len, 0, 64 - seed_len);
00430         t[0] = 0x67452301;
00431         t[1] = 0xEFCDAB89;
00432         t[2] = 0x98BADCFE;
00433         t[3] = 0x10325476;
00434         t[4] = 0xC3D2E1F0;
00435 
00436         m = xlen / 40;
00437         for (j = 0; j < m; j++) {
00438                 /* XSEED_j = 0 */
00439                 for (i = 0; i < 2; i++) {
00440                         /* XVAL = (XKEY + XSEED_j) mod 2^b */
00441 
00442                         /* w_i = G(t, XVAL) */
00443                         os_memcpy(_t, t, 20);
00444                         SHA1Transform(_t, xkey);
00445                         _t[0] = host_to_be32(_t[0]);
00446                         _t[1] = host_to_be32(_t[1]);
00447                         _t[2] = host_to_be32(_t[2]);
00448                         _t[3] = host_to_be32(_t[3]);
00449                         _t[4] = host_to_be32(_t[4]);
00450                         os_memcpy(xpos, _t, 20);
00451 
00452                         /* XKEY = (1 + XKEY + w_i) mod 2^b */
00453                         carry = 1;
00454                         for (k = 19; k >= 0; k--) {
00455                                 carry += xkey[k] + xpos[k];
00456                                 xkey[k] = carry & 0xff;
00457                                 carry >>= 8;
00458                         }
00459 
00460                         xpos += SHA1_MAC_LEN;
00461                 }
00462                 /* x_j = w_0|w_1 */
00463         }
00464 
00465         return 0;
00466 }
00467 
00468 
00469 /* ===== start - public domain SHA1 implementation ===== */
00470 
00471 /*
00472 SHA-1 in C
00473 By Steve Reid <[email protected]>
00474 100% Public Domain
00475 
00476 -----------------
00477 Modified 7/98 
00478 By James H. Brown <[email protected]>
00479 Still 100% Public Domain
00480 
00481 Corrected a problem which generated improper hash values on 16 bit machines
00482 Routine SHA1Update changed from
00483         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
00484 len)
00485 to
00486         void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
00487 long len)
00488 
00489 The 'len' parameter was declared an int which works fine on 32 bit machines.
00490 However, on 16 bit machines an int is too small for the shifts being done
00491 against
00492 it.  This caused the hash function to generate incorrect values if len was
00493 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
00494 
00495 Since the file IO in main() reads 16K at a time, any file 8K or larger would
00496 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
00497 "a"s).
00498 
00499 I also changed the declaration of variables i & j in SHA1Update to 
00500 unsigned long from unsigned int for the same reason.
00501 
00502 These changes should make no difference to any 32 bit implementations since
00503 an
00504 int and a long are the same size in those environments.
00505 
00506 --
00507 I also corrected a few compiler warnings generated by Borland C.
00508 1. Added #include <process.h> for exit() prototype
00509 2. Removed unused variable 'j' in SHA1Final
00510 3. Changed exit(0) to return(0) at end of main.
00511 
00512 ALL changes I made can be located by searching for comments containing 'JHB'
00513 -----------------
00514 Modified 8/98
00515 By Steve Reid <[email protected]>
00516 Still 100% public domain
00517 
00518 1- Removed #include <process.h> and used return() instead of exit()
00519 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
00520 3- Changed email address from [email protected] to [email protected]
00521 
00522 -----------------
00523 Modified 4/01
00524 By Saul Kravitz <[email protected]>
00525 Still 100% PD
00526 Modified to run on Compaq Alpha hardware.  
00527 
00528 -----------------
00529 Modified 4/01
00530 By Jouni Malinen <[email protected]>
00531 Minor changes to match the coding style used in Dynamics.
00532 
00533 Modified September 24, 2004
00534 By Jouni Malinen <[email protected]>
00535 Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.
00536 
00537 */
00538 
00539 /*
00540 Test Vectors (from FIPS PUB 180-1)
00541 "abc"
00542   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
00543 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
00544   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
00545 A million repetitions of "a"
00546   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
00547 */
00548 
00549 #define SHA1HANDSOFF
00550 
00551 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
00552 
00553 /* blk0() and blk() perform the initial expand. */
00554 /* I got the idea of expanding during the round function from SSLeay */
00555 #ifndef WORDS_BIGENDIAN
00556 #define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
00557         (rol(block->l[i], 8) & 0x00FF00FF))
00558 #else
00559 #define blk0(i) block->l[i]
00560 #endif
00561 #define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
00562         block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
00563 
00564 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
00565 #define R0(v,w,x,y,z,i) \
00566         z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
00567         w = rol(w, 30);
00568 #define R1(v,w,x,y,z,i) \
00569         z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
00570         w = rol(w, 30);
00571 #define R2(v,w,x,y,z,i) \
00572         z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
00573 #define R3(v,w,x,y,z,i) \
00574         z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
00575         w = rol(w, 30);
00576 #define R4(v,w,x,y,z,i) \
00577         z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
00578         w=rol(w, 30);
00579 
00580 
00581 #ifdef VERBOSE  /* SAK */
00582 void SHAPrintContext(SHA1_CTX *context, char *msg)
00583 {
00584         printf("%s (%d,%d) %x %x %x %x %x\n",
00585                msg,
00586                context->count[0], context->count[1], 
00587                context->state[0],
00588                context->state[1],
00589                context->state[2],
00590                context->state[3],
00591                context->state[4]);
00592 }
00593 #endif
00594 
00595 /* Hash a single 512-bit block. This is the core of the algorithm. */
00596 
00597 static void SHA1Transform(u32 state[5], const unsigned char buffer[64])
00598 {
00599         u32 a, b, c, d, e;
00600         typedef union {
00601                 unsigned char c[64];
00602                 u32 l[16];
00603         } CHAR64LONG16;
00604         CHAR64LONG16* block;
00605 #ifdef SHA1HANDSOFF
00606         u32 workspace[16];
00607         block = (CHAR64LONG16 *) workspace;
00608         os_memcpy(block, buffer, 64);
00609 #else
00610         block = (CHAR64LONG16 *) buffer;
00611 #endif
00612         /* Copy context->state[] to working vars */
00613         a = state[0];
00614         b = state[1];
00615         c = state[2];
00616         d = state[3];
00617         e = state[4];
00618         /* 4 rounds of 20 operations each. Loop unrolled. */
00619         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);
00620         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);
00621         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);
00622         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);
00623         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);
00624         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);
00625         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);
00626         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);
00627         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);
00628         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);
00629         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);
00630         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);
00631         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);
00632         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);
00633         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);
00634         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);
00635         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);
00636         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);
00637         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);
00638         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);
00639         /* Add the working vars back into context.state[] */
00640         state[0] += a;
00641         state[1] += b;
00642         state[2] += c;
00643         state[3] += d;
00644         state[4] += e;
00645         /* Wipe variables */
00646         a = b = c = d = e = 0;
00647 #ifdef SHA1HANDSOFF
00648         os_memset(block, 0, 64);
00649 #endif
00650 }
00651 
00652 
00653 /* SHA1Init - Initialize new context */
00654 
00655 void SHA1Init(SHA1_CTX* context)
00656 {
00657         /* SHA1 initialization constants */
00658         context->state[0] = 0x67452301;
00659         context->state[1] = 0xEFCDAB89;
00660         context->state[2] = 0x98BADCFE;
00661         context->state[3] = 0x10325476;
00662         context->state[4] = 0xC3D2E1F0;
00663         context->count[0] = context->count[1] = 0;
00664 }
00665 
00666 
00667 /* Run your data through this. */
00668 
00669 void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
00670 {
00671         u32 i, j;
00672         const unsigned char *data = _data;
00673 
00674 #ifdef VERBOSE
00675         SHAPrintContext(context, "before");
00676 #endif
00677         j = (context->count[0] >> 3) & 63;
00678         if ((context->count[0] += len << 3) < (len << 3))
00679                 context->count[1]++;
00680         context->count[1] += (len >> 29);
00681         if ((j + len) > 63) {
00682                 os_memcpy(&context->buffer[j], data, (i = 64-j));
00683                 SHA1Transform(context->state, context->buffer);
00684                 for ( ; i + 63 < len; i += 64) {
00685                         SHA1Transform(context->state, &data[i]);
00686                 }
00687                 j = 0;
00688         }
00689         else i = 0;
00690         os_memcpy(&context->buffer[j], &data[i], len - i);
00691 #ifdef VERBOSE
00692         SHAPrintContext(context, "after ");
00693 #endif
00694 }
00695 
00696 
00697 /* Add padding and return the message digest. */
00698 
00699 void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
00700 {
00701         u32 i;
00702         unsigned char finalcount[8];
00703 
00704         for (i = 0; i < 8; i++) {
00705                 finalcount[i] = (unsigned char)
00706                         ((context->count[(i >= 4 ? 0 : 1)] >>
00707                           ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
00708         }
00709         SHA1Update(context, (unsigned char *) "\200", 1);
00710         while ((context->count[0] & 504) != 448) {
00711                 SHA1Update(context, (unsigned char *) "\0", 1);
00712         }
00713         SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform()
00714                                               */
00715         for (i = 0; i < 20; i++) {
00716                 digest[i] = (unsigned char)
00717                         ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
00718                          255);
00719         }
00720         /* Wipe variables */
00721         i = 0;
00722         os_memset(context->buffer, 0, 64);
00723         os_memset(context->state, 0, 20);
00724         os_memset(context->count, 0, 8);
00725         os_memset(finalcount, 0, 8);
00726 }
00727 
00728 /* ===== end - public domain SHA1 implementation ===== */
00729 
00730 #endif /* INTERNAL_SHA1 */
00731 

Generated on Sun Dec 31 13:43:28 2006 for hostapd by  doxygen 1.4.2