Updating ChangeLog for 4.22.10
[centerim.git] / libyahoo2 / sha1.c
blobd90b17bae9f5ff32e38a260852824030bdd7af22
1 /*-
2 * Copyright (c) 2001-2003 Allan Saddi <allan@saddi.com>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
28 * Define WORDS_BIGENDIAN if compiling on a big-endian architecture.
30 * Define SHA1_TEST to test the implementation using the NIST's
31 * sample messages. The output should be:
33 * a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
34 * 84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1
35 * 34aa973c d4c4daa4 f61eeb2b dbad2731 6534016f
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif /* HAVE_CONFIG_H */
42 #if HAVE_INTTYPES_H
43 # include <inttypes.h>
44 #else
45 # if HAVE_STDINT_H
46 # include <stdint.h>
47 # endif
48 #endif
50 #include <string.h>
52 #include "sha1.h"
54 #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
55 #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
57 #define F_0_19(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
58 #define F_20_39(x, y, z) ((x) ^ (y) ^ (z))
59 #define F_40_59(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
60 #define F_60_79(x, y, z) ((x) ^ (y) ^ (z))
62 #define DO_ROUND(F, K) { \
63 temp = ROTL(a, 5) + F(b, c, d) + e + *(W++) + K; \
64 e = d; \
65 d = c; \
66 c = ROTL(b, 30); \
67 b = a; \
68 a = temp; \
71 #define K_0_19 0x5a827999L
72 #define K_20_39 0x6ed9eba1L
73 #define K_40_59 0x8f1bbcdcL
74 #define K_60_79 0xca62c1d6L
76 #ifndef RUNTIME_ENDIAN
78 #ifdef WORDS_BIGENDIAN
80 #define BYTESWAP(x) (x)
81 #define BYTESWAP64(x) (x)
83 #else /* WORDS_BIGENDIAN */
85 #define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | (ROTL((x), 8) & 0x00ff00ffL))
87 static uint64_t _byteswap64(uint64_t x)
89 uint32_t a = x >> 32;
90 uint32_t b = (uint32_t) x;
91 return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
94 #define BYTESWAP64(x) _byteswap64(x)
96 #endif /* WORDS_BIGENDIAN */
98 #else /* !RUNTIME_ENDIAN */
100 #define BYTESWAP(x) _byteswap(sc->littleEndian, x)
101 #define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
103 #define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
104 (ROTL((x), 8) & 0x00ff00ffL))
105 #define _BYTESWAP64(x) __byteswap64(x)
107 static uint64_t __byteswap64(uint64_t x)
109 uint32_t a = x >> 32;
110 uint32_t b = (uint32_t) x;
111 return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
114 static uint32_t _byteswap(int littleEndian, uint32_t x)
116 if (!littleEndian)
117 return x;
118 else
119 return _BYTESWAP(x);
122 static uint64_t _byteswap64(int littleEndian, uint64_t x)
124 if (!littleEndian)
125 return x;
126 else
127 return _BYTESWAP64(x);
130 static void setEndian(int *littleEndianp)
132 union {
133 uint32_t w;
134 uint8_t b[4];
135 } endian;
137 endian.w = 1L;
138 *littleEndianp = endian.b[0] != 0;
141 #endif /* !RUNTIME_ENDIAN */
143 static const uint8_t padding[64] = {
144 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
154 void SHA1Init(SHA1Context *sc)
156 #ifdef RUNTIME_ENDIAN
157 setEndian(&sc->littleEndian);
158 #endif /* RUNTIME_ENDIAN */
160 sc->totalLength = 0LL;
161 sc->hash[0] = 0x67452301L;
162 sc->hash[1] = 0xefcdab89L;
163 sc->hash[2] = 0x98badcfeL;
164 sc->hash[3] = 0x10325476L;
165 sc->hash[4] = 0xc3d2e1f0L;
166 sc->bufferLength = 0L;
169 static void burnStack(int size)
171 char buf[128];
173 memset(buf, 0, sizeof(buf));
174 size -= sizeof(buf);
175 if (size > 0)
176 burnStack(size);
179 static void SHA1Guts(SHA1Context *sc, const uint32_t *cbuf)
181 uint32_t buf[80];
182 uint32_t *W, *W3, *W8, *W14, *W16;
183 uint32_t a, b, c, d, e, temp;
184 int i;
186 W = buf;
188 for (i = 15; i >= 0; i--) {
189 *(W++) = BYTESWAP(*cbuf);
190 cbuf++;
193 W16 = &buf[0];
194 W14 = &buf[2];
195 W8 = &buf[8];
196 W3 = &buf[13];
198 for (i = 63; i >= 0; i--) {
199 *W = *(W3++) ^ *(W8++) ^ *(W14++) ^ *(W16++);
200 *W = ROTL(*W, 1);
201 W++;
204 a = sc->hash[0];
205 b = sc->hash[1];
206 c = sc->hash[2];
207 d = sc->hash[3];
208 e = sc->hash[4];
210 W = buf;
212 #ifndef SHA1_UNROLL
213 #define SHA1_UNROLL 20
214 #endif /* !SHA1_UNROLL */
216 #if SHA1_UNROLL == 1
217 for (i = 19; i >= 0; i--)
218 DO_ROUND(F_0_19, K_0_19);
220 for (i = 19; i >= 0; i--)
221 DO_ROUND(F_20_39, K_20_39);
223 for (i = 19; i >= 0; i--)
224 DO_ROUND(F_40_59, K_40_59);
226 for (i = 19; i >= 0; i--)
227 DO_ROUND(F_60_79, K_60_79);
228 #elif SHA1_UNROLL == 2
229 for (i = 9; i >= 0; i--) {
230 DO_ROUND(F_0_19, K_0_19);
231 DO_ROUND(F_0_19, K_0_19);
234 for (i = 9; i >= 0; i--) {
235 DO_ROUND(F_20_39, K_20_39);
236 DO_ROUND(F_20_39, K_20_39);
239 for (i = 9; i >= 0; i--) {
240 DO_ROUND(F_40_59, K_40_59);
241 DO_ROUND(F_40_59, K_40_59);
244 for (i = 9; i >= 0; i--) {
245 DO_ROUND(F_60_79, K_60_79);
246 DO_ROUND(F_60_79, K_60_79);
248 #elif SHA1_UNROLL == 4
249 for (i = 4; i >= 0; i--) {
250 DO_ROUND(F_0_19, K_0_19);
251 DO_ROUND(F_0_19, K_0_19);
252 DO_ROUND(F_0_19, K_0_19);
253 DO_ROUND(F_0_19, K_0_19);
256 for (i = 4; i >= 0; i--) {
257 DO_ROUND(F_20_39, K_20_39);
258 DO_ROUND(F_20_39, K_20_39);
259 DO_ROUND(F_20_39, K_20_39);
260 DO_ROUND(F_20_39, K_20_39);
263 for (i = 4; i >= 0; i--) {
264 DO_ROUND(F_40_59, K_40_59);
265 DO_ROUND(F_40_59, K_40_59);
266 DO_ROUND(F_40_59, K_40_59);
267 DO_ROUND(F_40_59, K_40_59);
270 for (i = 4; i >= 0; i--) {
271 DO_ROUND(F_60_79, K_60_79);
272 DO_ROUND(F_60_79, K_60_79);
273 DO_ROUND(F_60_79, K_60_79);
274 DO_ROUND(F_60_79, K_60_79);
276 #elif SHA1_UNROLL == 5
277 for (i = 3; i >= 0; i--) {
278 DO_ROUND(F_0_19, K_0_19);
279 DO_ROUND(F_0_19, K_0_19);
280 DO_ROUND(F_0_19, K_0_19);
281 DO_ROUND(F_0_19, K_0_19);
282 DO_ROUND(F_0_19, K_0_19);
285 for (i = 3; i >= 0; i--) {
286 DO_ROUND(F_20_39, K_20_39);
287 DO_ROUND(F_20_39, K_20_39);
288 DO_ROUND(F_20_39, K_20_39);
289 DO_ROUND(F_20_39, K_20_39);
290 DO_ROUND(F_20_39, K_20_39);
293 for (i = 3; i >= 0; i--) {
294 DO_ROUND(F_40_59, K_40_59);
295 DO_ROUND(F_40_59, K_40_59);
296 DO_ROUND(F_40_59, K_40_59);
297 DO_ROUND(F_40_59, K_40_59);
298 DO_ROUND(F_40_59, K_40_59);
301 for (i = 3; i >= 0; i--) {
302 DO_ROUND(F_60_79, K_60_79);
303 DO_ROUND(F_60_79, K_60_79);
304 DO_ROUND(F_60_79, K_60_79);
305 DO_ROUND(F_60_79, K_60_79);
306 DO_ROUND(F_60_79, K_60_79);
308 #elif SHA1_UNROLL == 10
309 for (i = 1; i >= 0; i--) {
310 DO_ROUND(F_0_19, K_0_19);
311 DO_ROUND(F_0_19, K_0_19);
312 DO_ROUND(F_0_19, K_0_19);
313 DO_ROUND(F_0_19, K_0_19);
314 DO_ROUND(F_0_19, K_0_19);
315 DO_ROUND(F_0_19, K_0_19);
316 DO_ROUND(F_0_19, K_0_19);
317 DO_ROUND(F_0_19, K_0_19);
318 DO_ROUND(F_0_19, K_0_19);
319 DO_ROUND(F_0_19, K_0_19);
322 for (i = 1; i >= 0; i--) {
323 DO_ROUND(F_20_39, K_20_39);
324 DO_ROUND(F_20_39, K_20_39);
325 DO_ROUND(F_20_39, K_20_39);
326 DO_ROUND(F_20_39, K_20_39);
327 DO_ROUND(F_20_39, K_20_39);
328 DO_ROUND(F_20_39, K_20_39);
329 DO_ROUND(F_20_39, K_20_39);
330 DO_ROUND(F_20_39, K_20_39);
331 DO_ROUND(F_20_39, K_20_39);
332 DO_ROUND(F_20_39, K_20_39);
335 for (i = 1; i >= 0; i--) {
336 DO_ROUND(F_40_59, K_40_59);
337 DO_ROUND(F_40_59, K_40_59);
338 DO_ROUND(F_40_59, K_40_59);
339 DO_ROUND(F_40_59, K_40_59);
340 DO_ROUND(F_40_59, K_40_59);
341 DO_ROUND(F_40_59, K_40_59);
342 DO_ROUND(F_40_59, K_40_59);
343 DO_ROUND(F_40_59, K_40_59);
344 DO_ROUND(F_40_59, K_40_59);
345 DO_ROUND(F_40_59, K_40_59);
348 for (i = 1; i >= 0; i--) {
349 DO_ROUND(F_60_79, K_60_79);
350 DO_ROUND(F_60_79, K_60_79);
351 DO_ROUND(F_60_79, K_60_79);
352 DO_ROUND(F_60_79, K_60_79);
353 DO_ROUND(F_60_79, K_60_79);
354 DO_ROUND(F_60_79, K_60_79);
355 DO_ROUND(F_60_79, K_60_79);
356 DO_ROUND(F_60_79, K_60_79);
357 DO_ROUND(F_60_79, K_60_79);
358 DO_ROUND(F_60_79, K_60_79);
360 #elif SHA1_UNROLL == 20
361 DO_ROUND(F_0_19, K_0_19);
362 DO_ROUND(F_0_19, K_0_19);
363 DO_ROUND(F_0_19, K_0_19);
364 DO_ROUND(F_0_19, K_0_19);
365 DO_ROUND(F_0_19, K_0_19);
366 DO_ROUND(F_0_19, K_0_19);
367 DO_ROUND(F_0_19, K_0_19);
368 DO_ROUND(F_0_19, K_0_19);
369 DO_ROUND(F_0_19, K_0_19);
370 DO_ROUND(F_0_19, K_0_19);
371 DO_ROUND(F_0_19, K_0_19);
372 DO_ROUND(F_0_19, K_0_19);
373 DO_ROUND(F_0_19, K_0_19);
374 DO_ROUND(F_0_19, K_0_19);
375 DO_ROUND(F_0_19, K_0_19);
376 DO_ROUND(F_0_19, K_0_19);
377 DO_ROUND(F_0_19, K_0_19);
378 DO_ROUND(F_0_19, K_0_19);
379 DO_ROUND(F_0_19, K_0_19);
380 DO_ROUND(F_0_19, K_0_19);
382 DO_ROUND(F_20_39, K_20_39);
383 DO_ROUND(F_20_39, K_20_39);
384 DO_ROUND(F_20_39, K_20_39);
385 DO_ROUND(F_20_39, K_20_39);
386 DO_ROUND(F_20_39, K_20_39);
387 DO_ROUND(F_20_39, K_20_39);
388 DO_ROUND(F_20_39, K_20_39);
389 DO_ROUND(F_20_39, K_20_39);
390 DO_ROUND(F_20_39, K_20_39);
391 DO_ROUND(F_20_39, K_20_39);
392 DO_ROUND(F_20_39, K_20_39);
393 DO_ROUND(F_20_39, K_20_39);
394 DO_ROUND(F_20_39, K_20_39);
395 DO_ROUND(F_20_39, K_20_39);
396 DO_ROUND(F_20_39, K_20_39);
397 DO_ROUND(F_20_39, K_20_39);
398 DO_ROUND(F_20_39, K_20_39);
399 DO_ROUND(F_20_39, K_20_39);
400 DO_ROUND(F_20_39, K_20_39);
401 DO_ROUND(F_20_39, K_20_39);
403 DO_ROUND(F_40_59, K_40_59);
404 DO_ROUND(F_40_59, K_40_59);
405 DO_ROUND(F_40_59, K_40_59);
406 DO_ROUND(F_40_59, K_40_59);
407 DO_ROUND(F_40_59, K_40_59);
408 DO_ROUND(F_40_59, K_40_59);
409 DO_ROUND(F_40_59, K_40_59);
410 DO_ROUND(F_40_59, K_40_59);
411 DO_ROUND(F_40_59, K_40_59);
412 DO_ROUND(F_40_59, K_40_59);
413 DO_ROUND(F_40_59, K_40_59);
414 DO_ROUND(F_40_59, K_40_59);
415 DO_ROUND(F_40_59, K_40_59);
416 DO_ROUND(F_40_59, K_40_59);
417 DO_ROUND(F_40_59, K_40_59);
418 DO_ROUND(F_40_59, K_40_59);
419 DO_ROUND(F_40_59, K_40_59);
420 DO_ROUND(F_40_59, K_40_59);
421 DO_ROUND(F_40_59, K_40_59);
422 DO_ROUND(F_40_59, K_40_59);
424 DO_ROUND(F_60_79, K_60_79);
425 DO_ROUND(F_60_79, K_60_79);
426 DO_ROUND(F_60_79, K_60_79);
427 DO_ROUND(F_60_79, K_60_79);
428 DO_ROUND(F_60_79, K_60_79);
429 DO_ROUND(F_60_79, K_60_79);
430 DO_ROUND(F_60_79, K_60_79);
431 DO_ROUND(F_60_79, K_60_79);
432 DO_ROUND(F_60_79, K_60_79);
433 DO_ROUND(F_60_79, K_60_79);
434 DO_ROUND(F_60_79, K_60_79);
435 DO_ROUND(F_60_79, K_60_79);
436 DO_ROUND(F_60_79, K_60_79);
437 DO_ROUND(F_60_79, K_60_79);
438 DO_ROUND(F_60_79, K_60_79);
439 DO_ROUND(F_60_79, K_60_79);
440 DO_ROUND(F_60_79, K_60_79);
441 DO_ROUND(F_60_79, K_60_79);
442 DO_ROUND(F_60_79, K_60_79);
443 DO_ROUND(F_60_79, K_60_79);
444 #else /* SHA1_UNROLL */
445 #error SHA1_UNROLL must be 1, 2, 4, 5, 10 or 20!
446 #endif
448 sc->hash[0] += a;
449 sc->hash[1] += b;
450 sc->hash[2] += c;
451 sc->hash[3] += d;
452 sc->hash[4] += e;
455 void SHA1Update(SHA1Context *sc, const void *vdata, uint32_t len)
457 const uint8_t *data = vdata;
458 uint32_t bufferBytesLeft;
459 uint32_t bytesToCopy;
460 int needBurn = 0;
462 #ifdef SHA1_FAST_COPY
463 if (sc->bufferLength) {
464 bufferBytesLeft = 64L - sc->bufferLength;
466 bytesToCopy = bufferBytesLeft;
467 if (bytesToCopy > len)
468 bytesToCopy = len;
470 memcpy(&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
472 sc->totalLength += bytesToCopy * 8L;
474 sc->bufferLength += bytesToCopy;
475 data += bytesToCopy;
476 len -= bytesToCopy;
478 if (sc->bufferLength == 64L) {
479 SHA1Guts(sc, sc->buffer.words);
480 needBurn = 1;
481 sc->bufferLength = 0L;
485 while (len > 63) {
486 sc->totalLength += 512L;
488 SHA1Guts(sc, data);
489 needBurn = 1;
491 data += 64L;
492 len -= 64L;
495 if (len) {
496 memcpy(&sc->buffer.bytes[sc->bufferLength], data, len);
498 sc->totalLength += len * 8L;
500 sc->bufferLength += len;
502 #else /* SHA1_FAST_COPY */
503 while (len) {
504 bufferBytesLeft = 64L - sc->bufferLength;
506 bytesToCopy = bufferBytesLeft;
507 if (bytesToCopy > len)
508 bytesToCopy = len;
510 memcpy(&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
512 sc->totalLength += bytesToCopy * 8L;
514 sc->bufferLength += bytesToCopy;
515 data += bytesToCopy;
516 len -= bytesToCopy;
518 if (sc->bufferLength == 64L) {
519 SHA1Guts(sc, sc->buffer.words);
520 needBurn = 1;
521 sc->bufferLength = 0L;
524 #endif /* SHA1_FAST_COPY */
526 if (needBurn)
527 burnStack(sizeof(uint32_t[86]) + sizeof(uint32_t *[5]) +
528 sizeof(int));
531 void SHA1Final(SHA1Context *sc, uint8_t hash[SHA1_HASH_SIZE])
533 uint32_t bytesToPad;
534 uint64_t lengthPad;
535 int i;
537 bytesToPad = 120L - sc->bufferLength;
538 if (bytesToPad > 64L)
539 bytesToPad -= 64L;
541 lengthPad = BYTESWAP64(sc->totalLength);
543 SHA1Update(sc, padding, bytesToPad);
544 SHA1Update(sc, &lengthPad, 8L);
546 if (hash) {
547 for (i = 0; i < SHA1_HASH_WORDS; i++) {
548 #ifdef SHA1_FAST_COPY
549 *((uint32_t *)hash) = BYTESWAP(sc->hash[i]);
550 #else /* SHA1_FAST_COPY */
551 hash[0] = (uint8_t) (sc->hash[i] >> 24);
552 hash[1] = (uint8_t) (sc->hash[i] >> 16);
553 hash[2] = (uint8_t) (sc->hash[i] >> 8);
554 hash[3] = (uint8_t) sc->hash[i];
555 #endif /* SHA1_FAST_COPY */
556 hash += 4;
561 #ifdef SHA1_TEST
563 #include <stdio.h>
564 #include <stdlib.h>
565 #include <string.h>
567 int main(int argc, char *argv[])
569 SHA1Context foo;
570 uint8_t hash[SHA1_HASH_SIZE];
571 char buf[1000];
572 int i;
574 SHA1Init(&foo);
575 SHA1Update(&foo, "abc", 3);
576 SHA1Final(&foo, hash);
578 for (i = 0; i < SHA1_HASH_SIZE;) {
579 printf("%02x", hash[i++]);
580 if (!(i % 4))
581 printf(" ");
583 printf("\n");
585 SHA1Init(&foo);
586 SHA1Update(&foo,
587 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
588 SHA1Final(&foo, hash);
590 for (i = 0; i < SHA1_HASH_SIZE;) {
591 printf("%02x", hash[i++]);
592 if (!(i % 4))
593 printf(" ");
595 printf("\n");
597 SHA1Init(&foo);
598 memset(buf, 'a', sizeof(buf));
599 for (i = 0; i < 1000; i++)
600 SHA1Update(&foo, buf, sizeof(buf));
601 SHA1Final(&foo, hash);
603 for (i = 0; i < SHA1_HASH_SIZE;) {
604 printf("%02x", hash[i++]);
605 if (!(i % 4))
606 printf(" ");
608 printf("\n");
610 exit(0);
613 #endif /* SHA1_TEST */