Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / icedax / sha_func.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)sha_func.c       1.3 01/10/27 Copyright 1998,1999 Heiko Eissfeldt */
14 /*____________________________________________________________________________
15 //
16 //   CD Index - The Internet CD Index
17 //
18 //   This program is free software; you can redistribute it and/or modify
19 //   it under the terms of the GNU General Public License as published by
20 //   the Free Software Foundation; either version 2 of the License, or
21 //   (at your option) any later version.
22 //
23 //   This program is distributed in the hope that it will be useful,
24 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
25 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 //   GNU General Public License for more details.
27 //
28 //   You should have received a copy of the GNU General Public License
29 //   along with this program; if not, write to the Free Software
30 //   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 //
32 //   $Id: sha_func.c,v 1.2 1999/06/04 14:10:07 marc Exp $
33 //____________________________________________________________________________
34 */
35 /* NIST Secure Hash Algorithm */
36
37 /* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */
38 /* from Peter C. Gutmann's implementation as found in */
39 /* Applied Cryptography by Bruce Schneier */
40 /* Further modifications to include the "UNRAVEL" stuff, below */
41 /* portability modifications Heiko Eissfeldt */
42
43 /* This code is in the public domain */
44
45 #include "config.h"
46 #include <strdefs.h>
47 #include "sha.h"
48
49 /* UNRAVEL should be fastest & biggest */
50 /* UNROLL_LOOPS should be just as big, but slightly slower */
51 /* both undefined should be smallest and slowest */
52
53 #define UNRAVEL
54 /* #define UNROLL_LOOPS */
55
56 /* SHA f()-functions */
57
58 #define f1(x,y,z)       ((x & y) | (~x & z))
59 #define f2(x,y,z)       (x ^ y ^ z)
60 #define f3(x,y,z)       ((x & y) | (x & z) | (y & z))
61 #define f4(x,y,z)       (x ^ y ^ z)
62
63 /* SHA constants */
64
65 #define CONST1          ULONG_C(0x5a827999)
66 #define CONST2          ULONG_C(0x6ed9eba1)
67 #define CONST3          ULONG_C(0x8f1bbcdc)
68 #define CONST4          ULONG_C(0xca62c1d6)
69
70 /* truncate to 32 bits -- should be a null op on 32-bit machines */
71
72 #define T32(x)  ((x) & ULONG_C(0xffffffff))
73
74 /* 32-bit rotate */
75
76 #define R32(x,n)        T32(((x << n) | (x >> (32 - n))))
77
78 /* the generic case, for when the overall rotation is not unraveled */
79
80 #define FG(n)   \
81     T = T32(R32(A,5) + CONCAT(f,n(B,C,D)) + E + *WP++ + CONCAT(CONST,n));       \
82     E = D; D = C; C = R32(B,30); B = A; A = T
83
84 /* specific cases, for when the overall rotation is unraveled */
85
86 #define FA(n)   \
87     T = T32(R32(A,5) + CONCAT(f,n(B,C,D)) + E + *WP++ + CONCAT(CONST,n)); B = R32(B,30)
88
89 #define FB(n)   \
90     E = T32(R32(T,5) + CONCAT(f,n(A,B,C)) + D + *WP++ + CONCAT(CONST,n)); A = R32(A,30)
91
92 #define FC(n)   \
93     D = T32(R32(E,5) + CONCAT(f,n(T,A,B)) + C + *WP++ + CONCAT(CONST,n)); T = R32(T,30)
94
95 #define FD(n)   \
96     C = T32(R32(D,5) + CONCAT(f,n(E,T,A)) + B + *WP++ + CONCAT(CONST,n)); E = R32(E,30)
97
98 #define FE(n)   \
99     B = T32(R32(C,5) + CONCAT(f,n(D,E,T)) + A + *WP++ + CONCAT(CONST,n)); D = R32(D,30)
100
101 #define FT(n)   \
102     A = T32(R32(B,5) + CONCAT(f,n(C,D,E)) + T + *WP++ + CONCAT(CONST,n)); C = R32(C,30)
103
104 /* do SHA transformation */
105
106 static void sha_transform(SHA_INFO *sha_info);
107
108 static void sha_transform(SHA_INFO *sha_info)
109 {
110     int i;
111     BYTE *dp;
112     ULONG T, A, B, C, D, E, W[80], *WP;
113
114     dp = sha_info->data;
115
116 /*
117 the following makes sure that at least one code block below is
118 traversed or an error is reported, without the necessity for nested
119 preprocessor if/else/endif blocks, which are a great pain in the
120 nether regions of the anatomy...
121 */
122 #undef SWAP_DONE
123
124 #if (SHA_BYTE_ORDER == 1234)
125 #define SWAP_DONE
126     for (i = 0; i < 16; ++i) {
127         T = *((ULONG *) dp);
128         dp += 4;
129         W[i] =  ((T << 24) & ULONG_C(0xff000000)) | ((T <<  8) & ULONG_C(0x00ff0000)) |
130                 ((T >>  8) & ULONG_C(0x0000ff00)) | ((T >> 24) & ULONG_C(0x000000ff));
131     }
132 #endif /* SHA_BYTE_ORDER == 1234 */
133
134 #if (SHA_BYTE_ORDER == 4321)
135 #define SWAP_DONE
136     for (i = 0; i < 16; ++i) {
137         T = *((ULONG *) dp);
138         dp += 4;
139         W[i] = T32(T);
140     }
141 #endif /* SHA_BYTE_ORDER == 4321 */
142
143 #if (SHA_BYTE_ORDER == 12345678)
144 #define SWAP_DONE
145     for (i = 0; i < 16; i += 2) {
146         T = *((ULONG *) dp);
147         dp += 8;
148         W[i] =  ((T << 24) & ULONG_C(0xff000000)) | ((T <<  8) & ULONG_C(0x00ff0000)) |
149                 ((T >>  8) & ULONG_C(0x0000ff00)) | ((T >> 24) & ULONG_C(0x000000ff));
150         T >>= 32;
151         W[i+1] = ((T << 24) & ULONG_C(0xff000000)) | ((T <<  8) & ULONG_C(0x00ff0000)) |
152                  ((T >>  8) & ULONG_C(0x0000ff00)) | ((T >> 24) & ULONG_C(0x000000ff));
153     }
154 #endif /* SHA_BYTE_ORDER == 12345678 */
155
156 #if (SHA_BYTE_ORDER == 87654321)
157 #define SWAP_DONE
158     for (i = 0; i < 16; i += 2) {
159         T = *((ULONG *) dp);
160         dp += 8;
161         W[i] = T32(T >> 32);
162         W[i+1] = T32(T);
163     }
164 #endif /* SHA_BYTE_ORDER == 87654321 */
165
166 #ifndef SWAP_DONE
167 error Unknown byte order -- you need to add code here
168 #endif /* SWAP_DONE */
169
170     for (i = 16; i < 80; ++i) {
171         W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
172 #if (SHA_VERSION == 1)
173         W[i] = R32(W[i], 1);
174 #endif /* SHA_VERSION */
175     }
176     A = sha_info->digest[0];
177     B = sha_info->digest[1];
178     C = sha_info->digest[2];
179     D = sha_info->digest[3];
180     E = sha_info->digest[4];
181     WP = W;
182 #ifdef UNRAVEL
183     FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
184     FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
185     FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
186     FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
187     FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
188     FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
189     FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
190     FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
191     sha_info->digest[0] = T32(sha_info->digest[0] + E);
192     sha_info->digest[1] = T32(sha_info->digest[1] + T);
193     sha_info->digest[2] = T32(sha_info->digest[2] + A);
194     sha_info->digest[3] = T32(sha_info->digest[3] + B);
195     sha_info->digest[4] = T32(sha_info->digest[4] + C);
196 #else /* !UNRAVEL */
197 #ifdef UNROLL_LOOPS
198     FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
199     FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
200     FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
201     FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
202     FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
203     FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
204     FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
205     FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
206 #else /* !UNROLL_LOOPS */
207     for (i =  0; i < 20; ++i) { FG(1); }
208     for (i = 20; i < 40; ++i) { FG(2); }
209     for (i = 40; i < 60; ++i) { FG(3); }
210     for (i = 60; i < 80; ++i) { FG(4); }
211 #endif /* !UNROLL_LOOPS */
212     sha_info->digest[0] = T32(sha_info->digest[0] + A);
213     sha_info->digest[1] = T32(sha_info->digest[1] + B);
214     sha_info->digest[2] = T32(sha_info->digest[2] + C);
215     sha_info->digest[3] = T32(sha_info->digest[3] + D);
216     sha_info->digest[4] = T32(sha_info->digest[4] + E);
217 #endif /* !UNRAVEL */
218 }
219
220 /* initialize the SHA digest */
221
222 void sha_init(SHA_INFO *sha_info);
223
224 void sha_init(SHA_INFO *sha_info)
225 {
226     sha_info->digest[0] = ULONG_C(0x67452301);
227     sha_info->digest[1] = ULONG_C(0xefcdab89);
228     sha_info->digest[2] = ULONG_C(0x98badcfe);
229     sha_info->digest[3] = ULONG_C(0x10325476);
230     sha_info->digest[4] = ULONG_C(0xc3d2e1f0);
231     sha_info->count_lo = 0L;
232     sha_info->count_hi = 0L;
233     sha_info->local = 0;
234 }
235
236 /* update the SHA digest */
237
238 void sha_update(SHA_INFO *sha_info, BYTE *buffer, int count);
239
240 void sha_update(SHA_INFO *sha_info, BYTE *buffer, int count)
241 {
242     int i;
243     ULONG clo;
244
245     clo = T32(sha_info->count_lo + ((ULONG) count << 3));
246     if (clo < sha_info->count_lo) {
247         ++sha_info->count_hi;
248     }
249     sha_info->count_lo = clo;
250     sha_info->count_hi += (ULONG) count >> 29;
251     if (sha_info->local) {
252         i = SHA_BLOCKSIZE - sha_info->local;
253         if (i > count) {
254             i = count;
255         }
256         memcpy(((BYTE *) sha_info->data) + sha_info->local, buffer, i);
257         count -= i;
258         buffer += i;
259         sha_info->local += i;
260         if (sha_info->local == SHA_BLOCKSIZE) {
261             sha_transform(sha_info);
262         } else {
263             return;
264         }
265     }
266     while (count >= SHA_BLOCKSIZE) {
267         memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
268         buffer += SHA_BLOCKSIZE;
269         count -= SHA_BLOCKSIZE;
270         sha_transform(sha_info);
271     }
272     memcpy(sha_info->data, buffer, count);
273     sha_info->local = count;
274 }
275
276 /* finish computing the SHA digest */
277
278 void sha_final(unsigned char digest[20], SHA_INFO *sha_info);
279
280 void sha_final(unsigned char digest[20], SHA_INFO *sha_info)
281 {
282     int count;
283     ULONG lo_bit_count, hi_bit_count;
284
285     lo_bit_count = sha_info->count_lo;
286     hi_bit_count = sha_info->count_hi;
287     count = (int) ((lo_bit_count >> 3) & 0x3f);
288     ((BYTE *) sha_info->data)[count++] = 0x80;
289     if (count > SHA_BLOCKSIZE - 8) {
290         memset(((BYTE *) sha_info->data) + count, 0, SHA_BLOCKSIZE - count);
291         sha_transform(sha_info);
292         memset((BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
293     } else {
294         memset(((BYTE *) sha_info->data) + count, 0,
295             SHA_BLOCKSIZE - 8 - count);
296     }
297     sha_info->data[56] = (unsigned char) ((hi_bit_count >> 24) & 0xff);
298     sha_info->data[57] = (unsigned char) ((hi_bit_count >> 16) & 0xff);
299     sha_info->data[58] = (unsigned char) ((hi_bit_count >>  8) & 0xff);
300     sha_info->data[59] = (unsigned char) ((hi_bit_count >>  0) & 0xff);
301     sha_info->data[60] = (unsigned char) ((lo_bit_count >> 24) & 0xff);
302     sha_info->data[61] = (unsigned char) ((lo_bit_count >> 16) & 0xff);
303     sha_info->data[62] = (unsigned char) ((lo_bit_count >>  8) & 0xff);
304     sha_info->data[63] = (unsigned char) ((lo_bit_count >>  0) & 0xff);
305     sha_transform(sha_info);
306     digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
307     digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
308     digest[ 2] = (unsigned char) ((sha_info->digest[0] >>  8) & 0xff);
309     digest[ 3] = (unsigned char) ((sha_info->digest[0]      ) & 0xff);
310     digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
311     digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
312     digest[ 6] = (unsigned char) ((sha_info->digest[1] >>  8) & 0xff);
313     digest[ 7] = (unsigned char) ((sha_info->digest[1]      ) & 0xff);
314     digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
315     digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
316     digest[10] = (unsigned char) ((sha_info->digest[2] >>  8) & 0xff);
317     digest[11] = (unsigned char) ((sha_info->digest[2]      ) & 0xff);
318     digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
319     digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
320     digest[14] = (unsigned char) ((sha_info->digest[3] >>  8) & 0xff);
321     digest[15] = (unsigned char) ((sha_info->digest[3]      ) & 0xff);
322     digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
323     digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
324     digest[18] = (unsigned char) ((sha_info->digest[4] >>  8) & 0xff);
325     digest[19] = (unsigned char) ((sha_info->digest[4]      ) & 0xff);
326 }
327
328 #ifdef SHA_FOR_C
329
330 /* compute the SHA digest of a FILE stream */
331
332 #define BLOCK_SIZE      8192
333
334 void sha_stream(unsigned char digest[20], SHA_INFO *sha_info, FILE *fin);
335
336 void sha_stream(unsigned char digest[20], SHA_INFO *sha_info, FILE *fin)
337 {
338     int i;
339     BYTE data[BLOCK_SIZE];
340
341     sha_init(sha_info);
342     while ((i = fread(data, 1, BLOCK_SIZE, fin)) > 0) {
343         sha_update(sha_info, data, i);
344     }
345     sha_final(digest, sha_info);
346 }
347
348 /* print a SHA digest */
349
350 void sha_print(unsigned char digest[20]);
351
352 void sha_print(unsigned char digest[20])
353 {
354     int i, j;
355
356     for (j = 0; j < 5; ++j) {
357         for (i = 0; i < 4; ++i) {
358             printf("%02x", *digest++);
359         }
360         printf("%c", (j < 4) ? ' ' : '\n');
361     }
362 }
363
364 char *sha_version(void);
365
366 char *sha_version()
367 {
368 #if (SHA_VERSION == 1)
369     static char *version = "SHA-1";
370 #else
371     static char *version = "SHA";
372 #endif
373     return(version);
374 }
375
376 #endif /* SHA_FOR_C */