8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libsum / common / sum-sha2.c
blobd42674eba1836e2314c20bfedcf61eda87d8c942
1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1996-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * *
19 ***********************************************************************/
20 #pragma prototyped
22 #if _typ_int64_t
25 * Aaron D. Gifford's SHA {256,384,512} code transcribed into a -lsum method
29 * Copyright (c) 2000-2001, Aaron D. Gifford
30 * All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. Neither the name of the copyright holder nor the names of contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
58 * ASSERT NOTE:
59 * Some sanity checking code is included using assert(). On my FreeBSD
60 * system, this additional code can be removed by compiling with NDEBUG
61 * defined. Check your own systems manpage on assert() to see how to
62 * compile WITHOUT the sanity checking code on your system.
64 * UNROLLED TRANSFORM LOOP NOTE:
65 * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
66 * loop version for the hash transform rounds (defined using macros
67 * later in this file). Either define on the command line, for example:
69 * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
71 * or define below:
73 * #define SHA2_UNROLL_TRANSFORM
77 /*** SHA-256/384/512 Machine Architecture Definitions *****************/
79 #if _PACKAGE_ast
81 #ifndef __USE_BSD
82 #define __undef__USE_BSD
83 #define __USE_BSD
84 #endif
85 #include <endian.h>
86 #ifdef __undef__USE_BSD
87 #undef __undef__USE_BSD
88 #undef __USE_BSD
89 #endif
91 typedef uint8_t sha2_byte; /* Exactly 1 byte */
92 typedef uint32_t sha2_word32; /* Exactly 4 bytes */
93 typedef uint64_t sha2_word64; /* Exactly 8 bytes */
95 #define assert(x)
97 #undef R
98 #undef S32
99 #undef S64
101 #else /* _PACKAGE_ast */
104 * BYTE_ORDER NOTE:
106 * Please make sure that your system defines BYTE_ORDER. If your
107 * architecture is little-endian, make sure it also defines
108 * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
109 * equivilent.
111 * If your system does not define the above, then you can do so by
112 * hand like this:
114 * #define LITTLE_ENDIAN 1234
115 * #define BIG_ENDIAN 4321
117 * And for little-endian machines, add:
119 * #define BYTE_ORDER LITTLE_ENDIAN
121 * Or for big-endian machines:
123 * #define BYTE_ORDER BIG_ENDIAN
125 * The FreeBSD machine this was written on defines BYTE_ORDER
126 * appropriately by including <sys/types.h> (which in turn includes
127 * <machine/endian.h> where the appropriate definitions are actually
128 * made).
131 #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
132 #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
133 #endif
136 * Define the following sha2_* types to types of the correct length on
137 * the native archtecture. Most BSD systems and Linux define u_intXX_t
138 * types. Machines with very recent ANSI C headers, can use the
139 * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
140 * during compile or in the sha.h header file.
142 * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
143 * will need to define these three typedefs below (and the appropriate
144 * ones in sha.h too) by hand according to their system architecture.
146 * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
147 * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
150 #ifdef SHA2_USE_INTTYPES_H
152 typedef uint8_t sha2_byte; /* Exactly 1 byte */
153 typedef uint32_t sha2_word32; /* Exactly 4 bytes */
154 typedef uint64_t sha2_word64; /* Exactly 8 bytes */
156 #else /* SHA2_USE_INTTYPES_H */
158 typedef u_int8_t sha2_byte; /* Exactly 1 byte */
159 typedef u_int32_t sha2_word32; /* Exactly 4 bytes */
160 typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
162 #endif /* SHA2_USE_INTTYPES_H */
164 #endif /* _PACKAGE_ast */
166 /*** SHA-256/384/512 Various Length Definitions ***********************/
168 #define SHA256_BLOCK_LENGTH 64
169 #define SHA256_DIGEST_LENGTH 32
170 #define SHA384_BLOCK_LENGTH 128
171 #define SHA384_DIGEST_LENGTH 48
172 #define SHA512_BLOCK_LENGTH 128
173 #define SHA512_DIGEST_LENGTH 64
175 #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
176 #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
177 #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
179 /*** ENDIAN REVERSAL MACROS *******************************************/
180 #if BYTE_ORDER == LITTLE_ENDIAN
181 #define REVERSE32(w,x) { \
182 sha2_word32 tmp = (w); \
183 tmp = (tmp >> 16) | (tmp << 16); \
184 (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
186 #if _ast_LL
187 #define REVERSE64(w,x) { \
188 sha2_word64 tmp = (w); \
189 tmp = (tmp >> 32) | (tmp << 32); \
190 tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
191 ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
192 (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
193 ((tmp & 0x0000ffff0000ffffULL) << 16); \
195 #else
196 #define REVERSE64(w,x) { \
197 sha2_word64 tmp = (w); \
198 tmp = (tmp >> 32) | (tmp << 32); \
199 tmp = ((tmp & ((sha2_word64)0xff00ff00ff00ff00)) >> 8) | \
200 ((tmp & ((sha2_word64)0x00ff00ff00ff00ff)) << 8); \
201 (x) = ((tmp & ((sha2_word64)0xffff0000ffff0000)) >> 16) | \
202 ((tmp & ((sha2_word64)0x0000ffff0000ffff)) << 16); \
204 #endif
205 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
208 * Macro for incrementally adding the unsigned 64-bit integer n to the
209 * unsigned 128-bit integer (represented using a two-element array of
210 * 64-bit words):
213 #define ADDINC128(w,n) { \
214 (w)[0] += (sha2_word64)(n); \
215 if ((w)[0] < (n)) { \
216 (w)[1]++; \
221 * Macros for copying blocks of memory and for zeroing out ranges
222 * of memory. Using these macros makes it easy to switch from
223 * using memset()/memcpy() and using bzero()/bcopy().
225 * Please define either SHA2_USE_MEMSET_MEMCPY or define
226 * SHA2_USE_BZERO_BCOPY depending on which function set you
227 * choose to use:
230 #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
231 /* Default to memset()/memcpy() if no option is specified */
232 #define SHA2_USE_MEMSET_MEMCPY 1
233 #endif
234 #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
235 /* Abort with an error if BOTH options are defined */
236 #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
237 #endif
239 #ifdef SHA2_USE_MEMSET_MEMCPY
240 #define MEMSET_BZERO(p,l) memset((p), 0, (l))
241 #define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
242 #endif
243 #ifdef SHA2_USE_BZERO_BCOPY
244 #define MEMSET_BZERO(p,l) bzero((p), (l))
245 #define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
246 #endif
249 /*** THE SIX LOGICAL FUNCTIONS ****************************************/
251 * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
253 * NOTE: The naming of R and S appears backwards here (R is a SHIFT and
254 * S is a ROTATION) because the SHA-256/384/512 description document
255 * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
256 * same "backwards" definition.
259 /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
260 #define R(b,x) ((x) >> (b))
261 /* 32-bit Rotate-right (used in SHA-256): */
262 #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
263 /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
264 #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
266 /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
267 #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
268 #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
270 /* Four of six logical functions used in SHA-256: */
271 #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
272 #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
273 #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
274 #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
276 /* Four of six logical functions used in SHA-384 and SHA-512: */
277 #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
278 #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
279 #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
280 #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
282 /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
283 /* Hash constant words K for SHA-256: */
284 static const sha2_word32 K256[64] = {
285 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
286 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
287 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
288 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
289 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
290 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
291 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
292 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
293 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
294 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
295 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
296 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
297 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
298 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
299 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
300 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
303 /* Initial hash value H for SHA-256: */
304 static const sha2_word32 sha256_initial_hash_value[8] = {
305 0x6a09e667UL,
306 0xbb67ae85UL,
307 0x3c6ef372UL,
308 0xa54ff53aUL,
309 0x510e527fUL,
310 0x9b05688cUL,
311 0x1f83d9abUL,
312 0x5be0cd19UL
315 /* Hash constant words K for SHA-384 and SHA-512: */
316 static const sha2_word64 K512[80] = {
317 #if _ast_LL
318 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
319 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
320 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
321 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
322 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
323 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
324 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
325 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
326 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
327 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
328 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
329 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
330 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
331 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
332 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
333 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
334 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
335 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
336 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
337 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
338 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
339 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
340 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
341 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
342 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
343 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
344 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
345 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
346 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
347 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
348 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
349 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
350 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
351 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
352 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
353 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
354 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
355 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
356 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
357 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
358 #else
359 ((sha2_word64)0x428a2f98d728ae22), ((sha2_word64)0x7137449123ef65cd),
360 ((sha2_word64)0xb5c0fbcfec4d3b2f), ((sha2_word64)0xe9b5dba58189dbbc),
361 ((sha2_word64)0x3956c25bf348b538), ((sha2_word64)0x59f111f1b605d019),
362 ((sha2_word64)0x923f82a4af194f9b), ((sha2_word64)0xab1c5ed5da6d8118),
363 ((sha2_word64)0xd807aa98a3030242), ((sha2_word64)0x12835b0145706fbe),
364 ((sha2_word64)0x243185be4ee4b28c), ((sha2_word64)0x550c7dc3d5ffb4e2),
365 ((sha2_word64)0x72be5d74f27b896f), ((sha2_word64)0x80deb1fe3b1696b1),
366 ((sha2_word64)0x9bdc06a725c71235), ((sha2_word64)0xc19bf174cf692694),
367 ((sha2_word64)0xe49b69c19ef14ad2), ((sha2_word64)0xefbe4786384f25e3),
368 ((sha2_word64)0x0fc19dc68b8cd5b5), ((sha2_word64)0x240ca1cc77ac9c65),
369 ((sha2_word64)0x2de92c6f592b0275), ((sha2_word64)0x4a7484aa6ea6e483),
370 ((sha2_word64)0x5cb0a9dcbd41fbd4), ((sha2_word64)0x76f988da831153b5),
371 ((sha2_word64)0x983e5152ee66dfab), ((sha2_word64)0xa831c66d2db43210),
372 ((sha2_word64)0xb00327c898fb213f), ((sha2_word64)0xbf597fc7beef0ee4),
373 ((sha2_word64)0xc6e00bf33da88fc2), ((sha2_word64)0xd5a79147930aa725),
374 ((sha2_word64)0x06ca6351e003826f), ((sha2_word64)0x142929670a0e6e70),
375 ((sha2_word64)0x27b70a8546d22ffc), ((sha2_word64)0x2e1b21385c26c926),
376 ((sha2_word64)0x4d2c6dfc5ac42aed), ((sha2_word64)0x53380d139d95b3df),
377 ((sha2_word64)0x650a73548baf63de), ((sha2_word64)0x766a0abb3c77b2a8),
378 ((sha2_word64)0x81c2c92e47edaee6), ((sha2_word64)0x92722c851482353b),
379 ((sha2_word64)0xa2bfe8a14cf10364), ((sha2_word64)0xa81a664bbc423001),
380 ((sha2_word64)0xc24b8b70d0f89791), ((sha2_word64)0xc76c51a30654be30),
381 ((sha2_word64)0xd192e819d6ef5218), ((sha2_word64)0xd69906245565a910),
382 ((sha2_word64)0xf40e35855771202a), ((sha2_word64)0x106aa07032bbd1b8),
383 ((sha2_word64)0x19a4c116b8d2d0c8), ((sha2_word64)0x1e376c085141ab53),
384 ((sha2_word64)0x2748774cdf8eeb99), ((sha2_word64)0x34b0bcb5e19b48a8),
385 ((sha2_word64)0x391c0cb3c5c95a63), ((sha2_word64)0x4ed8aa4ae3418acb),
386 ((sha2_word64)0x5b9cca4f7763e373), ((sha2_word64)0x682e6ff3d6b2b8a3),
387 ((sha2_word64)0x748f82ee5defb2fc), ((sha2_word64)0x78a5636f43172f60),
388 ((sha2_word64)0x84c87814a1f0ab72), ((sha2_word64)0x8cc702081a6439ec),
389 ((sha2_word64)0x90befffa23631e28), ((sha2_word64)0xa4506cebde82bde9),
390 ((sha2_word64)0xbef9a3f7b2c67915), ((sha2_word64)0xc67178f2e372532b),
391 ((sha2_word64)0xca273eceea26619c), ((sha2_word64)0xd186b8c721c0c207),
392 ((sha2_word64)0xeada7dd6cde0eb1e), ((sha2_word64)0xf57d4f7fee6ed178),
393 ((sha2_word64)0x06f067aa72176fba), ((sha2_word64)0x0a637dc5a2c898a6),
394 ((sha2_word64)0x113f9804bef90dae), ((sha2_word64)0x1b710b35131c471b),
395 ((sha2_word64)0x28db77f523047d84), ((sha2_word64)0x32caab7b40c72493),
396 ((sha2_word64)0x3c9ebe0a15c9bebc), ((sha2_word64)0x431d67c49c100d4c),
397 ((sha2_word64)0x4cc5d4becb3e42b6), ((sha2_word64)0x597f299cfc657e2a),
398 ((sha2_word64)0x5fcb6fab3ad6faec), ((sha2_word64)0x6c44198c4a475817)
399 #endif
402 /* Initial hash value H for SHA-384 */
403 static const sha2_word64 sha384_initial_hash_value[8] = {
404 #if _ast_LL
405 0xcbbb9d5dc1059ed8ULL,
406 0x629a292a367cd507ULL,
407 0x9159015a3070dd17ULL,
408 0x152fecd8f70e5939ULL,
409 0x67332667ffc00b31ULL,
410 0x8eb44a8768581511ULL,
411 0xdb0c2e0d64f98fa7ULL,
412 0x47b5481dbefa4fa4ULL
413 #else
414 ((sha2_word64)0xcbbb9d5dc1059ed8),
415 ((sha2_word64)0x629a292a367cd507),
416 ((sha2_word64)0x9159015a3070dd17),
417 ((sha2_word64)0x152fecd8f70e5939),
418 ((sha2_word64)0x67332667ffc00b31),
419 ((sha2_word64)0x8eb44a8768581511),
420 ((sha2_word64)0xdb0c2e0d64f98fa7),
421 ((sha2_word64)0x47b5481dbefa4fa4)
422 #endif
425 /* Initial hash value H for SHA-512 */
426 static const sha2_word64 sha512_initial_hash_value[8] = {
427 #if _ast_LL
428 0x6a09e667f3bcc908ULL,
429 0xbb67ae8584caa73bULL,
430 0x3c6ef372fe94f82bULL,
431 0xa54ff53a5f1d36f1ULL,
432 0x510e527fade682d1ULL,
433 0x9b05688c2b3e6c1fULL,
434 0x1f83d9abfb41bd6bULL,
435 0x5be0cd19137e2179ULL
436 #else
437 ((sha2_word64)0x6a09e667f3bcc908),
438 ((sha2_word64)0xbb67ae8584caa73b),
439 ((sha2_word64)0x3c6ef372fe94f82b),
440 ((sha2_word64)0xa54ff53a5f1d36f1),
441 ((sha2_word64)0x510e527fade682d1),
442 ((sha2_word64)0x9b05688c2b3e6c1f),
443 ((sha2_word64)0x1f83d9abfb41bd6b),
444 ((sha2_word64)0x5be0cd19137e2179)
445 #endif
448 /*** SHA-256: *********************************************************/
450 #define sha256_description "FIPS SHA-256 secure hash algorithm."
451 #define sha256_options "\
452 [+(version)?sha-256 (FIPS) 2000-01-01]\
453 [+(author)?Aaron D. Gifford]\
455 #define sha256_match "sha256|sha-256|SHA256|SHA-256"
456 #define sha256_scale 0
458 #define sha256_padding md5_pad
460 #define SHA256_CTX Sha256_t
462 typedef struct Sha256_s
464 _SUM_PUBLIC_
465 _SUM_PRIVATE_
466 sha2_byte digest[SHA256_DIGEST_LENGTH];
467 sha2_byte digest_sum[SHA256_DIGEST_LENGTH];
468 sha2_word32 state[8];
469 sha2_word64 bitcount;
470 sha2_byte buffer[SHA256_BLOCK_LENGTH];
471 } Sha256_t;
473 #ifdef SHA2_UNROLL_TRANSFORM
475 /* Unrolled SHA-256 round macros: */
477 #if BYTE_ORDER == LITTLE_ENDIAN
479 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
480 REVERSE32(*data++, W256[j]); \
481 T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
482 K256[j] + W256[j]; \
483 (d) += T1; \
484 (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
488 #else /* BYTE_ORDER == LITTLE_ENDIAN */
490 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
491 T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
492 K256[j] + (W256[j] = *data++); \
493 (d) += T1; \
494 (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
497 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
499 #define ROUND256(a,b,c,d,e,f,g,h) \
500 s0 = W256[(j+1)&0x0f]; \
501 s0 = sigma0_256(s0); \
502 s1 = W256[(j+14)&0x0f]; \
503 s1 = sigma1_256(s1); \
504 T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
505 (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
506 (d) += T1; \
507 (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
510 static void SHA256_Transform(SHA256_CTX* sha, const sha2_word32* data) {
511 sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
512 sha2_word32 T1, *W256;
513 int j;
515 W256 = (sha2_word32*)sha->buffer;
517 /* Initialize registers with the prev. intermediate value */
518 a = sha->state[0];
519 b = sha->state[1];
520 c = sha->state[2];
521 d = sha->state[3];
522 e = sha->state[4];
523 f = sha->state[5];
524 g = sha->state[6];
525 h = sha->state[7];
527 j = 0;
528 do {
529 /* Rounds 0 to 15 (unrolled): */
530 ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
531 ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
532 ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
533 ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
534 ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
535 ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
536 ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
537 ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
538 } while (j < 16);
540 /* Now for the remaining rounds to 64: */
541 do {
542 ROUND256(a,b,c,d,e,f,g,h);
543 ROUND256(h,a,b,c,d,e,f,g);
544 ROUND256(g,h,a,b,c,d,e,f);
545 ROUND256(f,g,h,a,b,c,d,e);
546 ROUND256(e,f,g,h,a,b,c,d);
547 ROUND256(d,e,f,g,h,a,b,c);
548 ROUND256(c,d,e,f,g,h,a,b);
549 ROUND256(b,c,d,e,f,g,h,a);
550 } while (j < 64);
552 /* Compute the current intermediate hash value */
553 sha->state[0] += a;
554 sha->state[1] += b;
555 sha->state[2] += c;
556 sha->state[3] += d;
557 sha->state[4] += e;
558 sha->state[5] += f;
559 sha->state[6] += g;
560 sha->state[7] += h;
562 /* Clean up */
563 a = b = c = d = e = f = g = h = T1 = 0;
566 #else /* SHA2_UNROLL_TRANSFORM */
568 static void SHA256_Transform(SHA256_CTX* sha, const sha2_word32* data) {
569 sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
570 sha2_word32 T1, T2, *W256;
571 int j;
573 W256 = (sha2_word32*)sha->buffer;
575 /* Initialize registers with the prev. intermediate value */
576 a = sha->state[0];
577 b = sha->state[1];
578 c = sha->state[2];
579 d = sha->state[3];
580 e = sha->state[4];
581 f = sha->state[5];
582 g = sha->state[6];
583 h = sha->state[7];
585 j = 0;
586 do {
587 #if BYTE_ORDER == LITTLE_ENDIAN
588 /* Copy data while converting to host byte order */
589 REVERSE32(*data++,W256[j]);
590 /* Apply the SHA-256 compression function to update a..h */
591 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
592 #else /* BYTE_ORDER == LITTLE_ENDIAN */
593 /* Apply the SHA-256 compression function to update a..h with copy */
594 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
595 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
596 T2 = Sigma0_256(a) + Maj(a, b, c);
597 h = g;
598 g = f;
599 f = e;
600 e = d + T1;
601 d = c;
602 c = b;
603 b = a;
604 a = T1 + T2;
606 j++;
607 } while (j < 16);
609 do {
610 /* Part of the message block expansion: */
611 s0 = W256[(j+1)&0x0f];
612 s0 = sigma0_256(s0);
613 s1 = W256[(j+14)&0x0f];
614 s1 = sigma1_256(s1);
616 /* Apply the SHA-256 compression function to update a..h */
617 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
618 (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
619 T2 = Sigma0_256(a) + Maj(a, b, c);
620 h = g;
621 g = f;
622 f = e;
623 e = d + T1;
624 d = c;
625 c = b;
626 b = a;
627 a = T1 + T2;
629 j++;
630 } while (j < 64);
632 /* Compute the current intermediate hash value */
633 sha->state[0] += a;
634 sha->state[1] += b;
635 sha->state[2] += c;
636 sha->state[3] += d;
637 sha->state[4] += e;
638 sha->state[5] += f;
639 sha->state[6] += g;
640 sha->state[7] += h;
642 /* Clean up */
643 a = b = c = d = e = f = g = h = T1 = T2 = 0;
646 #endif /* SHA2_UNROLL_TRANSFORM */
648 static int
649 sha256_block(register Sum_t* p, const void* s, size_t len)
651 Sha256_t* sha = (Sha256_t*)p;
652 sha2_byte* data = (sha2_byte*)s;
653 unsigned int freespace, usedspace;
655 if (!len)
656 return 0;
657 usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
658 if (usedspace > 0) {
659 /* Calculate how much free space is available in the buffer */
660 freespace = SHA256_BLOCK_LENGTH - usedspace;
662 if (len >= freespace) {
663 /* Fill the buffer completely and process it */
664 MEMCPY_BCOPY(&sha->buffer[usedspace], data, freespace);
665 sha->bitcount += freespace << 3;
666 len -= freespace;
667 data += freespace;
668 SHA256_Transform(sha, (sha2_word32*)sha->buffer);
669 } else {
670 /* The buffer is not yet full */
671 MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
672 sha->bitcount += len << 3;
673 /* Clean up: */
674 usedspace = freespace = 0;
675 return 0;
678 while (len >= SHA256_BLOCK_LENGTH) {
679 /* Process as many complete blocks as we can */
680 SHA256_Transform(sha, (sha2_word32*)data);
681 sha->bitcount += SHA256_BLOCK_LENGTH << 3;
682 len -= SHA256_BLOCK_LENGTH;
683 data += SHA256_BLOCK_LENGTH;
685 if (len > 0) {
686 /* There's left-overs, so save 'em */
687 MEMCPY_BCOPY(sha->buffer, data, len);
688 sha->bitcount += len << 3;
690 /* Clean up: */
691 usedspace = freespace = 0;
693 return 0;
696 static int
697 sha256_init(Sum_t* p)
699 register Sha256_t* sha = (Sha256_t*)p;
701 MEMCPY_BCOPY(sha->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
702 MEMSET_BZERO(sha->buffer, SHA256_BLOCK_LENGTH);
703 sha->bitcount = 0;
705 return 0;
708 static Sum_t*
709 sha256_open(const Method_t* method, const char* name)
711 Sha256_t* sha;
713 if (sha = newof(0, Sha256_t, 1, 0))
715 sha->method = (Method_t*)method;
716 sha->name = name;
717 sha256_init((Sum_t*)sha);
719 return (Sum_t*)sha;
722 static int
723 sha256_done(Sum_t* p)
725 Sha256_t* sha = (Sha256_t*)p;
726 unsigned int usedspace;
727 register int i;
729 /* Sanity check: */
730 assert(sha != (SHA256_CTX*)0);
732 usedspace = (sha->bitcount >> 3) % SHA256_BLOCK_LENGTH;
733 #if BYTE_ORDER == LITTLE_ENDIAN
734 /* Convert FROM host byte order */
735 REVERSE64(sha->bitcount,sha->bitcount);
736 #endif
737 if (usedspace > 0) {
738 /* Begin padding with a 1 bit: */
739 sha->buffer[usedspace++] = 0x80;
741 if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
742 /* Set-up for the last transform: */
743 MEMSET_BZERO(&sha->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
744 } else {
745 if (usedspace < SHA256_BLOCK_LENGTH) {
746 MEMSET_BZERO(&sha->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
748 /* Do second-to-last transform: */
749 SHA256_Transform(sha, (sha2_word32*)sha->buffer);
751 /* And set-up for the last transform: */
752 MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
754 } else {
755 /* Set-up for the last transform: */
756 MEMSET_BZERO(sha->buffer, SHA256_SHORT_BLOCK_LENGTH);
758 /* Begin padding with a 1 bit: */
759 *sha->buffer = 0x80;
761 /* Set the bit count: */
762 *(sha2_word64*)&sha->buffer[SHA256_SHORT_BLOCK_LENGTH] = sha->bitcount;
764 /* Final transform: */
765 SHA256_Transform(sha, (sha2_word32*)sha->buffer);
767 #if BYTE_ORDER == LITTLE_ENDIAN
769 /* Convert TO host byte order */
770 int j;
771 sha2_word32* d = (sha2_word32*)sha->digest;
772 for (j = 0; j < 8; j++) {
773 REVERSE32(sha->state[j],sha->state[j]);
774 *d++ = sha->state[j];
777 #else
778 MEMCPY_BCOPY(sha->digest, sha->state, SHA256_DIGEST_LENGTH);
779 #endif
781 /* accumulate the digests */
782 for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
783 sha->digest_sum[i] ^= sha->digest[i];
785 /* Clean up state data: */
786 MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha256_t, state));
787 usedspace = 0;
789 return 0;
792 static int
793 sha256_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
795 register Sha256_t* sha = (Sha256_t*)p;
796 register sha2_byte* d;
797 register sha2_byte* e;
799 d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
800 e = d + SHA256_DIGEST_LENGTH;
801 while (d < e)
802 sfprintf(sp, "%02x", *d++);
803 return 0;
806 static int
807 sha256_data(Sum_t* p, Sumdata_t* data)
809 register Sha256_t* sha = (Sha256_t*)p;
811 data->size = SHA256_DIGEST_LENGTH;
812 data->num = 0;
813 data->buf = sha->digest;
814 return 0;
817 /*** SHA-512: *********************************************************/
819 #define sha512_description "FIPS SHA-512 secure hash algorithm."
820 #define sha512_options "\
821 [+(version)?sha-512 (FIPS) 2000-01-01]\
822 [+(author)?Aaron D. Gifford]\
824 #define sha512_match "sha512|sha-512|SHA512|SHA-512"
825 #define sha512_scale 0
827 #define sha512_padding md5_pad
829 #define SHA512_CTX Sha512_t
831 typedef struct Sha512_s
833 _SUM_PUBLIC_
834 _SUM_PRIVATE_
835 sha2_byte digest[SHA512_DIGEST_LENGTH];
836 sha2_byte digest_sum[SHA512_DIGEST_LENGTH];
837 sha2_word64 state[8];
838 sha2_word64 bitcount[2];
839 sha2_byte buffer[SHA512_BLOCK_LENGTH];
840 } Sha512_t;
842 #ifdef SHA2_UNROLL_TRANSFORM
844 /* Unrolled SHA-512 round macros: */
845 #if BYTE_ORDER == LITTLE_ENDIAN
847 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
848 REVERSE64(*data++, W512[j]); \
849 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
850 K512[j] + W512[j]; \
851 (d) += T1, \
852 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
856 #else /* BYTE_ORDER == LITTLE_ENDIAN */
858 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
859 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
860 K512[j] + (W512[j] = *data++); \
861 (d) += T1; \
862 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
865 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
867 #define ROUND512(a,b,c,d,e,f,g,h) \
868 s0 = W512[(j+1)&0x0f]; \
869 s0 = sigma0_512(s0); \
870 s1 = W512[(j+14)&0x0f]; \
871 s1 = sigma1_512(s1); \
872 T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
873 (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
874 (d) += T1; \
875 (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
878 static void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
879 sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
880 sha2_word64 T1, *W512 = (sha2_word64*)sha->buffer;
881 int j;
883 /* Initialize registers with the prev. intermediate value */
884 a = sha->state[0];
885 b = sha->state[1];
886 c = sha->state[2];
887 d = sha->state[3];
888 e = sha->state[4];
889 f = sha->state[5];
890 g = sha->state[6];
891 h = sha->state[7];
893 j = 0;
894 do {
895 ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
896 ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
897 ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
898 ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
899 ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
900 ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
901 ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
902 ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
903 } while (j < 16);
905 /* Now for the remaining rounds up to 79: */
906 do {
907 ROUND512(a,b,c,d,e,f,g,h);
908 ROUND512(h,a,b,c,d,e,f,g);
909 ROUND512(g,h,a,b,c,d,e,f);
910 ROUND512(f,g,h,a,b,c,d,e);
911 ROUND512(e,f,g,h,a,b,c,d);
912 ROUND512(d,e,f,g,h,a,b,c);
913 ROUND512(c,d,e,f,g,h,a,b);
914 ROUND512(b,c,d,e,f,g,h,a);
915 } while (j < 80);
917 /* Compute the current intermediate hash value */
918 sha->state[0] += a;
919 sha->state[1] += b;
920 sha->state[2] += c;
921 sha->state[3] += d;
922 sha->state[4] += e;
923 sha->state[5] += f;
924 sha->state[6] += g;
925 sha->state[7] += h;
927 /* Clean up */
928 a = b = c = d = e = f = g = h = T1 = 0;
931 #else /* SHA2_UNROLL_TRANSFORM */
933 static void SHA512_Transform(SHA512_CTX* sha, const sha2_word64* data) {
934 sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
935 sha2_word64 T1, T2, *W512 = (sha2_word64*)sha->buffer;
936 int j;
938 /* Initialize registers with the prev. intermediate value */
939 a = sha->state[0];
940 b = sha->state[1];
941 c = sha->state[2];
942 d = sha->state[3];
943 e = sha->state[4];
944 f = sha->state[5];
945 g = sha->state[6];
946 h = sha->state[7];
948 j = 0;
949 do {
950 #if BYTE_ORDER == LITTLE_ENDIAN
951 /* Convert TO host byte order */
952 REVERSE64(*data++, W512[j]);
953 /* Apply the SHA-512 compression function to update a..h */
954 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
955 #else /* BYTE_ORDER == LITTLE_ENDIAN */
956 /* Apply the SHA-512 compression function to update a..h with copy */
957 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
958 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
959 T2 = Sigma0_512(a) + Maj(a, b, c);
960 h = g;
961 g = f;
962 f = e;
963 e = d + T1;
964 d = c;
965 c = b;
966 b = a;
967 a = T1 + T2;
969 j++;
970 } while (j < 16);
972 do {
973 /* Part of the message block expansion: */
974 s0 = W512[(j+1)&0x0f];
975 s0 = sigma0_512(s0);
976 s1 = W512[(j+14)&0x0f];
977 s1 = sigma1_512(s1);
979 /* Apply the SHA-512 compression function to update a..h */
980 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
981 (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
982 T2 = Sigma0_512(a) + Maj(a, b, c);
983 h = g;
984 g = f;
985 f = e;
986 e = d + T1;
987 d = c;
988 c = b;
989 b = a;
990 a = T1 + T2;
992 j++;
993 } while (j < 80);
995 /* Compute the current intermediate hash value */
996 sha->state[0] += a;
997 sha->state[1] += b;
998 sha->state[2] += c;
999 sha->state[3] += d;
1000 sha->state[4] += e;
1001 sha->state[5] += f;
1002 sha->state[6] += g;
1003 sha->state[7] += h;
1005 /* Clean up */
1006 a = b = c = d = e = f = g = h = T1 = T2 = 0;
1009 #endif /* SHA2_UNROLL_TRANSFORM */
1011 static int
1012 sha512_block(register Sum_t* p, const void* s, size_t len)
1014 Sha512_t* sha = (Sha512_t*)p;
1015 sha2_byte* data = (sha2_byte*)s;
1016 unsigned int freespace, usedspace;
1018 if (!len)
1019 return 0;
1020 usedspace = (sha->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
1021 if (usedspace > 0) {
1022 /* Calculate how much free space is available in the buffer */
1023 freespace = SHA512_BLOCK_LENGTH - usedspace;
1025 if (len >= freespace) {
1026 /* Fill the buffer completely and process it */
1027 MEMCPY_BCOPY(&sha->buffer[usedspace], data, freespace);
1028 ADDINC128(sha->bitcount, freespace << 3);
1029 len -= freespace;
1030 data += freespace;
1031 SHA512_Transform(sha, (sha2_word64*)sha->buffer);
1032 } else {
1033 /* The buffer is not yet full */
1034 MEMCPY_BCOPY(&sha->buffer[usedspace], data, len);
1035 ADDINC128(sha->bitcount, len << 3);
1036 /* Clean up: */
1037 usedspace = freespace = 0;
1038 return 0;
1041 while (len >= SHA512_BLOCK_LENGTH) {
1042 /* Process as many complete blocks as we can */
1043 SHA512_Transform(sha, (sha2_word64*)data);
1044 ADDINC128(sha->bitcount, SHA512_BLOCK_LENGTH << 3);
1045 len -= SHA512_BLOCK_LENGTH;
1046 data += SHA512_BLOCK_LENGTH;
1048 if (len > 0) {
1049 /* There's left-overs, so save 'em */
1050 MEMCPY_BCOPY(sha->buffer, data, len);
1051 ADDINC128(sha->bitcount, len << 3);
1053 /* Clean up: */
1054 usedspace = freespace = 0;
1056 return 0;
1059 static int
1060 sha512_init(Sum_t* p)
1062 register Sha512_t* sha = (Sha512_t*)p;
1064 MEMCPY_BCOPY(sha->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
1065 MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH);
1066 sha->bitcount[0] = sha->bitcount[1] = 0;
1068 return 0;
1071 static Sum_t*
1072 sha512_open(const Method_t* method, const char* name)
1074 Sha512_t* sha;
1076 if (sha = newof(0, Sha512_t, 1, 0))
1078 sha->method = (Method_t*)method;
1079 sha->name = name;
1080 sha512_init((Sum_t*)sha);
1082 return (Sum_t*)sha;
1085 static int
1086 sha512_done(Sum_t* p)
1088 Sha512_t* sha = (Sha512_t*)p;
1089 unsigned int usedspace;
1090 register int i;
1092 usedspace = (sha->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
1093 #if BYTE_ORDER == LITTLE_ENDIAN
1094 /* Convert FROM host byte order */
1095 REVERSE64(sha->bitcount[0],sha->bitcount[0]);
1096 REVERSE64(sha->bitcount[1],sha->bitcount[1]);
1097 #endif
1098 if (usedspace > 0) {
1099 /* Begin padding with a 1 bit: */
1100 sha->buffer[usedspace++] = 0x80;
1102 if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
1103 /* Set-up for the last transform: */
1104 MEMSET_BZERO(&sha->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
1105 } else {
1106 if (usedspace < SHA512_BLOCK_LENGTH) {
1107 MEMSET_BZERO(&sha->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
1109 /* Do second-to-last transform: */
1110 SHA512_Transform(sha, (sha2_word64*)sha->buffer);
1112 /* And set-up for the last transform: */
1113 MEMSET_BZERO(sha->buffer, SHA512_BLOCK_LENGTH - 2);
1115 } else {
1116 /* Prepare for final transform: */
1117 MEMSET_BZERO(sha->buffer, SHA512_SHORT_BLOCK_LENGTH);
1119 /* Begin padding with a 1 bit: */
1120 *sha->buffer = 0x80;
1122 /* Store the length of input data (in bits): */
1123 *(sha2_word64*)&sha->buffer[SHA512_SHORT_BLOCK_LENGTH] = sha->bitcount[1];
1124 *(sha2_word64*)&sha->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = sha->bitcount[0];
1126 /* Final transform: */
1127 SHA512_Transform(sha, (sha2_word64*)sha->buffer);
1129 #if BYTE_ORDER == LITTLE_ENDIAN
1131 /* Convert TO host byte order */
1132 sha2_word64* d = (sha2_word64*)sha->digest;
1133 int j;
1134 for (j = 0; j < 8; j++) {
1135 REVERSE64(sha->state[j],sha->state[j]);
1136 *d++ = sha->state[j];
1139 #else
1140 MEMCPY_BCOPY(sha->digest, sha->state, SHA512_DIGEST_LENGTH);
1141 #endif
1143 /* accumulate the digests */
1144 for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
1145 sha->digest_sum[i] ^= sha->digest[i];
1147 /* Clean up state data: */
1148 MEMSET_BZERO(&sha->state, sizeof(*sha) - offsetof(Sha512_t, state));
1149 usedspace = 0;
1151 return 0;
1154 static int
1155 sha512_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
1157 register Sha512_t* sha = (Sha512_t*)p;
1158 register sha2_byte* d;
1159 register sha2_byte* e;
1161 d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
1162 e = d + SHA512_DIGEST_LENGTH;
1163 while (d < e)
1164 sfprintf(sp, "%02x", *d++);
1165 return 0;
1168 static int
1169 sha512_data(Sum_t* p, Sumdata_t* data)
1171 register Sha512_t* sha = (Sha512_t*)p;
1173 data->size = SHA512_DIGEST_LENGTH;
1174 data->num = 0;
1175 data->buf = sha->digest;
1176 return 0;
1179 /*** SHA-384: *********************************************************/
1181 #define sha384_description "FIPS SHA-384 secure hash algorithm."
1182 #define sha384_options "\
1183 [+(version)?sha-384 (FIPS) 2000-01-01]\
1184 [+(author)?Aaron D. Gifford]\
1186 #define sha384_match "sha384|sha-384|SHA384|SHA-384"
1187 #define sha384_scale 0
1188 #define sha384_block sha512_block
1189 #define sha384_done sha512_done
1191 #define sha384_padding md5_pad
1193 #define Sha384_t Sha512_t
1194 #define SHA384_CTX Sha384_t
1195 #define SHA384_DIGEST_LENGTH 48
1197 static int
1198 sha384_init(Sum_t* p)
1200 register Sha384_t* sha = (Sha384_t*)p;
1202 MEMCPY_BCOPY(sha->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
1203 MEMSET_BZERO(sha->buffer, SHA384_BLOCK_LENGTH);
1204 sha->bitcount[0] = sha->bitcount[1] = 0;
1206 return 0;
1209 static Sum_t*
1210 sha384_open(const Method_t* method, const char* name)
1212 Sha384_t* sha;
1214 if (sha = newof(0, Sha384_t, 1, 0))
1216 sha->method = (Method_t*)method;
1217 sha->name = name;
1218 sha384_init((Sum_t*)sha);
1220 return (Sum_t*)sha;
1223 static int
1224 sha384_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
1226 register Sha384_t* sha = (Sha384_t*)p;
1227 register sha2_byte* d;
1228 register sha2_byte* e;
1230 d = (flags & SUM_TOTAL) ? sha->digest_sum : sha->digest;
1231 e = d + SHA384_DIGEST_LENGTH;
1232 while (d < e)
1233 sfprintf(sp, "%02x", *d++);
1234 return 0;
1237 static int
1238 sha384_data(Sum_t* p, Sumdata_t* data)
1240 register Sha384_t* sha = (Sha384_t*)p;
1242 data->size = SHA384_DIGEST_LENGTH;
1243 data->num = 0;
1244 data->buf = sha->digest;
1245 return 0;
1248 #endif /* _typ_int64_t */