Annotation of parser3/src/lib/md5/pa_sha2.c, revision 1.4
1.1 moko 1: /*
2: * FILE: sha2.c
3: * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
4: *
5: * Copyright (c) 2000-2001, Aaron D. Gifford
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. Neither the name of the copyright holder nor the names of contributors
17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: *
32: */
33:
34: #include "pa_sha2.h"
35:
1.4 ! moko 36: volatile const char * IDENT_PA_SHA2_C="$Id$" IDENT_PA_SHA2_H;
! 37:
1.1 moko 38: /*
39: * ASSERT NOTE:
40: * Some sanity checking code is included using assert(). On my FreeBSD
41: * system, this additional code can be removed by compiling with NDEBUG
42: * defined. Check your own systems manpage on assert() to see how to
43: * compile WITHOUT the sanity checking code on your system.
44: *
45: * UNROLLED TRANSFORM LOOP NOTE:
46: * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
47: * loop version for the hash transform rounds (defined using macros
48: * later in this file). Either define on the command line, for example:
49: *
50: * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
51: *
52: * or define below:
53: *
54: * #define SHA2_UNROLL_TRANSFORM
55: *
56: */
57:
58:
59: /*** SHA-256/384/512 Machine Architecture Definitions *****************/
60:
61: /*
62: * Define the followingsha2_* types to types of the correct length on
63: * the native archtecture. Most BSD systems and Linux define u_intXX_t
64: * types. Machines with very recent ANSI C headers, can use the
65: * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
66: * during compile or in the sha.h header file.
67: *
68: * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
69: * will need to define these three typedefs below (and the appropriate
70: * ones in sha.h too) by hand according to their system architecture.
71: *
72: * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
73: * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
74: */
75:
76: typedef uint8_t sha2_byte; /* Exactly 1 byte */
77: typedef uint32_t sha2_word32; /* Exactly 4 bytes */
78: typedef uint64_t sha2_word64; /* Exactly 8 bytes */
79:
80: /*** SHA-256/384/512 Various Length Definitions ***********************/
81: /* NOTE: Most of these are in sha2.h */
82: #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
83: #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
84: #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
85:
86:
87: /*** ENDIAN REVERSAL MACROS *******************************************/
1.2 moko 88: #ifdef PA_LITTLE_ENDIAN
1.1 moko 89: #define REVERSE32(w,x) { \
90: sha2_word32 tmp = (w); \
91: tmp = (tmp >> 16) | (tmp << 16); \
92: (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
93: }
94: #define REVERSE64(w,x) { \
95: sha2_word64 tmp = (w); \
96: tmp = (tmp >> 32) | (tmp << 32); \
97: tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
98: ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
99: (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
100: ((tmp & 0x0000ffff0000ffffULL) << 16); \
101: }
1.2 moko 102: #endif /* PA_LITTLE_ENDIAN */
1.1 moko 103:
104: /*
105: * Macro for incrementally adding the unsigned 64-bit integer n to the
106: * unsigned 128-bit integer (represented using a two-element array of
107: * 64-bit words):
108: */
109: #define ADDINC128(w,n) { \
110: (w)[0] += (sha2_word64)(n); \
111: if ((w)[0] < (n)) { \
112: (w)[1]++; \
113: } \
114: }
115:
116: /*
117: * Macros for copying blocks of memory and for zeroing out ranges
118: * of memory. Using these macros makes it easy to switch from
119: * using memset()/memcpy() and using bzero()/bcopy().
120: *
121: * Please define either SHA2_USE_MEMSET_MEMCPY or define
122: * SHA2_USE_BZERO_BCOPY depending on which function set you
123: * choose to use:
124: */
125: #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
126: /* Default to memset()/memcpy() if no option is specified */
127: #define SHA2_USE_MEMSET_MEMCPY 1
128: #endif
129: #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
130: /* Abort with an error if BOTH options are defined */
131: #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
132: #endif
133:
134: #ifdef SHA2_USE_MEMSET_MEMCPY
135: #define MEMSET_BZERO(p,l) memset((p), 0, (l))
136: #define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
137: #endif
138: #ifdef SHA2_USE_BZERO_BCOPY
139: #define MEMSET_BZERO(p,l) bzero((p), (l))
140: #define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
141: #endif
142:
143:
144: /*** THE SIX LOGICAL FUNCTIONS ****************************************/
145: /*
146: * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
147: *
148: * NOTE: The naming of R and S appears backwards here (R is a SHIFT and
149: * S is a ROTATION) because the SHA-256/384/512 description document
150: * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
151: * same "backwards" definition.
152: */
153: /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
154: #define R(b,x) ((x) >> (b))
155: /* 32-bit Rotate-right (used in SHA-256): */
156: #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
157: /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
158: #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
159:
160: /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
161: #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
162: #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
163:
164: /* Four of six logical functions used in SHA-256: */
165: #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
166: #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
167: #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
168: #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
169:
170: /* Four of six logical functions used in SHA-384 and SHA-512: */
171: #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
172: #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
173: #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
174: #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
175:
176: /*** INTERNAL FUNCTION PROTOTYPES *************************************/
177: /* NOTE: These should not be accessed directly from outside this
178: * library -- they are intended for private internal visibility/use
179: * only.
180: */
181: void pa_SHA512_Last(SHA512_CTX*);
182: void pa_SHA256_Transform(SHA256_CTX*, const sha2_word32*);
183: void pa_SHA512_Transform(SHA512_CTX*, const sha2_word64*);
184:
185:
186: /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
187: /* Hash constant words K for SHA-256: */
188: const static sha2_word32 K256[64] = {
189: 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
190: 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
191: 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
192: 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
193: 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
194: 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
195: 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
196: 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
197: 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
198: 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
199: 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
200: 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
201: 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
202: 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
203: 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
204: 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
205: };
206:
207: /* Initial hash value H for SHA-256: */
208: const static sha2_word32 sha256_initial_hash_value[8] = {
209: 0x6a09e667UL,
210: 0xbb67ae85UL,
211: 0x3c6ef372UL,
212: 0xa54ff53aUL,
213: 0x510e527fUL,
214: 0x9b05688cUL,
215: 0x1f83d9abUL,
216: 0x5be0cd19UL
217: };
218:
219: /* Hash constant words K for SHA-384 and SHA-512: */
220: const static sha2_word64 K512[80] = {
221: 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
222: 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
223: 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
224: 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
225: 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
226: 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
227: 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
228: 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
229: 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
230: 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
231: 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
232: 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
233: 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
234: 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
235: 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
236: 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
237: 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
238: 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
239: 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
240: 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
241: 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
242: 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
243: 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
244: 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
245: 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
246: 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
247: 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
248: 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
249: 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
250: 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
251: 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
252: 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
253: 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
254: 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
255: 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
256: 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
257: 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
258: 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
259: 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
260: 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
261: };
262:
263: /* Initial hash value H for SHA-384 */
264: const static sha2_word64 sha384_initial_hash_value[8] = {
265: 0xcbbb9d5dc1059ed8ULL,
266: 0x629a292a367cd507ULL,
267: 0x9159015a3070dd17ULL,
268: 0x152fecd8f70e5939ULL,
269: 0x67332667ffc00b31ULL,
270: 0x8eb44a8768581511ULL,
271: 0xdb0c2e0d64f98fa7ULL,
272: 0x47b5481dbefa4fa4ULL
273: };
274:
275: /* Initial hash value H for SHA-512 */
276: const static sha2_word64 sha512_initial_hash_value[8] = {
277: 0x6a09e667f3bcc908ULL,
278: 0xbb67ae8584caa73bULL,
279: 0x3c6ef372fe94f82bULL,
280: 0xa54ff53a5f1d36f1ULL,
281: 0x510e527fade682d1ULL,
282: 0x9b05688c2b3e6c1fULL,
283: 0x1f83d9abfb41bd6bULL,
284: 0x5be0cd19137e2179ULL
285: };
286:
287: /*
288: * Constant used by SHA256/384/512_End() functions for converting the
289: * digest to a readable hexadecimal character string:
290: */
291: static const char *sha2_hex_digits = "0123456789abcdef";
292:
293:
294: /*** SHA-256: *********************************************************/
295: void pa_SHA256_Init(SHA256_CTX* context) {
296: if (context == (SHA256_CTX*)0) {
297: return;
298: }
299: MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
300: MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
301: context->bitcount = 0;
302: }
303:
304: #ifdef SHA2_UNROLL_TRANSFORM
305:
306: /* Unrolled SHA-256 round macros: */
307:
1.2 moko 308: #ifdef PA_LITTLE_ENDIAN
1.1 moko 309:
310: #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
311: REVERSE32(*data++, W256[j]); \
312: T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
313: K256[j] + W256[j]; \
314: (d) += T1; \
315: (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
316: j++
317:
318:
1.2 moko 319: #else /* PA_LITTLE_ENDIAN */
1.1 moko 320:
321: #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
322: T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
323: K256[j] + (W256[j] = *data++); \
324: (d) += T1; \
325: (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
326: j++
327:
1.2 moko 328: #endif /* PA_LITTLE_ENDIAN */
1.1 moko 329:
330: #define ROUND256(a,b,c,d,e,f,g,h) \
331: s0 = W256[(j+1)&0x0f]; \
332: s0 = sigma0_256(s0); \
333: s1 = W256[(j+14)&0x0f]; \
334: s1 = sigma1_256(s1); \
335: T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
336: (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
337: (d) += T1; \
338: (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
339: j++
340:
341: void pa_SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
342: sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
343: sha2_word32 T1, *W256;
344: int j;
345:
346: W256 = (sha2_word32*)context->buffer;
347:
348: /* Initialize registers with the prev. intermediate value */
349: a = context->state[0];
350: b = context->state[1];
351: c = context->state[2];
352: d = context->state[3];
353: e = context->state[4];
354: f = context->state[5];
355: g = context->state[6];
356: h = context->state[7];
357:
358: j = 0;
359: do {
360: /* Rounds 0 to 15 (unrolled): */
361: ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
362: ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
363: ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
364: ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
365: ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
366: ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
367: ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
368: ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
369: } while (j < 16);
370:
371: /* Now for the remaining rounds to 64: */
372: do {
373: ROUND256(a,b,c,d,e,f,g,h);
374: ROUND256(h,a,b,c,d,e,f,g);
375: ROUND256(g,h,a,b,c,d,e,f);
376: ROUND256(f,g,h,a,b,c,d,e);
377: ROUND256(e,f,g,h,a,b,c,d);
378: ROUND256(d,e,f,g,h,a,b,c);
379: ROUND256(c,d,e,f,g,h,a,b);
380: ROUND256(b,c,d,e,f,g,h,a);
381: } while (j < 64);
382:
383: /* Compute the current intermediate hash value */
384: context->state[0] += a;
385: context->state[1] += b;
386: context->state[2] += c;
387: context->state[3] += d;
388: context->state[4] += e;
389: context->state[5] += f;
390: context->state[6] += g;
391: context->state[7] += h;
392:
393: /* Clean up */
394: a = b = c = d = e = f = g = h = T1 = 0;
395: }
396:
397: #else /* SHA2_UNROLL_TRANSFORM */
398:
399: void pa_SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
400: sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
401: sha2_word32 T1, T2, *W256;
402: int j;
403:
404: W256 = (sha2_word32*)context->buffer;
405:
406: /* Initialize registers with the prev. intermediate value */
407: a = context->state[0];
408: b = context->state[1];
409: c = context->state[2];
410: d = context->state[3];
411: e = context->state[4];
412: f = context->state[5];
413: g = context->state[6];
414: h = context->state[7];
415:
416: j = 0;
417: do {
1.2 moko 418: #ifdef PA_LITTLE_ENDIAN
1.1 moko 419: /* Copy data while converting to host byte order */
420: REVERSE32(*data++,W256[j]);
421: /* Apply the SHA-256 compression function to update a..h */
422: T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
1.2 moko 423: #else /* PA_LITTLE_ENDIAN */
1.1 moko 424: /* Apply the SHA-256 compression function to update a..h with copy */
425: T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
1.2 moko 426: #endif /* PA_LITTLE_ENDIAN */
1.1 moko 427: T2 = Sigma0_256(a) + Maj(a, b, c);
428: h = g;
429: g = f;
430: f = e;
431: e = d + T1;
432: d = c;
433: c = b;
434: b = a;
435: a = T1 + T2;
436:
437: j++;
438: } while (j < 16);
439:
440: do {
441: /* Part of the message block expansion: */
442: s0 = W256[(j+1)&0x0f];
443: s0 = sigma0_256(s0);
444: s1 = W256[(j+14)&0x0f];
445: s1 = sigma1_256(s1);
446:
447: /* Apply the SHA-256 compression function to update a..h */
448: T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
449: (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
450: T2 = Sigma0_256(a) + Maj(a, b, c);
451: h = g;
452: g = f;
453: f = e;
454: e = d + T1;
455: d = c;
456: c = b;
457: b = a;
458: a = T1 + T2;
459:
460: j++;
461: } while (j < 64);
462:
463: /* Compute the current intermediate hash value */
464: context->state[0] += a;
465: context->state[1] += b;
466: context->state[2] += c;
467: context->state[3] += d;
468: context->state[4] += e;
469: context->state[5] += f;
470: context->state[6] += g;
471: context->state[7] += h;
472:
473: /* Clean up */
474: a = b = c = d = e = f = g = h = T1 = T2 = 0;
475: }
476:
477: #endif /* SHA2_UNROLL_TRANSFORM */
478:
479: void pa_SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
480: unsigned int freespace, usedspace;
481:
482: if (len == 0) {
483: /* Calling with no data is valid - we do nothing */
484: return;
485: }
486:
487: /* Sanity check: */
488: assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
489:
1.3 moko 490: usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH);
1.1 moko 491: if (usedspace > 0) {
492: /* Calculate how much free space is available in the buffer */
493: freespace = SHA256_BLOCK_LENGTH - usedspace;
494:
495: if (len >= freespace) {
496: /* Fill the buffer completely and process it */
497: MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
498: context->bitcount += freespace << 3;
499: len -= freespace;
500: data += freespace;
501: pa_SHA256_Transform(context, (sha2_word32*)context->buffer);
502: } else {
503: /* The buffer is not yet full */
504: MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
505: context->bitcount += len << 3;
506: /* Clean up: */
507: usedspace = freespace = 0;
508: return;
509: }
510: }
511: while (len >= SHA256_BLOCK_LENGTH) {
512: /* Process as many complete blocks as we can */
513: pa_SHA256_Transform(context, (sha2_word32*)data);
514: context->bitcount += SHA256_BLOCK_LENGTH << 3;
515: len -= SHA256_BLOCK_LENGTH;
516: data += SHA256_BLOCK_LENGTH;
517: }
518: if (len > 0) {
519: /* There's left-overs, so save 'em */
520: MEMCPY_BCOPY(context->buffer, data, len);
521: context->bitcount += len << 3;
522: }
523: /* Clean up: */
524: usedspace = freespace = 0;
525: }
526:
527: void pa_SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
528: sha2_word32 *d = (sha2_word32*)digest;
529: unsigned int usedspace;
530:
531: /* Sanity check: */
532: assert(context != (SHA256_CTX*)0);
533:
534: /* If no digest buffer is passed, we don't bother doing this: */
535: if (digest != (sha2_byte*)0) {
1.3 moko 536: usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH);
1.2 moko 537: #ifdef PA_LITTLE_ENDIAN
1.1 moko 538: /* Convert FROM host byte order */
539: REVERSE64(context->bitcount,context->bitcount);
540: #endif
541: if (usedspace > 0) {
542: /* Begin padding with a 1 bit: */
543: context->buffer[usedspace++] = 0x80;
544:
545: if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
546: /* Set-up for the last transform: */
547: MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
548: } else {
549: if (usedspace < SHA256_BLOCK_LENGTH) {
550: MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
551: }
552: /* Do second-to-last transform: */
553: pa_SHA256_Transform(context, (sha2_word32*)context->buffer);
554:
555: /* And set-up for the last transform: */
556: MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
557: }
558: } else {
559: /* Set-up for the last transform: */
560: MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
561:
562: /* Begin padding with a 1 bit: */
563: *context->buffer = 0x80;
564: }
565: /* Set the bit count: */
566: *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
567:
568: /* Final transform: */
569: pa_SHA256_Transform(context, (sha2_word32*)context->buffer);
570:
1.2 moko 571: #ifdef PA_LITTLE_ENDIAN
1.1 moko 572: {
573: /* Convert TO host byte order */
574: int j;
575: for (j = 0; j < 8; j++) {
576: REVERSE32(context->state[j],context->state[j]);
577: *d++ = context->state[j];
578: }
579: }
580: #else
581: MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
582: #endif
583: }
584:
585: /* Clean up state data: */
586: MEMSET_BZERO(context, sizeof(SHA256_CTX));
587: usedspace = 0;
588: }
589:
590: char *pa_SHA256_End(SHA256_CTX* context, char buffer[]) {
591: sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
592: int i;
593:
594: /* Sanity check: */
595: assert(context != (SHA256_CTX*)0);
596:
597: if (buffer != (char*)0) {
598: pa_SHA256_Final(digest, context);
599:
600: for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
601: *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
602: *buffer++ = sha2_hex_digits[*d & 0x0f];
603: d++;
604: }
605: *buffer = (char)0;
606: } else {
607: MEMSET_BZERO(context, sizeof(SHA256_CTX));
608: }
609: MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
610: return buffer;
611: }
612:
613: char* pa_SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
614: SHA256_CTX context;
615:
616: pa_SHA256_Init(&context);
617: pa_SHA256_Update(&context, data, len);
618: return pa_SHA256_End(&context, digest);
619: }
620:
621:
622: /*** SHA-512: *********************************************************/
623: void pa_SHA512_Init(SHA512_CTX* context) {
624: if (context == (SHA512_CTX*)0) {
625: return;
626: }
627: MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
628: MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
629: context->bitcount[0] = context->bitcount[1] = 0;
630: }
631:
632: #ifdef SHA2_UNROLL_TRANSFORM
633:
634: /* Unrolled SHA-512 round macros: */
1.2 moko 635: #ifdef PA_LITTLE_ENDIAN
1.1 moko 636:
637: #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
638: REVERSE64(*data++, W512[j]); \
639: T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
640: K512[j] + W512[j]; \
641: (d) += T1, \
642: (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
643: j++
644:
645:
1.2 moko 646: #else /* PA_LITTLE_ENDIAN */
1.1 moko 647:
648: #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
649: T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
650: K512[j] + (W512[j] = *data++); \
651: (d) += T1; \
652: (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
653: j++
654:
1.2 moko 655: #endif /* PA_LITTLE_ENDIAN */
1.1 moko 656:
657: #define ROUND512(a,b,c,d,e,f,g,h) \
658: s0 = W512[(j+1)&0x0f]; \
659: s0 = sigma0_512(s0); \
660: s1 = W512[(j+14)&0x0f]; \
661: s1 = sigma1_512(s1); \
662: T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
663: (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
664: (d) += T1; \
665: (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
666: j++
667:
668: void pa_SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
669: sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
670: sha2_word64 T1, *W512 = (sha2_word64*)context->buffer;
671: int j;
672:
673: /* Initialize registers with the prev. intermediate value */
674: a = context->state[0];
675: b = context->state[1];
676: c = context->state[2];
677: d = context->state[3];
678: e = context->state[4];
679: f = context->state[5];
680: g = context->state[6];
681: h = context->state[7];
682:
683: j = 0;
684: do {
685: ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
686: ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
687: ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
688: ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
689: ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
690: ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
691: ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
692: ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
693: } while (j < 16);
694:
695: /* Now for the remaining rounds up to 79: */
696: do {
697: ROUND512(a,b,c,d,e,f,g,h);
698: ROUND512(h,a,b,c,d,e,f,g);
699: ROUND512(g,h,a,b,c,d,e,f);
700: ROUND512(f,g,h,a,b,c,d,e);
701: ROUND512(e,f,g,h,a,b,c,d);
702: ROUND512(d,e,f,g,h,a,b,c);
703: ROUND512(c,d,e,f,g,h,a,b);
704: ROUND512(b,c,d,e,f,g,h,a);
705: } while (j < 80);
706:
707: /* Compute the current intermediate hash value */
708: context->state[0] += a;
709: context->state[1] += b;
710: context->state[2] += c;
711: context->state[3] += d;
712: context->state[4] += e;
713: context->state[5] += f;
714: context->state[6] += g;
715: context->state[7] += h;
716:
717: /* Clean up */
718: a = b = c = d = e = f = g = h = T1 = 0;
719: }
720:
721: #else /* SHA2_UNROLL_TRANSFORM */
722:
723: void pa_SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
724: sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
725: sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
726: int j;
727:
728: /* Initialize registers with the prev. intermediate value */
729: a = context->state[0];
730: b = context->state[1];
731: c = context->state[2];
732: d = context->state[3];
733: e = context->state[4];
734: f = context->state[5];
735: g = context->state[6];
736: h = context->state[7];
737:
738: j = 0;
739: do {
1.2 moko 740: #ifdef PA_LITTLE_ENDIAN
1.1 moko 741: /* Convert TO host byte order */
742: REVERSE64(*data++, W512[j]);
743: /* Apply the SHA-512 compression function to update a..h */
744: T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
1.2 moko 745: #else /* PA_LITTLE_ENDIAN */
1.1 moko 746: /* Apply the SHA-512 compression function to update a..h with copy */
747: T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
1.2 moko 748: #endif /* PA_LITTLE_ENDIAN */
1.1 moko 749: T2 = Sigma0_512(a) + Maj(a, b, c);
750: h = g;
751: g = f;
752: f = e;
753: e = d + T1;
754: d = c;
755: c = b;
756: b = a;
757: a = T1 + T2;
758:
759: j++;
760: } while (j < 16);
761:
762: do {
763: /* Part of the message block expansion: */
764: s0 = W512[(j+1)&0x0f];
765: s0 = sigma0_512(s0);
766: s1 = W512[(j+14)&0x0f];
767: s1 = sigma1_512(s1);
768:
769: /* Apply the SHA-512 compression function to update a..h */
770: T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
771: (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
772: T2 = Sigma0_512(a) + Maj(a, b, c);
773: h = g;
774: g = f;
775: f = e;
776: e = d + T1;
777: d = c;
778: c = b;
779: b = a;
780: a = T1 + T2;
781:
782: j++;
783: } while (j < 80);
784:
785: /* Compute the current intermediate hash value */
786: context->state[0] += a;
787: context->state[1] += b;
788: context->state[2] += c;
789: context->state[3] += d;
790: context->state[4] += e;
791: context->state[5] += f;
792: context->state[6] += g;
793: context->state[7] += h;
794:
795: /* Clean up */
796: a = b = c = d = e = f = g = h = T1 = T2 = 0;
797: }
798:
799: #endif /* SHA2_UNROLL_TRANSFORM */
800:
801: void pa_SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
802: unsigned int freespace, usedspace;
803:
804: if (len == 0) {
805: /* Calling with no data is valid - we do nothing */
806: return;
807: }
808:
809: /* Sanity check: */
810: assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
811:
1.3 moko 812: usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH);
1.1 moko 813: if (usedspace > 0) {
814: /* Calculate how much free space is available in the buffer */
815: freespace = SHA512_BLOCK_LENGTH - usedspace;
816:
817: if (len >= freespace) {
818: /* Fill the buffer completely and process it */
819: MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
820: ADDINC128(context->bitcount, freespace << 3);
821: len -= freespace;
822: data += freespace;
823: pa_SHA512_Transform(context, (sha2_word64*)context->buffer);
824: } else {
825: /* The buffer is not yet full */
826: MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
827: ADDINC128(context->bitcount, len << 3);
828: /* Clean up: */
829: usedspace = freespace = 0;
830: return;
831: }
832: }
833: while (len >= SHA512_BLOCK_LENGTH) {
834: /* Process as many complete blocks as we can */
835: pa_SHA512_Transform(context, (sha2_word64*)data);
836: ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
837: len -= SHA512_BLOCK_LENGTH;
838: data += SHA512_BLOCK_LENGTH;
839: }
840: if (len > 0) {
841: /* There's left-overs, so save 'em */
842: MEMCPY_BCOPY(context->buffer, data, len);
843: ADDINC128(context->bitcount, len << 3);
844: }
845: /* Clean up: */
846: usedspace = freespace = 0;
847: }
848:
849: void pa_SHA512_Last(SHA512_CTX* context) {
850: unsigned int usedspace;
851:
1.3 moko 852: usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH);
1.2 moko 853: #ifdef PA_LITTLE_ENDIAN
1.1 moko 854: /* Convert FROM host byte order */
855: REVERSE64(context->bitcount[0],context->bitcount[0]);
856: REVERSE64(context->bitcount[1],context->bitcount[1]);
857: #endif
858: if (usedspace > 0) {
859: /* Begin padding with a 1 bit: */
860: context->buffer[usedspace++] = 0x80;
861:
862: if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
863: /* Set-up for the last transform: */
864: MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
865: } else {
866: if (usedspace < SHA512_BLOCK_LENGTH) {
867: MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
868: }
869: /* Do second-to-last transform: */
870: pa_SHA512_Transform(context, (sha2_word64*)context->buffer);
871:
872: /* And set-up for the last transform: */
873: MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
874: }
875: } else {
876: /* Prepare for final transform: */
877: MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
878:
879: /* Begin padding with a 1 bit: */
880: *context->buffer = 0x80;
881: }
882: /* Store the length of input data (in bits): */
883: *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
884: *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
885:
886: /* Final transform: */
887: pa_SHA512_Transform(context, (sha2_word64*)context->buffer);
888: }
889:
890: void pa_SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
891: sha2_word64 *d = (sha2_word64*)digest;
892:
893: /* Sanity check: */
894: assert(context != (SHA512_CTX*)0);
895:
896: /* If no digest buffer is passed, we don't bother doing this: */
897: if (digest != (sha2_byte*)0) {
898: pa_SHA512_Last(context);
899:
900: /* Save the hash data for output: */
1.2 moko 901: #ifdef PA_LITTLE_ENDIAN
1.1 moko 902: {
903: /* Convert TO host byte order */
904: int j;
905: for (j = 0; j < 8; j++) {
906: REVERSE64(context->state[j],context->state[j]);
907: *d++ = context->state[j];
908: }
909: }
910: #else
911: MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
912: #endif
913: }
914:
915: /* Zero out state data */
916: MEMSET_BZERO(context, sizeof(SHA512_CTX));
917: }
918:
919: char *pa_SHA512_End(SHA512_CTX* context, char buffer[]) {
920: sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
921: int i;
922:
923: /* Sanity check: */
924: assert(context != (SHA512_CTX*)0);
925:
926: if (buffer != (char*)0) {
927: pa_SHA512_Final(digest, context);
928:
929: for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
930: *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
931: *buffer++ = sha2_hex_digits[*d & 0x0f];
932: d++;
933: }
934: *buffer = (char)0;
935: } else {
936: MEMSET_BZERO(context, sizeof(SHA512_CTX));
937: }
938: MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
939: return buffer;
940: }
941:
942: char* pa_SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
943: SHA512_CTX context;
944:
945: pa_SHA512_Init(&context);
946: pa_SHA512_Update(&context, data, len);
947: return pa_SHA512_End(&context, digest);
948: }
949:
950:
951: /*** SHA-384: *********************************************************/
952: void pa_SHA384_Init(SHA384_CTX* context) {
953: if (context == (SHA384_CTX*)0) {
954: return;
955: }
956: MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
957: MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
958: context->bitcount[0] = context->bitcount[1] = 0;
959: }
960:
961: void pa_SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
962: pa_SHA512_Update((SHA512_CTX*)context, data, len);
963: }
964:
965: void pa_SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
966: sha2_word64 *d = (sha2_word64*)digest;
967:
968: /* Sanity check: */
969: assert(context != (SHA384_CTX*)0);
970:
971: /* If no digest buffer is passed, we don't bother doing this: */
972: if (digest != (sha2_byte*)0) {
973: pa_SHA512_Last((SHA512_CTX*)context);
974:
975: /* Save the hash data for output: */
1.2 moko 976: #ifdef PA_LITTLE_ENDIAN
1.1 moko 977: {
978: /* Convert TO host byte order */
979: int j;
980: for (j = 0; j < 6; j++) {
981: REVERSE64(context->state[j],context->state[j]);
982: *d++ = context->state[j];
983: }
984: }
985: #else
986: MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
987: #endif
988: }
989:
990: /* Zero out state data */
991: MEMSET_BZERO(context, sizeof(SHA384_CTX));
992: }
993:
994: char *pa_SHA384_End(SHA384_CTX* context, char buffer[]) {
995: sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
996: int i;
997:
998: /* Sanity check: */
999: assert(context != (SHA384_CTX*)0);
1000:
1001: if (buffer != (char*)0) {
1002: pa_SHA384_Final(digest, context);
1003:
1004: for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
1005: *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1006: *buffer++ = sha2_hex_digits[*d & 0x0f];
1007: d++;
1008: }
1009: *buffer = (char)0;
1010: } else {
1011: MEMSET_BZERO(context, sizeof(SHA384_CTX));
1012: }
1013: MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
1014: return buffer;
1015: }
1016:
1017: char* pa_SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
1018: SHA384_CTX context;
1019:
1020: pa_SHA384_Init(&context);
1021: pa_SHA384_Update(&context, data, len);
1022: return pa_SHA384_End(&context, digest);
1023: }
1024:
E-mail: