sha2.c

Go to the documentation of this file.
00001 /*
00002  * FILE:        sha2.c
00003  * AUTHOR:      Aaron D. Gifford <me@aarongifford.com>
00004  * 
00005  * Copyright (c) 2000-2001, Aaron D. Gifford
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the copyright holder nor the names of contributors
00017  *    may be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  * 
00020  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
00024  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00025  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00026  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00027  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00028  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00029  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
00033  */
00034 
00035 #include <sys/types.h>
00036 #include <string.h>     /* memcpy()/memset() or bcopy()/bzero() */
00037 /* #include <assert.h> */   /* assert() */
00038 #include <stdio.h>
00039 #include <sysexits.h>
00040 #include <sys/uio.h>
00041 #include <unistd.h>
00042 #include <inttypes.h>
00043 
00044 #include "sha2.h"
00045 
00046 
00047 /*
00048  * ASSERT NOTE:
00049  * Some sanity checking code is included using assert().  On my FreeBSD
00050  * system, this additional code can be removed by compiling with NDEBUG
00051  * defined.  Check your own systems manpage on assert() to see how to
00052  * compile WITHOUT the sanity checking code on your system.
00053  *
00054  * UNROLLED TRANSFORM LOOP NOTE:
00055  * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
00056  * loop version for the hash transform rounds (defined using macros
00057  * later in this file).  Either define on the command line, for example:
00058  *
00059  *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
00060  *
00061  * or define below:
00062  *
00063  *   #define SHA2_UNROLL_TRANSFORM
00064  *
00065  */
00066 
00067  #define SHA2_UNROLL_TRANSFORM
00068 
00069 
00070 /*** SHA-256/384/512 Machine Architecture Definitions *****************/
00071 /*
00072  * BYTE_ORDER NOTE:
00073  *
00074  * Please make sure that your system defines BYTE_ORDER.  If your
00075  * architecture is little-endian, make sure it also defines
00076  * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
00077  * equivilent.
00078  *
00079  * If your system does not define the above, then you can do so by
00080  * hand like this:
00081  *
00082  *   #define LITTLE_ENDIAN 1234
00083  *   #define BIG_ENDIAN    4321
00084  *
00085  * And for little-endian machines, add:
00086  *
00087  *   #define BYTE_ORDER LITTLE_ENDIAN 
00088  *
00089  * Or for big-endian machines:
00090  *
00091  *   #define BYTE_ORDER BIG_ENDIAN
00092  *
00093  * The FreeBSD machine this was written on defines BYTE_ORDER
00094  * appropriately by including <sys/types.h> (which in turn includes
00095  * <machine/endian.h> where the appropriate definitions are actually
00096  * made).
00097  */
00098 
00099 /*
00100  * Define the following sha2_* types to types of the correct length on
00101  * the native archtecture.   Most BSD systems and Linux define u_intXX_t
00102  * types.  Machines with very recent ANSI C headers, can use the
00103  * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
00104  * during compile or in the sha.h header file.
00105  *
00106  * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
00107  * will need to define these three typedefs below (and the appropriate
00108  * ones in sha.h too) by hand according to their system architecture.
00109  *
00110  * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
00111  * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
00112  */
00113 typedef uint8_t  sha2_byte;     /* Exactly 1 byte */
00114 typedef uint32_t sha2_word32;   /* Exactly 4 bytes */
00115 typedef uint64_t sha2_word64;   /* Exactly 8 bytes */
00116 
00117 
00118 /*** SHA-256/384/512 Various Length Definitions ***********************/
00119 /* NOTE: Most of these are in sha2.h */
00120 #define SHA256_SHORT_BLOCK_LENGTH       (SHA256_BLOCK_LENGTH - 8)
00121 #define SHA384_SHORT_BLOCK_LENGTH       (SHA384_BLOCK_LENGTH - 16)
00122 #define SHA512_SHORT_BLOCK_LENGTH       (SHA512_BLOCK_LENGTH - 16)
00123 
00124 
00125 /*** ENDIAN REVERSAL MACROS *******************************************/
00126 #ifndef WORDS_BIGENDIAN
00127 #define REVERSE32(w,x)  { \
00128         sha2_word32 tmp = (w); \
00129         tmp = (tmp >> 16) | (tmp << 16); \
00130         (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
00131 }
00132 #define REVERSE64(w,x)  { \
00133         sha2_word64 tmp = (w); \
00134         tmp = (tmp >> 32) | (tmp << 32); \
00135         tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
00136               ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
00137         (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
00138               ((tmp & 0x0000ffff0000ffffULL) << 16); \
00139 }
00140 #endif /* !WORDS_BIGENDIAN */
00141 
00142 /*
00143  * Macro for incrementally adding the unsigned 64-bit integer n to the
00144  * unsigned 128-bit integer (represented using a two-element array of
00145  * 64-bit words):
00146  */
00147 #define ADDINC128(w,n)  { \
00148         (w)[0] += (sha2_word64)(n); \
00149         if ((w)[0] < (n)) { \
00150                 (w)[1]++; \
00151         } \
00152 }
00153 
00154 /*
00155  * Macros for copying blocks of memory and for zeroing out ranges
00156  * of memory.  Using these macros makes it easy to switch from
00157  * using memset()/memcpy() and using bzero()/bcopy().
00158  *
00159  * Please define either SHA2_USE_MEMSET_MEMCPY or define
00160  * SHA2_USE_BZERO_BCOPY depending on which function set you
00161  * choose to use:
00162  */
00163 #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
00164 /* Default to memset()/memcpy() if no option is specified */
00165 #define SHA2_USE_MEMSET_MEMCPY  1
00166 #endif
00167 #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
00168 /* Abort with an error if BOTH options are defined */
00169 #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
00170 #endif
00171 
00172 #ifdef SHA2_USE_MEMSET_MEMCPY
00173 #define MEMSET_BZERO(p,l)       memset((p), 0, (l))
00174 #define MEMCPY_BCOPY(d,s,l)     memcpy((d), (s), (l))
00175 #endif
00176 #ifdef SHA2_USE_BZERO_BCOPY
00177 #define MEMSET_BZERO(p,l)       bzero((p), (l))
00178 #define MEMCPY_BCOPY(d,s,l)     bcopy((s), (d), (l))
00179 #endif
00180 
00181 
00182 /*** THE SIX LOGICAL FUNCTIONS ****************************************/
00183 /*
00184  * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
00185  *
00186  *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
00187  *   S is a ROTATION) because the SHA-256/384/512 description document
00188  *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
00189  *   same "backwards" definition.
00190  */
00191 /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
00192 #define R(b,x)          ((x) >> (b))
00193 /* 32-bit Rotate-right (used in SHA-256): */
00194 #define S32(b,x)        (((x) >> (b)) | ((x) << (32 - (b))))
00195 /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
00196 #define S64(b,x)        (((x) >> (b)) | ((x) << (64 - (b))))
00197 
00198 /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
00199 #define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
00200 #define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
00201 
00202 /* Four of six logical functions used in SHA-256: */
00203 #define Sigma0_256(x)   (S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
00204 #define Sigma1_256(x)   (S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
00205 #define sigma0_256(x)   (S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
00206 #define sigma1_256(x)   (S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
00207 
00208 /* Four of six logical functions used in SHA-384 and SHA-512: */
00209 #define Sigma0_512(x)   (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
00210 #define Sigma1_512(x)   (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
00211 #define sigma0_512(x)   (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
00212 #define sigma1_512(x)   (S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
00213 
00214 /*** INTERNAL FUNCTION PROTOTYPES *************************************/
00215 /* NOTE: These should not be accessed directly from outside this
00216  * library -- they are intended for private internal visibility/use
00217  * only.
00218  */
00219 static void SHA512_Last(SHA512_CTX*);
00220 static void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
00221 static void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
00222 
00223 
00224 /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
00225 /* Hash constant words K for SHA-256: */
00226 const static sha2_word32 K256[64] = {
00227         0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
00228         0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
00229         0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
00230         0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
00231         0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
00232         0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
00233         0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
00234         0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
00235         0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
00236         0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
00237         0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
00238         0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
00239         0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
00240         0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
00241         0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
00242         0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
00243 };
00244 
00245 /* Initial hash value H for SHA-256: */
00246 const static sha2_word32 sha256_initial_hash_value[8] = {
00247         0x6a09e667UL,
00248         0xbb67ae85UL,
00249         0x3c6ef372UL,
00250         0xa54ff53aUL,
00251         0x510e527fUL,
00252         0x9b05688cUL,
00253         0x1f83d9abUL,
00254         0x5be0cd19UL
00255 };
00256 
00257 /* Hash constant words K for SHA-384 and SHA-512: */
00258 const static sha2_word64 K512[80] = {
00259         0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
00260         0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
00261         0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
00262         0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
00263         0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
00264         0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
00265         0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
00266         0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
00267         0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
00268         0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
00269         0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
00270         0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
00271         0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
00272         0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
00273         0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
00274         0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
00275         0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
00276         0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
00277         0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
00278         0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
00279         0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
00280         0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
00281         0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
00282         0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
00283         0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
00284         0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
00285         0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
00286         0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
00287         0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
00288         0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
00289         0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
00290         0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
00291         0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
00292         0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
00293         0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
00294         0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
00295         0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
00296         0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
00297         0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
00298         0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
00299 };
00300 
00301 /* Initial hash value H for SHA-384 */
00302 const static sha2_word64 sha384_initial_hash_value[8] = {
00303         0xcbbb9d5dc1059ed8ULL,
00304         0x629a292a367cd507ULL,
00305         0x9159015a3070dd17ULL,
00306         0x152fecd8f70e5939ULL,
00307         0x67332667ffc00b31ULL,
00308         0x8eb44a8768581511ULL,
00309         0xdb0c2e0d64f98fa7ULL,
00310         0x47b5481dbefa4fa4ULL
00311 };
00312 
00313 /* Initial hash value H for SHA-512 */
00314 const static sha2_word64 sha512_initial_hash_value[8] = {
00315         0x6a09e667f3bcc908ULL,
00316         0xbb67ae8584caa73bULL,
00317         0x3c6ef372fe94f82bULL,
00318         0xa54ff53a5f1d36f1ULL,
00319         0x510e527fade682d1ULL,
00320         0x9b05688c2b3e6c1fULL,
00321         0x1f83d9abfb41bd6bULL,
00322         0x5be0cd19137e2179ULL
00323 };
00324 
00325 /*
00326  * Constant used by SHA256/384/512_End() functions for converting the
00327  * digest to a readable hexadecimal character string:
00328  */
00329 static const char *sha2_hex_digits = "0123456789abcdef";
00330 
00331 
00332 /*** SHA-256: *********************************************************/
00333 void sat_SHA256_Init(SHA256_CTX* context) {
00334         if (context == (SHA256_CTX*)0) {
00335                 return;
00336         }
00337         MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
00338         MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
00339         context->bitcount = 0;
00340 }
00341 
00342 #ifdef SHA2_UNROLL_TRANSFORM
00343 
00344 /* Unrolled SHA-256 round macros: */
00345 
00346 #ifndef WORDS_BIGENDIAN
00347 
00348 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)       \
00349         REVERSE32(*data++, W256[j]); \
00350         T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
00351              K256[j] + W256[j]; \
00352         (d) += T1; \
00353         (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
00354         j++
00355 
00356 
00357 #else /* !WORDS_BIGENDIAN */
00358 
00359 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)       \
00360         T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
00361              K256[j] + (W256[j] = *data++); \
00362         (d) += T1; \
00363         (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
00364         j++
00365 
00366 #endif /* !WORDS_BIGENDIAN */
00367 
00368 #define ROUND256(a,b,c,d,e,f,g,h)       \
00369         s0 = W256[(j+1)&0x0f]; \
00370         s0 = sigma0_256(s0); \
00371         s1 = W256[(j+14)&0x0f]; \
00372         s1 = sigma1_256(s1); \
00373         T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
00374              (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
00375         (d) += T1; \
00376         (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
00377         j++
00378 
00379 static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
00380         sha2_word32     a, b, c, d, e, f, g, h, s0, s1;
00381         sha2_word32     T1, *W256;
00382         int             j;
00383 
00384         W256 = (sha2_word32*)context->buffer;
00385 
00386         /* Initialize registers with the prev. intermediate value */
00387         a = context->state[0];
00388         b = context->state[1];
00389         c = context->state[2];
00390         d = context->state[3];
00391         e = context->state[4];
00392         f = context->state[5];
00393         g = context->state[6];
00394         h = context->state[7];
00395 
00396         j = 0;
00397         do {
00398                 /* Rounds 0 to 15 (unrolled): */
00399                 ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
00400                 ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
00401                 ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
00402                 ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
00403                 ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
00404                 ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
00405                 ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
00406                 ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
00407         } while (j < 16);
00408 
00409         /* Now for the remaining rounds to 64: */
00410         do {
00411                 ROUND256(a,b,c,d,e,f,g,h);
00412                 ROUND256(h,a,b,c,d,e,f,g);
00413                 ROUND256(g,h,a,b,c,d,e,f);
00414                 ROUND256(f,g,h,a,b,c,d,e);
00415                 ROUND256(e,f,g,h,a,b,c,d);
00416                 ROUND256(d,e,f,g,h,a,b,c);
00417                 ROUND256(c,d,e,f,g,h,a,b);
00418                 ROUND256(b,c,d,e,f,g,h,a);
00419         } while (j < 64);
00420 
00421         /* Compute the current intermediate hash value */
00422         context->state[0] += a;
00423         context->state[1] += b;
00424         context->state[2] += c;
00425         context->state[3] += d;
00426         context->state[4] += e;
00427         context->state[5] += f;
00428         context->state[6] += g;
00429         context->state[7] += h;
00430 
00431         /* Clean up */
00432         a = b = c = d = e = f = g = h = T1 = 0;
00433 }
00434 
00435 #else /* SHA2_UNROLL_TRANSFORM */
00436 
00437 static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
00438         sha2_word32     a, b, c, d, e, f, g, h, s0, s1;
00439         sha2_word32     T1, T2, *W256;
00440         int             j;
00441 
00442         W256 = (sha2_word32*)context->buffer;
00443 
00444         /* Initialize registers with the prev. intermediate value */
00445         a = context->state[0];
00446         b = context->state[1];
00447         c = context->state[2];
00448         d = context->state[3];
00449         e = context->state[4];
00450         f = context->state[5];
00451         g = context->state[6];
00452         h = context->state[7];
00453 
00454         j = 0;
00455         do {
00456 #ifndef WORDS_BIGENDIAN
00457                 /* Copy data while converting to host byte order */
00458                 REVERSE32(*data++,W256[j]);
00459                 /* Apply the SHA-256 compression function to update a..h */
00460                 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
00461 #else /* !WORDS_BIGENDIAN */
00462                 /* Apply the SHA-256 compression function to update a..h with copy */
00463                 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
00464 #endif /* !WORDS_BIGENDIAN */
00465                 T2 = Sigma0_256(a) + Maj(a, b, c);
00466                 h = g;
00467                 g = f;
00468                 f = e;
00469                 e = d + T1;
00470                 d = c;
00471                 c = b;
00472                 b = a;
00473                 a = T1 + T2;
00474 
00475                 j++;
00476         } while (j < 16);
00477 
00478         do {
00479                 /* Part of the message block expansion: */
00480                 s0 = W256[(j+1)&0x0f];
00481                 s0 = sigma0_256(s0);
00482                 s1 = W256[(j+14)&0x0f]; 
00483                 s1 = sigma1_256(s1);
00484 
00485                 /* Apply the SHA-256 compression function to update a..h */
00486                 T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 
00487                      (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
00488                 T2 = Sigma0_256(a) + Maj(a, b, c);
00489                 h = g;
00490                 g = f;
00491                 f = e;
00492                 e = d + T1;
00493                 d = c;
00494                 c = b;
00495                 b = a;
00496                 a = T1 + T2;
00497 
00498                 j++;
00499         } while (j < 64);
00500 
00501         /* Compute the current intermediate hash value */
00502         context->state[0] += a;
00503         context->state[1] += b;
00504         context->state[2] += c;
00505         context->state[3] += d;
00506         context->state[4] += e;
00507         context->state[5] += f;
00508         context->state[6] += g;
00509         context->state[7] += h;
00510 
00511         /* Clean up */
00512         a = b = c = d = e = f = g = h = T1 = T2 = 0;
00513 }
00514 
00515 #endif /* SHA2_UNROLL_TRANSFORM */
00516 
00517 void sat_SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
00518         unsigned int    freespace, usedspace;
00519 
00520         if (len == 0) {
00521                 /* Calling with no data is valid - we do nothing */
00522                 return;
00523         }
00524 
00525         /* Sanity check: */
00526         /* assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); */
00527 
00528         usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
00529         if (usedspace > 0) {
00530                 /* Calculate how much free space is available in the buffer */
00531                 freespace = SHA256_BLOCK_LENGTH - usedspace;
00532 
00533                 if (len >= freespace) {
00534                         /* Fill the buffer completely and process it */
00535                         MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
00536                         context->bitcount += freespace << 3;
00537                         len -= freespace;
00538                         data += freespace;
00539                         SHA256_Transform(context, (sha2_word32*)context->buffer);
00540                 } else {
00541                         /* The buffer is not yet full */
00542                         MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
00543                         context->bitcount += len << 3;
00544                         /* Clean up: */
00545                         usedspace = freespace = 0;
00546                         return;
00547                 }
00548         }
00549         while (len >= SHA256_BLOCK_LENGTH) {
00550                 /* Process as many complete blocks as we can */
00551                 SHA256_Transform(context, (sha2_word32*)data);
00552                 context->bitcount += SHA256_BLOCK_LENGTH << 3;
00553                 len -= SHA256_BLOCK_LENGTH;
00554                 data += SHA256_BLOCK_LENGTH;
00555         }
00556         if (len > 0) {
00557                 /* There's left-overs, so save 'em */
00558                 MEMCPY_BCOPY(context->buffer, data, len);
00559                 context->bitcount += len << 3;
00560         }
00561         /* Clean up: */
00562         usedspace = freespace = 0;
00563 }
00564 
00565 void sat_SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
00566         sha2_word32     *d = (sha2_word32*)digest;
00567         unsigned int    usedspace;
00568 
00569         /* Sanity check: */
00570         /* assert(context != (SHA256_CTX*)0); */
00571 
00572         /* If no digest buffer is passed, we don't bother doing this: */
00573         if (digest != (sha2_byte*)0) {
00574                 usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
00575 #ifndef WORDS_BIGENDIAN
00576                 /* Convert FROM host byte order */
00577                 REVERSE64(context->bitcount,context->bitcount);
00578 #endif
00579                 if (usedspace > 0) {
00580                         /* Begin padding with a 1 bit: */
00581                         context->buffer[usedspace++] = 0x80;
00582 
00583                         if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
00584                                 /* Set-up for the last transform: */
00585                                 MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
00586                         } else {
00587                                 if (usedspace < SHA256_BLOCK_LENGTH) {
00588                                         MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
00589                                 }
00590                                 /* Do second-to-last transform: */
00591                                 SHA256_Transform(context, (sha2_word32*)context->buffer);
00592 
00593                                 /* And set-up for the last transform: */
00594                                 MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
00595                         }
00596                 } else {
00597                         /* Set-up for the last transform: */
00598                         MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
00599 
00600                         /* Begin padding with a 1 bit: */
00601                         *context->buffer = 0x80;
00602                 }
00603                 /* Set the bit count: */
00604                 *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
00605 
00606                 /* Final transform: */
00607                 SHA256_Transform(context, (sha2_word32*)context->buffer);
00608 
00609 #ifndef WORDS_BIGENDIAN
00610                 {
00611                         /* Convert TO host byte order */
00612                         int     j;
00613                         for (j = 0; j < 8; j++) {
00614                                 REVERSE32(context->state[j],context->state[j]);
00615                                 *d++ = context->state[j];
00616                         }
00617                 }
00618 #else
00619                 MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
00620 #endif
00621         }
00622 
00623         /* Clean up state data: */
00624         MEMSET_BZERO(context, sizeof(context));
00625         usedspace = 0;
00626 }
00627 
00628 char *sat_SHA256_End(SHA256_CTX* context, char buffer[]) {
00629         sha2_byte       digest[SHA256_DIGEST_LENGTH], *d = digest;
00630         int             i;
00631 
00632         /* Sanity check: */
00633         /* assert(context != (SHA256_CTX*)0); */
00634 
00635         if (buffer != (char*)0) {
00636                 sat_SHA256_Final(digest, context);
00637 
00638                 for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
00639                         *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
00640                         *buffer++ = sha2_hex_digits[*d & 0x0f];
00641                         d++;
00642                 }
00643                 *buffer = (char)0;
00644         } else {
00645                 MEMSET_BZERO(context, sizeof(context));
00646         }
00647         MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
00648         return buffer;
00649 }
00650 
00651 char* sat_SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
00652         SHA256_CTX      context;
00653 
00654         sat_SHA256_Init(&context);
00655         sat_SHA256_Update(&context, data, len);
00656         return sat_SHA256_End(&context, digest);
00657 }
00658 
00659 
00660 /*** SHA-512: *********************************************************/
00661 void sat_SHA512_Init(SHA512_CTX* context) {
00662         if (context == (SHA512_CTX*)0) {
00663                 return;
00664         }
00665         MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
00666         MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
00667         context->bitcount[0] = context->bitcount[1] =  0;
00668 }
00669 
00670 #ifdef SHA2_UNROLL_TRANSFORM
00671 
00672 /* Unrolled SHA-512 round macros: */
00673 #ifndef WORDS_BIGENDIAN
00674 
00675 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)       \
00676         REVERSE64(*data++, W512[j]); \
00677         T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
00678              K512[j] + W512[j]; \
00679         (d) += T1, \
00680         (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
00681         j++
00682 
00683 
00684 #else /* !WORDS_BIGENDIAN */
00685 
00686 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)       \
00687         T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
00688              K512[j] + (W512[j] = *data++); \
00689         (d) += T1; \
00690         (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
00691         j++
00692 
00693 #endif /* !WORDS_BIGENDIAN */
00694 
00695 #define ROUND512(a,b,c,d,e,f,g,h)       \
00696         s0 = W512[(j+1)&0x0f]; \
00697         s0 = sigma0_512(s0); \
00698         s1 = W512[(j+14)&0x0f]; \
00699         s1 = sigma1_512(s1); \
00700         T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
00701              (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
00702         (d) += T1; \
00703         (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
00704         j++
00705 
00706 static void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
00707         sha2_word64     a, b, c, d, e, f, g, h, s0, s1;
00708         sha2_word64     T1, *W512 = (sha2_word64*)context->buffer;
00709         int             j;
00710 
00711         /* Initialize registers with the prev. intermediate value */
00712         a = context->state[0];
00713         b = context->state[1];
00714         c = context->state[2];
00715         d = context->state[3];
00716         e = context->state[4];
00717         f = context->state[5];
00718         g = context->state[6];
00719         h = context->state[7];
00720 
00721         j = 0;
00722         do {
00723                 ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
00724                 ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
00725                 ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
00726                 ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
00727                 ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
00728                 ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
00729                 ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
00730                 ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
00731         } while (j < 16);
00732 
00733         /* Now for the remaining rounds up to 79: */
00734         do {
00735                 ROUND512(a,b,c,d,e,f,g,h);
00736                 ROUND512(h,a,b,c,d,e,f,g);
00737                 ROUND512(g,h,a,b,c,d,e,f);
00738                 ROUND512(f,g,h,a,b,c,d,e);
00739                 ROUND512(e,f,g,h,a,b,c,d);
00740                 ROUND512(d,e,f,g,h,a,b,c);
00741                 ROUND512(c,d,e,f,g,h,a,b);
00742                 ROUND512(b,c,d,e,f,g,h,a);
00743         } while (j < 80);
00744 
00745         /* Compute the current intermediate hash value */
00746         context->state[0] += a;
00747         context->state[1] += b;
00748         context->state[2] += c;
00749         context->state[3] += d;
00750         context->state[4] += e;
00751         context->state[5] += f;
00752         context->state[6] += g;
00753         context->state[7] += h;
00754 
00755         /* Clean up */
00756         a = b = c = d = e = f = g = h = T1 = 0;
00757 }
00758 
00759 #else /* SHA2_UNROLL_TRANSFORM */
00760 
00761 static void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
00762         sha2_word64     a, b, c, d, e, f, g, h, s0, s1;
00763         sha2_word64     T1, T2, *W512 = (sha2_word64*)context->buffer;
00764         int             j;
00765 
00766         /* Initialize registers with the prev. intermediate value */
00767         a = context->state[0];
00768         b = context->state[1];
00769         c = context->state[2];
00770         d = context->state[3];
00771         e = context->state[4];
00772         f = context->state[5];
00773         g = context->state[6];
00774         h = context->state[7];
00775 
00776         j = 0;
00777         do {
00778 #ifndef WORDS_BIGENDIAN
00779                 /* Convert TO host byte order */
00780                 REVERSE64(*data++, W512[j]);
00781                 /* Apply the SHA-512 compression function to update a..h */
00782                 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
00783 #else /* !WORDS_BIGENDIAN */
00784                 /* Apply the SHA-512 compression function to update a..h with copy */
00785                 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
00786 #endif /* !WORDS_BIGENDIAN */
00787                 T2 = Sigma0_512(a) + Maj(a, b, c);
00788                 h = g;
00789                 g = f;
00790                 f = e;
00791                 e = d + T1;
00792                 d = c;
00793                 c = b;
00794                 b = a;
00795                 a = T1 + T2;
00796 
00797                 j++;
00798         } while (j < 16);
00799 
00800         do {
00801                 /* Part of the message block expansion: */
00802                 s0 = W512[(j+1)&0x0f];
00803                 s0 = sigma0_512(s0);
00804                 s1 = W512[(j+14)&0x0f];
00805                 s1 =  sigma1_512(s1);
00806 
00807                 /* Apply the SHA-512 compression function to update a..h */
00808                 T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
00809                      (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
00810                 T2 = Sigma0_512(a) + Maj(a, b, c);
00811                 h = g;
00812                 g = f;
00813                 f = e;
00814                 e = d + T1;
00815                 d = c;
00816                 c = b;
00817                 b = a;
00818                 a = T1 + T2;
00819 
00820                 j++;
00821         } while (j < 80);
00822 
00823         /* Compute the current intermediate hash value */
00824         context->state[0] += a;
00825         context->state[1] += b;
00826         context->state[2] += c;
00827         context->state[3] += d;
00828         context->state[4] += e;
00829         context->state[5] += f;
00830         context->state[6] += g;
00831         context->state[7] += h;
00832 
00833         /* Clean up */
00834         a = b = c = d = e = f = g = h = T1 = T2 = 0;
00835 }
00836 
00837 #endif /* SHA2_UNROLL_TRANSFORM */
00838 
00839 void sat_SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
00840         unsigned int    freespace, usedspace;
00841 
00842         if (len == 0) {
00843                 /* Calling with no data is valid - we do nothing */
00844                 return;
00845         }
00846 
00847         /* Sanity check: */
00848         /* assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); */
00849 
00850         usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
00851         if (usedspace > 0) {
00852                 /* Calculate how much free space is available in the buffer */
00853                 freespace = SHA512_BLOCK_LENGTH - usedspace;
00854 
00855                 if (len >= freespace) {
00856                         /* Fill the buffer completely and process it */
00857                         MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
00858                         ADDINC128(context->bitcount, freespace << 3);
00859                         len -= freespace;
00860                         data += freespace;
00861                         SHA512_Transform(context, (sha2_word64*)context->buffer);
00862                 } else {
00863                         /* The buffer is not yet full */
00864                         MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
00865                         ADDINC128(context->bitcount, len << 3);
00866                         /* Clean up: */
00867                         usedspace = freespace = 0;
00868                         return;
00869                 }
00870         }
00871         while (len >= SHA512_BLOCK_LENGTH) {
00872                 /* Process as many complete blocks as we can */
00873                 SHA512_Transform(context, (sha2_word64*)data);
00874                 ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
00875                 len -= SHA512_BLOCK_LENGTH;
00876                 data += SHA512_BLOCK_LENGTH;
00877         }
00878         if (len > 0) {
00879                 /* There's left-overs, so save 'em */
00880                 MEMCPY_BCOPY(context->buffer, data, len);
00881                 ADDINC128(context->bitcount, len << 3);
00882         }
00883         /* Clean up: */
00884         usedspace = freespace = 0;
00885 }
00886 
00887 static void SHA512_Last(SHA512_CTX* context) {
00888         unsigned int    usedspace;
00889 
00890         usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
00891 #ifndef WORDS_BIGENDIAN
00892         /* Convert FROM host byte order */
00893         REVERSE64(context->bitcount[0],context->bitcount[0]);
00894         REVERSE64(context->bitcount[1],context->bitcount[1]);
00895 #endif
00896         if (usedspace > 0) {
00897                 /* Begin padding with a 1 bit: */
00898                 context->buffer[usedspace++] = 0x80;
00899 
00900                 if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
00901                         /* Set-up for the last transform: */
00902                         MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
00903                 } else {
00904                         if (usedspace < SHA512_BLOCK_LENGTH) {
00905                                 MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
00906                         }
00907                         /* Do second-to-last transform: */
00908                         SHA512_Transform(context, (sha2_word64*)context->buffer);
00909 
00910                         /* And set-up for the last transform: */
00911                         MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
00912                 }
00913         } else {
00914                 /* Prepare for final transform: */
00915                 MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
00916 
00917                 /* Begin padding with a 1 bit: */
00918                 *context->buffer = 0x80;
00919         }
00920         /* Store the length of input data (in bits): */
00921         *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
00922         *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
00923 
00924         /* Final transform: */
00925         SHA512_Transform(context, (sha2_word64*)context->buffer);
00926 }
00927 
00928 void sat_SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
00929         sha2_word64     *d = (sha2_word64*)digest;
00930 
00931         /* Sanity check: */
00932         /* assert(context != (SHA512_CTX*)0); */
00933 
00934         /* If no digest buffer is passed, we don't bother doing this: */
00935         if (digest != (sha2_byte*)0) {
00936                 SHA512_Last(context);
00937 
00938                 /* Save the hash data for output: */
00939 #ifndef WORDS_BIGENDIAN
00940                 {
00941                         /* Convert TO host byte order */
00942                         int     j;
00943                         for (j = 0; j < 8; j++) {
00944                                 REVERSE64(context->state[j],context->state[j]);
00945                                 *d++ = context->state[j];
00946                         }
00947                 }
00948 #else
00949                 MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
00950 #endif
00951         }
00952 
00953         /* Zero out state data */
00954         MEMSET_BZERO(context, sizeof(context));
00955 }
00956 
00957 char *sat_SHA512_End(SHA512_CTX* context, char buffer[]) {
00958         sha2_byte       digest[SHA512_DIGEST_LENGTH], *d = digest;
00959         int             i;
00960 
00961         /* Sanity check: */
00962         /* assert(context != (SHA512_CTX*)0); */
00963 
00964         if (buffer != (char*)0) {
00965                 sat_SHA512_Final(digest, context);
00966 
00967                 for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
00968                         *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
00969                         *buffer++ = sha2_hex_digits[*d & 0x0f];
00970                         d++;
00971                 }
00972                 *buffer = (char)0;
00973         } else {
00974                 MEMSET_BZERO(context, sizeof(context));
00975         }
00976         MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
00977         return buffer;
00978 }
00979 
00980 char* sat_SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
00981         SHA512_CTX      context;
00982 
00983         sat_SHA512_Init(&context);
00984         sat_SHA512_Update(&context, data, len);
00985         return sat_SHA512_End(&context, digest);
00986 }
00987 
00988 
00989 /*** SHA-384: *********************************************************/
00990 void sat_SHA384_Init(SHA384_CTX* context) {
00991         if (context == (SHA384_CTX*)0) {
00992                 return;
00993         }
00994         MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
00995         MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
00996         context->bitcount[0] = context->bitcount[1] = 0;
00997 }
00998 
00999 void sat_SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
01000         sat_SHA512_Update((SHA512_CTX*)context, data, len);
01001 }
01002 
01003 void sat_SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
01004         sha2_word64     *d = (sha2_word64*)digest;
01005 
01006         /* Sanity check: */
01007         /* assert(context != (SHA384_CTX*)0); */
01008 
01009         /* If no digest buffer is passed, we don't bother doing this: */
01010         if (digest != (sha2_byte*)0) {
01011                 SHA512_Last((SHA512_CTX*)context);
01012 
01013                 /* Save the hash data for output: */
01014 #ifndef WORDS_BIGENDIAN
01015                 {
01016                         /* Convert TO host byte order */
01017                         int     j;
01018                         for (j = 0; j < 6; j++) {
01019                                 REVERSE64(context->state[j],context->state[j]);
01020                                 *d++ = context->state[j];
01021                         }
01022                 }
01023 #else
01024                 MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
01025 #endif
01026         }
01027 
01028         /* Zero out state data */
01029         MEMSET_BZERO(context, sizeof(context));
01030 }
01031 
01032 char *sat_SHA384_End(SHA384_CTX* context, char buffer[]) {
01033         sha2_byte       digest[SHA384_DIGEST_LENGTH], *d = digest;
01034         int             i;
01035 
01036         /* Sanity check: */
01037         /* assert(context != (SHA384_CTX*)0); */
01038 
01039         if (buffer != (char*)0) {
01040                 sat_SHA384_Final(digest, context);
01041 
01042                 for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
01043                         *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
01044                         *buffer++ = sha2_hex_digits[*d & 0x0f];
01045                         d++;
01046                 }
01047                 *buffer = (char)0;
01048         } else {
01049                 MEMSET_BZERO(context, sizeof(context));
01050         }
01051         MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
01052         return buffer;
01053 }
01054 
01055 char* sat_SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
01056         SHA384_CTX      context;
01057 
01058         sat_SHA384_Init(&context);
01059         sat_SHA384_Update(&context, data, len);
01060         return sat_SHA384_End(&context, digest);
01061 }

Generated on Mon Dec 15 17:56:24 2014 for satsolver by  doxygen 1.5.6