Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / sshd / libtomcrypt / sha1.c
1 #include "mycrypt.h"
2
3 #ifdef SHA1
4
5 const struct _hash_descriptor sha1_desc =
6 {
7     "sha1",
8     2,
9     20,
10     64,
11     &sha1_init,
12     &sha1_process,
13     &sha1_done,
14     &sha1_test
15 };
16
17 #define F0(x,y,z)  (z ^ (x & (y ^ z)))
18 #define F1(x,y,z)  (x ^ y ^ z)
19 #define F2(x,y,z)  ((x & y) | (z & (x | y)))
20 #define F3(x,y,z)  (x ^ y ^ z)
21
22 #ifdef CLEAN_STACK
23 static void _sha1_compress(hash_state *md)
24 #else
25 static void sha1_compress(hash_state *md)
26 #endif
27 {
28     unsigned long a,b,c,d,e,W[80],i,j;
29
30     _ARGCHK(md != NULL);
31
32     /* copy the state into 512-bits into W[0..15] */
33     for (i = 0; i < 16; i++) {
34         LOAD32H(W[i], md->sha1.buf + (4*i));
35     }
36
37     /* copy state */
38     a = md->sha1.state[0];
39     b = md->sha1.state[1];
40     c = md->sha1.state[2];
41     d = md->sha1.state[3];
42     e = md->sha1.state[4];
43
44     /* expand it */
45     for (i = 16; i < 80; i++) {
46         j = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; 
47         W[i] = ROL(j, 1);
48     }
49
50
51     /* compress */
52     /* round one */
53     for (i = 0;  i < 20; i++)  { 
54         j = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); 
55         e = d; 
56         d = c; 
57         c = ROL(b, 30); 
58         b = a; 
59         a = j; 
60     }
61
62     /* round two */
63     for (i = 20; i < 40; i++)  { 
64         j = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); 
65         e = d; 
66         d = c; 
67         c = ROL(b, 30); 
68         b = a; 
69         a = j; 
70     }
71
72     /* round three */
73     for (i = 40; i < 60; i++)  { 
74         j = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); 
75         e = d; 
76         d = c; 
77         c = ROL(b, 30); 
78         b = a; 
79         a = j; 
80     }
81
82     /* round four */
83     for (i = 60; i < 80; i++)  { 
84         j = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL);
85         e = d;
86         d = c;
87         c = ROL(b, 30);
88         b = a;
89         a = j;
90     }
91
92     /* store */
93     md->sha1.state[0] = md->sha1.state[0] + a;
94     md->sha1.state[1] = md->sha1.state[1] + b;
95     md->sha1.state[2] = md->sha1.state[2] + c;
96     md->sha1.state[3] = md->sha1.state[3] + d;
97     md->sha1.state[4] = md->sha1.state[4] + e;
98 }
99
100 #ifdef CLEAN_STACK
101 static void sha1_compress(hash_state *md)
102 {
103    _sha1_compress(md);
104    burn_stack(sizeof(unsigned long) * 87);
105 }
106 #endif
107
108 void sha1_init(hash_state * md)
109 {
110    _ARGCHK(md != NULL);
111    md->sha1.state[0] = 0x67452301UL;
112    md->sha1.state[1] = 0xefcdab89UL;
113    md->sha1.state[2] = 0x98badcfeUL;
114    md->sha1.state[3] = 0x10325476UL;
115    md->sha1.state[4] = 0xc3d2e1f0UL;
116    md->sha1.curlen = 0;
117    md->sha1.length = 0;
118 }
119
120 void sha1_process(hash_state * md, const unsigned char *buf, unsigned long len)
121 {
122     unsigned long n;
123     _ARGCHK(md != NULL);
124     _ARGCHK(buf != NULL);
125
126     while (len > 0) {
127         n = MIN(len, (64 - md->sha1.curlen));
128         memcpy(md->sha1.buf + md->sha1.curlen, buf, (size_t)n);
129         md->sha1.curlen += n;
130         buf             += n;
131         len             -= n;
132
133         /* is 64 bytes full? */
134         if (md->sha1.curlen == 64) {
135             sha1_compress(md);
136             md->sha1.length += 512;
137             md->sha1.curlen = 0;
138         }
139     }
140 }
141
142 void sha1_done(hash_state * md, unsigned char *hash)
143 {
144     int i;
145
146     _ARGCHK(md != NULL);
147     _ARGCHK(hash != NULL);
148
149     /* increase the length of the message */
150     md->sha1.length += md->sha1.curlen * 8;
151
152     /* append the '1' bit */
153     md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
154
155     /* if the length is currently above 56 bytes we append zeros
156      * then compress.  Then we can fall back to padding zeros and length
157      * encoding like normal.
158      */
159     if (md->sha1.curlen > 56) {
160         while (md->sha1.curlen < 64) {
161             md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
162         }
163         sha1_compress(md);
164         md->sha1.curlen = 0;
165     }
166
167     /* pad upto 56 bytes of zeroes */
168     while (md->sha1.curlen < 56) {
169         md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
170     }
171
172     /* store length */
173     STORE64H(md->sha1.length, md->sha1.buf+56);
174     sha1_compress(md);
175
176     /* copy output */
177     for (i = 0; i < 5; i++) {
178         STORE32H(md->sha1.state[i], hash+(4*i));
179     }
180 #ifdef CLEAN_STACK
181     zeromem(md, sizeof(hash_state));
182 #endif
183 }
184
185 int  sha1_test(void)
186 {
187  #ifndef LTC_TEST
188     return CRYPT_NOP;
189  #else    
190   static const struct {
191       char *msg;
192       unsigned char hash[20];
193   } tests[] = {
194     { "abc",
195       { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
196         0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
197         0x9c, 0xd0, 0xd8, 0x9d }
198     },
199     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
200       { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
201         0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
202         0xE5, 0x46, 0x70, 0xF1 }
203     }
204   };
205
206   int i;
207   unsigned char tmp[20];
208   hash_state md;
209
210   for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0]));  i++) {
211       sha1_init(&md);
212       sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
213       sha1_done(&md, tmp);
214       if (memcmp(tmp, tests[i].hash, 20) != 0) {
215          return CRYPT_FAIL_TESTVECTOR;
216       }
217   }
218   return CRYPT_OK;
219   #endif
220 }
221
222 #endif
223
224