Header And Logo

PostgreSQL
| The world's most advanced open source database.

sha2.c

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