1f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/*
2f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comSHA-1 in C
3f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comBy Steve Reid <sreid@sea-to-sky.net>
4f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com100% Public Domain
5f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
6f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com-----------------
7f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comModified 7/98
8f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comBy James H. Brown <jbrown@burgoyne.com>
9f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comStill 100% Public Domain
10f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
11f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comCorrected a problem which generated improper hash values on 16 bit machines
12f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comRoutine SHA1Update changed from
13f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
14f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comlen)
15f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comto
16f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
17f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comlong len)
18f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
19f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comThe 'len' parameter was declared an int which works fine on 32 bit machines.
20f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comHowever, on 16 bit machines an int is too small for the shifts being done
21f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comagainst
22f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comit.  This caused the hash function to generate incorrect values if len was
23f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comgreater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
24f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
25f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comSince the file IO in main() reads 16K at a time, any file 8K or larger would
26f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.combe guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
27f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com"a"s).
28f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
29f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comI also changed the declaration of variables i & j in SHA1Update to
30f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comunsigned long from unsigned int for the same reason.
31f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
32f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comThese changes should make no difference to any 32 bit implementations since
33f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.coman
34f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comint and a long are the same size in those environments.
35f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
36f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com--
37f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comI also corrected a few compiler warnings generated by Borland C.
38f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com1. Added #include <process.h> for exit() prototype
39f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com2. Removed unused variable 'j' in SHA1Final
40f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com3. Changed exit(0) to return(0) at end of main.
41f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
42f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comALL changes I made can be located by searching for comments containing 'JHB'
43f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com-----------------
44f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comModified 8/98
45f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comBy Steve Reid <sreid@sea-to-sky.net>
46f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comStill 100% public domain
47f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
48f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com1- Removed #include <process.h> and used return() instead of exit()
49f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
50f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
51f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
52f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com-----------------
53f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comModified 4/01
54f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comBy Saul Kravitz <Saul.Kravitz@celera.com>
55f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comStill 100% PD
56f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comModified to run on Compaq Alpha hardware.
57f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
58f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com-----------------
59f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comModified 07/2002
60f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comBy Ralph Giles <giles@ghostscript.com>
61f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comStill 100% public domain
62f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.commodified for use with stdint types, autoconf
63f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comcode cleanup, removed attribution comments
64f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comswitched SHA1Final() argument order for consistency
65f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comuse SHA1_ prefix for public api
66f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.commove public api to sha1.h
67f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com*/
68f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
69f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/*
70f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comTest Vectors (from FIPS PUB 180-1)
71f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com"abc"
72f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
73f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
74f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
75f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comA million repetitions of "a"
76f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
77f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com*/
78f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
79f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#include <stdio.h>
80f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#include <string.h>
81f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#include <stdlib.h>
82f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
83f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#include "sha1.h"
84f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
85f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#if defined(_MSC_VER)
86f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#pragma warning(disable : 4267)
87f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#pragma warning(disable : 4996)
88f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#pragma warning(disable : 4100)
89f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#endif
90f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
91f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
92f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
93f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define rol ROTL32
94f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
95f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* blk0() and blk() perform the initial expand. */
96f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* I got the idea of expanding during the round function from SSLeay */
97f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* FIXME: can we do this in an endian-proof way? */
98f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
99f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#ifdef WORDS_BIGENDIAN
100f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define blk0(i) block->l[i]
101f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#else
102f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) | (rol(block->l[i],8)&0x00FF00FF))
103f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#endif
104f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] ^ block->l[(i+2)&15]^block->l[i&15],1))
105f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
106f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
107f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
108f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
109f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
110f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
111f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
112f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
113f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
114f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* Hash a single 512-bit block. This is the core of the algorithm. */
115f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
116f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
117f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    uint32_t a, b, c, d, e;
118f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    typedef union {
119f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        uint8_t c[64];
120f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        uint32_t l[16];
121f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    } CHAR64LONG16;
122f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    CHAR64LONG16* block;
123f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
124f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    block = (CHAR64LONG16*)buffer;
125f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
126f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    /* Copy context->state[] to working vars */
127f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    a = state[0];
128f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    b = state[1];
129f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    c = state[2];
130f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    d = state[3];
131f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    e = state[4];
132f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
133f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    /* 4 rounds of 20 operations each. Loop unrolled. */
134f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
135f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
136f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
137f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
138f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
139f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
140f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
141f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
142f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
143f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
144f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
145f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
146f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
147f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
148f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
149f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
150f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
151f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
152f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
153f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    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);
154f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
155f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    /* Add the working vars back into context.state[] */
156f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    state[0] += a;
157f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    state[1] += b;
158f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    state[2] += c;
159f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    state[3] += d;
160f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    state[4] += e;
161f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
162f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    /* Wipe variables */
163f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    a = b = c = d = e = 0;
164f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
165f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
166f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
167f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* SHA1Init - Initialize new context */
168f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid SHA1_Init(SHA1_CTX* context)
169f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
170f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    /* SHA1 initialization constants */
171f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    context->state[0] = 0x67452301;
172f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    context->state[1] = 0xEFCDAB89;
173f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    context->state[2] = 0x98BADCFE;
174f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    context->state[3] = 0x10325476;
175f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    context->state[4] = 0xC3D2E1F0;
176f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    context->count[0] = 0;
177f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  context->count[1] = 0;
178f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
179f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
180f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
181f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* Run your data through this. */
182f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
183f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
184f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    size_t i, j;
185f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
186f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    j = (context->count[0] >> 3) & 63;
187f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
188f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
189f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    context->count[1] += (len >> 29);
190f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
191f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    if ((j + len) > 63)
192f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  {
193f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        memcpy(&context->buffer[j], data, (i = 64-j));
194f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        SHA1_Transform(context->state, context->buffer);
195f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
196f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        for ( ; i + 63 < len; i += 64)
197f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    {
198f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com            SHA1_Transform(context->state, data + i);
199f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        }
200f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
201f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        j = 0;
202f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    }
203f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    else i = 0;
204f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    memcpy(&context->buffer[j], &data[i], len - i);
205f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
206f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
207f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
208f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* Add padding and return the message digest. */
209f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
210f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
211f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    uint32_t i;
212f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    uint8_t  finalcount[8];
213f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
214f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    for (i = 0; i < 8; i++) {
215f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
216f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
217f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    }
218f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    SHA1_Update(context, (uint8_t *)"\200", 1);
219f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    while ((context->count[0] & 504) != 448) {
220f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        SHA1_Update(context, (uint8_t *)"\0", 1);
221f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    }
222f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1_Transform() */
223f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
224f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        digest[i] = (uint8_t)
225f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
226f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    }
227f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
228f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    /* Wipe variables */
229f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    i = 0;
230f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    memset(context->buffer, 0, 64);
231f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    memset(context->state, 0, 20);
232f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    memset(context->count, 0, 8);
233f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    memset(finalcount, 0, 8);	/* SWR */
234f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
235f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
236f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com//-----------------------------------------------------------------------------
237f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
238f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid sha1_32a ( const void * key, int len, uint32_t seed, void * out )
239f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
240f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  SHA1_CTX context;
241f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
242f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  uint8_t digest[20];
243f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
244f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  SHA1_Init(&context);
245f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  SHA1_Update(&context, (uint8_t*)key, len);
246f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  SHA1_Final(&context, digest);
247f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
248f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  memcpy(out,&digest[0],4);
249f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
250f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
251f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com//-----------------------------------------------------------------------------
252f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com// self test
253f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
254f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com//#define TEST
255f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
256f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#ifdef TEST
257f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
258f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comstatic char *test_data[] = {
259f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    "abc",
260f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
261f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    "A million repetitions of 'a'"};
262f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comstatic char *test_results[] = {
263f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
264f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
265f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"};
266f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
267f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
268f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output)
269f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
270f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    int i,j;
271f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    char *c = output;
272f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
273f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
274f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        for (j = 0; j < 4; j++) {
275f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com            sprintf(c,"%02X", digest[i*4+j]);
276f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com            c += 2;
277f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        }
278f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        sprintf(c, " ");
279f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        c += 1;
280f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    }
281f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    *(c - 1) = '\0';
282f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
283f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
284f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comint main(int argc, char** argv)
285f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
286f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    int k;
287f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    SHA1_CTX context;
288f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    uint8_t digest[20];
289f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    char output[80];
290f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
291f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    fprintf(stdout, "verifying SHA-1 implementation... ");
292f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
293f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    for (k = 0; k < 2; k++){
294f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        SHA1_Init(&context);
295f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k]));
296f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        SHA1_Final(&context, digest);
297f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  digest_to_hex(digest, output);
298f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
299f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        if (strcmp(output, test_results[k])) {
300f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com            fprintf(stdout, "FAIL\n");
301f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com            fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]);
302f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com            fprintf(stderr,"\t%s returned\n", output);
303f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com            fprintf(stderr,"\t%s is correct\n", test_results[k]);
304f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com            return (1);
305f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        }
306f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    }
307f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    /* million 'a' vector we feed separately */
308f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    SHA1_Init(&context);
309f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    for (k = 0; k < 1000000; k++)
310f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        SHA1_Update(&context, (uint8_t*)"a", 1);
311f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    SHA1_Final(&context, digest);
312f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    digest_to_hex(digest, output);
313f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    if (strcmp(output, test_results[2])) {
314f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        fprintf(stdout, "FAIL\n");
315f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]);
316f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        fprintf(stderr,"\t%s returned\n", output);
317f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        fprintf(stderr,"\t%s is correct\n", test_results[2]);
318f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        return (1);
319f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    }
320f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
321f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    /* success */
322f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    fprintf(stdout, "ok\n");
323f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    return(0);
324f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
325f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#endif /* TEST */
326