]> pd.if.org Git - zpackage/blob - libtomcrypt/src/hashes/sha1.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / hashes / sha1.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include "tomcrypt.h"
10
11 /**
12   @file sha1.c
13   LTC_SHA1 code by Tom St Denis
14 */
15
16
17 #ifdef LTC_SHA1
18
19 const struct ltc_hash_descriptor sha1_desc =
20 {
21     "sha1",
22     2,
23     20,
24     64,
25
26     /* OID */
27    { 1, 3, 14, 3, 2, 26,  },
28    6,
29
30     &sha1_init,
31     &sha1_process,
32     &sha1_done,
33     &sha1_test,
34     NULL
35 };
36
37 #define F0(x,y,z)  (z ^ (x & (y ^ z)))
38 #define F1(x,y,z)  (x ^ y ^ z)
39 #define F2(x,y,z)  ((x & y) | (z & (x | y)))
40 #define F3(x,y,z)  (x ^ y ^ z)
41
42 #ifdef LTC_CLEAN_STACK
43 static int _sha1_compress(hash_state *md, unsigned char *buf)
44 #else
45 static int  sha1_compress(hash_state *md, unsigned char *buf)
46 #endif
47 {
48     ulong32 a,b,c,d,e,W[80],i;
49 #ifdef LTC_SMALL_CODE
50     ulong32 t;
51 #endif
52
53     /* copy the state into 512-bits into W[0..15] */
54     for (i = 0; i < 16; i++) {
55         LOAD32H(W[i], buf + (4*i));
56     }
57
58     /* copy state */
59     a = md->sha1.state[0];
60     b = md->sha1.state[1];
61     c = md->sha1.state[2];
62     d = md->sha1.state[3];
63     e = md->sha1.state[4];
64
65     /* expand it */
66     for (i = 16; i < 80; i++) {
67         W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
68     }
69
70     /* compress */
71     /* round one */
72     #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
73     #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
74     #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
75     #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
76
77 #ifdef LTC_SMALL_CODE
78
79     for (i = 0; i < 20; ) {
80        FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
81     }
82
83     for (; i < 40; ) {
84        FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
85     }
86
87     for (; i < 60; ) {
88        FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
89     }
90
91     for (; i < 80; ) {
92        FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
93     }
94
95 #else
96
97     for (i = 0; i < 20; ) {
98        FF0(a,b,c,d,e,i++);
99        FF0(e,a,b,c,d,i++);
100        FF0(d,e,a,b,c,i++);
101        FF0(c,d,e,a,b,i++);
102        FF0(b,c,d,e,a,i++);
103     }
104
105     /* round two */
106     for (; i < 40; )  {
107        FF1(a,b,c,d,e,i++);
108        FF1(e,a,b,c,d,i++);
109        FF1(d,e,a,b,c,i++);
110        FF1(c,d,e,a,b,i++);
111        FF1(b,c,d,e,a,i++);
112     }
113
114     /* round three */
115     for (; i < 60; )  {
116        FF2(a,b,c,d,e,i++);
117        FF2(e,a,b,c,d,i++);
118        FF2(d,e,a,b,c,i++);
119        FF2(c,d,e,a,b,i++);
120        FF2(b,c,d,e,a,i++);
121     }
122
123     /* round four */
124     for (; i < 80; )  {
125        FF3(a,b,c,d,e,i++);
126        FF3(e,a,b,c,d,i++);
127        FF3(d,e,a,b,c,i++);
128        FF3(c,d,e,a,b,i++);
129        FF3(b,c,d,e,a,i++);
130     }
131 #endif
132
133     #undef FF0
134     #undef FF1
135     #undef FF2
136     #undef FF3
137
138     /* store */
139     md->sha1.state[0] = md->sha1.state[0] + a;
140     md->sha1.state[1] = md->sha1.state[1] + b;
141     md->sha1.state[2] = md->sha1.state[2] + c;
142     md->sha1.state[3] = md->sha1.state[3] + d;
143     md->sha1.state[4] = md->sha1.state[4] + e;
144
145     return CRYPT_OK;
146 }
147
148 #ifdef LTC_CLEAN_STACK
149 static int sha1_compress(hash_state *md, unsigned char *buf)
150 {
151    int err;
152    err = _sha1_compress(md, buf);
153    burn_stack(sizeof(ulong32) * 87);
154    return err;
155 }
156 #endif
157
158 /**
159    Initialize the hash state
160    @param md   The hash state you wish to initialize
161    @return CRYPT_OK if successful
162 */
163 int sha1_init(hash_state * md)
164 {
165    LTC_ARGCHK(md != NULL);
166    md->sha1.state[0] = 0x67452301UL;
167    md->sha1.state[1] = 0xefcdab89UL;
168    md->sha1.state[2] = 0x98badcfeUL;
169    md->sha1.state[3] = 0x10325476UL;
170    md->sha1.state[4] = 0xc3d2e1f0UL;
171    md->sha1.curlen = 0;
172    md->sha1.length = 0;
173    return CRYPT_OK;
174 }
175
176 /**
177    Process a block of memory though the hash
178    @param md     The hash state
179    @param in     The data to hash
180    @param inlen  The length of the data (octets)
181    @return CRYPT_OK if successful
182 */
183 HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
184
185 /**
186    Terminate the hash to get the digest
187    @param md  The hash state
188    @param out [out] The destination of the hash (20 bytes)
189    @return CRYPT_OK if successful
190 */
191 int sha1_done(hash_state * md, unsigned char *out)
192 {
193     int i;
194
195     LTC_ARGCHK(md  != NULL);
196     LTC_ARGCHK(out != NULL);
197
198     if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
199        return CRYPT_INVALID_ARG;
200     }
201
202     /* increase the length of the message */
203     md->sha1.length += md->sha1.curlen * 8;
204
205     /* append the '1' bit */
206     md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
207
208     /* if the length is currently above 56 bytes we append zeros
209      * then compress.  Then we can fall back to padding zeros and length
210      * encoding like normal.
211      */
212     if (md->sha1.curlen > 56) {
213         while (md->sha1.curlen < 64) {
214             md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
215         }
216         sha1_compress(md, md->sha1.buf);
217         md->sha1.curlen = 0;
218     }
219
220     /* pad upto 56 bytes of zeroes */
221     while (md->sha1.curlen < 56) {
222         md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
223     }
224
225     /* store length */
226     STORE64H(md->sha1.length, md->sha1.buf+56);
227     sha1_compress(md, md->sha1.buf);
228
229     /* copy output */
230     for (i = 0; i < 5; i++) {
231         STORE32H(md->sha1.state[i], out+(4*i));
232     }
233 #ifdef LTC_CLEAN_STACK
234     zeromem(md, sizeof(hash_state));
235 #endif
236     return CRYPT_OK;
237 }
238
239 /**
240   Self-test the hash
241   @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
242 */
243 int  sha1_test(void)
244 {
245  #ifndef LTC_TEST
246     return CRYPT_NOP;
247  #else
248   static const struct {
249       const char *msg;
250       unsigned char hash[20];
251   } tests[] = {
252     { "abc",
253       { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
254         0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
255         0x9c, 0xd0, 0xd8, 0x9d }
256     },
257     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
258       { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
259         0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
260         0xE5, 0x46, 0x70, 0xF1 }
261     }
262   };
263
264   int i;
265   unsigned char tmp[20];
266   hash_state md;
267
268   for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0]));  i++) {
269       sha1_init(&md);
270       sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
271       sha1_done(&md, tmp);
272       if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) {
273          return CRYPT_FAIL_TESTVECTOR;
274       }
275   }
276   return CRYPT_OK;
277   #endif
278 }
279
280 #endif
281
282
283
284 /* ref:         $Format:%D$ */
285 /* git commit:  $Format:%H$ */
286 /* commit time: $Format:%ai$ */