Annotation of parser3/src/lib/md5/pa_sha2.c, revision 1.2

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

E-mail: