From 9912c41c176105bf0dad953e242aacc2717e9e6f Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 27 Jun 2011 14:27:23 -0400 Subject: Import sha2 implementation 1.0 from Aaron D. Gifford Copy cm_sha2.[hc] from sha2.[hc] in "sha2-1.0.tar.gz" downloaded today from http://www.aarongifford.com/computers/sha.html with trivial whitespace cleanup. Also fix #include to account for rename. --- Source/.gitattributes | 2 + Source/cm_sha2.c | 1064 +++++++++++++++++++++++++++++++++++++++++++++++++ Source/cm_sha2.h | 196 +++++++++ 3 files changed, 1262 insertions(+) create mode 100644 Source/.gitattributes create mode 100644 Source/cm_sha2.c create mode 100644 Source/cm_sha2.h diff --git a/Source/.gitattributes b/Source/.gitattributes new file mode 100644 index 0000000..cf4dabd --- /dev/null +++ b/Source/.gitattributes @@ -0,0 +1,2 @@ +# Preserve upstream indentation style. +cm_sha2.* whitespace=indent-with-non-tab diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c new file mode 100644 index 0000000..15f0f20 --- /dev/null +++ b/Source/cm_sha2.c @@ -0,0 +1,1064 @@ +/* + * FILE: sha2.c + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ + */ + +#include /* memcpy()/memset() or bcopy()/bzero() */ +#include /* assert() */ +#include "cm_sha2.h" /* "sha2.h" -> "cm_sha2.h" renamed for CMake */ + +/* + * ASSERT NOTE: + * Some sanity checking code is included using assert(). On my FreeBSD + * system, this additional code can be removed by compiling with NDEBUG + * defined. Check your own systems manpage on assert() to see how to + * compile WITHOUT the sanity checking code on your system. + * + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + + +/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER. If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivilent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including (which in turn includes + * where the appropriate definitions are actually + * made). + */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + +/* + * Define the followingsha2_* types to types of the correct length on + * the native archtecture. Most BSD systems and Linux define u_intXX_t + * types. Machines with very recent ANSI C headers, can use the + * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H + * during compile or in the sha.h header file. + * + * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t + * will need to define these three typedefs below (and the appropriate + * ones in sha.h too) by hand according to their system architecture. + * + * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t + * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. + */ +#ifdef SHA2_USE_INTTYPES_H + +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ + +#else /* SHA2_USE_INTTYPES_H */ + +typedef u_int8_t sha2_byte; /* Exactly 1 byte */ +typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ +typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) + + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#if BYTE_ORDER == LITTLE_ENDIAN +#define REVERSE32(w,x) { \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/* + * Macros for copying blocks of memory and for zeroing out ranges + * of memory. Using these macros makes it easy to switch from + * using memset()/memcpy() and using bzero()/bcopy(). + * + * Please define either SHA2_USE_MEMSET_MEMCPY or define + * SHA2_USE_BZERO_BCOPY depending on which function set you + * choose to use: + */ +#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) +/* Default to memset()/memcpy() if no option is specified */ +#define SHA2_USE_MEMSET_MEMCPY 1 +#endif +#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) +/* Abort with an error if BOTH options are defined */ +#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! +#endif + +#ifdef SHA2_USE_MEMSET_MEMCPY +#define MEMSET_BZERO(p,l) memset((p), 0, (l)) +#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) +#endif +#ifdef SHA2_USE_BZERO_BCOPY +#define MEMSET_BZERO(p,l) bzero((p), (l)) +#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) +#endif + + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + * same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) +#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ +/* NOTE: These should not be accessed directly from outside this + * library -- they are intended for private internal visibility/use + * only. + */ +void SHA512_Last(SHA512_CTX*); +void SHA256_Transform(SHA256_CTX*, const sha2_word32*); +void SHA512_Transform(SHA512_CTX*, const sha2_word64*); + + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-256: */ +const static sha2_word32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +const static sha2_word32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +const static sha2_word64 K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* Initial hash value H for SHA-384 */ +const static sha2_word64 sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL +}; + +/* Initial hash value H for SHA-512 */ +const static sha2_word64 sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha2_hex_digits = "0123456789abcdef"; + + +/*** SHA-256: *********************************************************/ +void SHA256_Init(SHA256_CTX* context) { + if (context == (SHA256_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA256_Transform(context, (sha2_word32*)data); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(context)); + usedspace = 0; +} + +char *SHA256_End(SHA256_CTX* context, char buffer[]) { + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); + return buffer; +} + +char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA256_CTX context; + + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); +} + + +/*** SHA-512: *********************************************************/ +void SHA512_Init(SHA512_CTX* context) { + if (context == (SHA512_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + W512[j]; \ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA512_Transform(context, (sha2_word64*)data); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA512_Last(SHA512_CTX* context) { + unsigned int usedspace; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); +} + +void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(context)); +} + +char *SHA512_End(SHA512_CTX* context, char buffer[]) { + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); + return buffer; +} + +char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA512_CTX context; + + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); +} + + +/*** SHA-384: *********************************************************/ +void SHA384_Init(SHA384_CTX* context) { + if (context == (SHA384_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { + SHA512_Update((SHA512_CTX*)context, data, len); +} + +void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(context)); +} + +char *SHA384_End(SHA384_CTX* context, char buffer[]) { + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); + return buffer; +} + +char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA384_CTX context; + + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); +} diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h new file mode 100644 index 0000000..3a55b33 --- /dev/null +++ b/Source/cm_sha2.h @@ -0,0 +1,196 @@ +/* + * FILE: sha2.h + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ + */ + +#ifndef __SHA2_H__ +#define __SHA2_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Import u_intXX_t size_t type definitions from system headers. You + * may need to change this, or define these things yourself in this + * file. + */ +#include + +#ifdef SHA2_USE_INTTYPES_H + +#include + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-256/384/512 Context Structures *******************************/ +/* NOTE: If your architecture does not define either u_intXX_t types or + * uintXX_t (from inttypes.h), you may need to define things by hand + * for your system: + */ +#if 0 +typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ +typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +#endif +/* + * Most BSD systems already define u_intXX_t types, as does Linux. + * Some systems, however, like Compaq's Tru64 Unix instead can use + * uintXX_t types defined by very recent ANSI C standards and included + * in the file: + * + * #include + * + * If you choose to use then please define: + * + * #define SHA2_USE_INTTYPES_H + * + * Or on the command line during compile: + * + * cc -DSHA2_USE_INTTYPES_H ... + */ +#ifdef SHA2_USE_INTTYPES_H + +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#else /* SHA2_USE_INTTYPES_H */ + +typedef struct _SHA256_CTX { + u_int32_t state[8]; + u_int64_t bitcount; + u_int8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + u_int64_t state[8]; + u_int64_t bitcount[2]; + u_int8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#endif /* SHA2_USE_INTTYPES_H */ + +typedef SHA512_CTX SHA384_CTX; + + +/*** SHA-256/384/512 Function Prototypes ******************************/ +#ifndef NOPROTO +#ifdef SHA2_USE_INTTYPES_H + +void SHA256_Init(SHA256_CTX *); +void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); +void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); + +void SHA384_Init(SHA384_CTX*); +void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); +void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void SHA512_Init(SHA512_CTX*); +void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); +void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); + +#else /* SHA2_USE_INTTYPES_H */ + +void SHA256_Init(SHA256_CTX *); +void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); +void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); + +void SHA384_Init(SHA384_CTX*); +void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); +void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void SHA512_Init(SHA512_CTX*); +void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); +void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); + +#endif /* SHA2_USE_INTTYPES_H */ + +#else /* NOPROTO */ + +void SHA256_Init(); +void SHA256_Update(); +void SHA256_Final(); +char* SHA256_End(); +char* SHA256_Data(); + +void SHA384_Init(); +void SHA384_Update(); +void SHA384_Final(); +char* SHA384_End(); +char* SHA384_Data(); + +void SHA512_Init(); +void SHA512_Update(); +void SHA512_Final(); +char* SHA512_End(); +char* SHA512_Data(); + +#endif /* NOPROTO */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __SHA2_H__ */ -- cgit v0.12 From 8251b20d4bba026b920c018e7cfb6ce2ce101110 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 27 Jun 2011 14:35:09 -0400 Subject: Import sha2 implementation 1.1 from Aaron D. Gifford Update cm_sha2.[hc] from sha2.[hc] in "sha2-1.1-ALPHA.tgz" downloaded today from http://www.aarongifford.com/computers/sha.html with trivial whitespace cleanup. This adds SHA-224 support. --- Source/cm_sha2.c | 1103 ++++++++++++++++++++++++++++++++++++++++-------------- Source/cm_sha2.h | 192 ++++++---- 2 files changed, 949 insertions(+), 346 deletions(-) diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index 15f0f20..855a5bb 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -1,8 +1,9 @@ /* * FILE: sha2.c - * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * AUTHOR: Aaron D. Gifford + * http://www.aarongifford.com/computers/sha.html * - * Copyright (c) 2000-2001, Aaron D. Gifford + * Copyright (c) 2000-2003, Aaron D. Gifford * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ + * $Id: sha2.c,v 1.4 2004/01/07 22:58:18 adg Exp $ */ #include /* memcpy()/memset() or bcopy()/bzero() */ @@ -57,7 +58,7 @@ */ -/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/*** SHA-224/256/384/512 Machine Architecture Definitions *************/ /* * BYTE_ORDER NOTE: * @@ -90,7 +91,7 @@ #endif /* - * Define the followingsha2_* types to types of the correct length on + * Define the following sha_* types to types of the correct length on * the native archtecture. Most BSD systems and Linux define u_intXX_t * types. Machines with very recent ANSI C headers, can use the * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H @@ -105,35 +106,28 @@ */ #ifdef SHA2_USE_INTTYPES_H -typedef uint8_t sha2_byte; /* Exactly 1 byte */ -typedef uint32_t sha2_word32; /* Exactly 4 bytes */ -typedef uint64_t sha2_word64; /* Exactly 8 bytes */ +typedef uint8_t sha_byte; /* Exactly 1 byte */ +typedef uint32_t sha_word32; /* Exactly 4 bytes */ +typedef uint64_t sha_word64; /* Exactly 8 bytes */ #else /* SHA2_USE_INTTYPES_H */ -typedef u_int8_t sha2_byte; /* Exactly 1 byte */ -typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ -typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ +typedef u_int8_t sha_byte; /* Exactly 1 byte */ +typedef u_int32_t sha_word32; /* Exactly 4 bytes */ +typedef u_int64_t sha_word64; /* Exactly 8 bytes */ #endif /* SHA2_USE_INTTYPES_H */ -/*** SHA-256/384/512 Various Length Definitions ***********************/ -/* NOTE: Most of these are in sha2.h */ -#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) -#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) -#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) - - /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ - sha2_word32 tmp = (w); \ + sha_word32 tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ } #define REVERSE64(w,x) { \ - sha2_word64 tmp = (w); \ + sha_word64 tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ @@ -148,7 +142,7 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ * 64-bit words): */ #define ADDINC128(w,n) { \ - (w)[0] += (sha2_word64)(n); \ + (w)[0] += (sha_word64)(n); \ if ((w)[0] < (n)) { \ (w)[1]++; \ } \ @@ -186,47 +180,81 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ /* * Bit shifting and rotation (used by the six SHA-XYZ logical functions: * - * NOTE: The naming of R and S appears backwards here (R is a SHIFT and - * S is a ROTATION) because the SHA-256/384/512 description document - * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this - * same "backwards" definition. + * NOTE: In the original SHA-256/384/512 document, the shift-right + * function was named R and the rotate-right function was called S. + * (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the + * web.) + * + * The newer NIST FIPS 180-2 document uses a much clearer naming + * scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for + * rotate-left. (See: + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + * on the web.) + * + * WARNING: These macros must be used cautiously, since they reference + * supplied parameters sometimes more than once, and thus could have + * unexpected side-effects if used without taking this into account. */ /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ -#define R(b,x) ((x) >> (b)) +#define SHR(b,x) ((x) >> (b)) /* 32-bit Rotate-right (used in SHA-256): */ -#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +#define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ -#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) +#define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) +/* 32-bit Rotate-left (used in SHA-1): */ +#define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b)))) -/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +/* Two logical functions used in SHA-1, SHA-254, SHA-256, SHA-384, and SHA-512: */ #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) -/* Four of six logical functions used in SHA-256: */ -#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) -#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) -#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) -#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) +/* Function used in SHA-1: */ +#define Parity(x,y,z) ((x) ^ (y) ^ (z)) + +/* Four logical functions used in SHA-256: */ +#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x))) +#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x))) +#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR( 3 , (x))) +#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR( 10, (x))) /* Four of six logical functions used in SHA-384 and SHA-512: */ -#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) -#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) -#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) -#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) +#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x))) +#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x))) +#define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x))) +#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x))) /*** INTERNAL FUNCTION PROTOTYPES *************************************/ -/* NOTE: These should not be accessed directly from outside this - * library -- they are intended for private internal visibility/use - * only. - */ -void SHA512_Last(SHA512_CTX*); -void SHA256_Transform(SHA256_CTX*, const sha2_word32*); -void SHA512_Transform(SHA512_CTX*, const sha2_word64*); +/* SHA-224 and SHA-256: */ +void SHA256_Internal_Init(SHA_CTX*, const sha_word32*); +void SHA256_Internal_Last(SHA_CTX*); +void SHA256_Internal_Transform(SHA_CTX*, const sha_word32*); + +/* SHA-384 and SHA-512: */ +void SHA512_Internal_Init(SHA_CTX*, const sha_word64*); +void SHA512_Internal_Last(SHA_CTX*); +void SHA512_Internal_Transform(SHA_CTX*, const sha_word64*); + + +/*** SHA2 INITIAL HASH VALUES AND CONSTANTS ***************************/ -/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ -/* Hash constant words K for SHA-256: */ -const static sha2_word32 K256[64] = { +/* Hash constant words K for SHA-1: */ +#define K1_0_TO_19 0x5a827999UL +#define K1_20_TO_39 0x6ed9eba1UL +#define K1_40_TO_59 0x8f1bbcdcUL +#define K1_60_TO_79 0xca62c1d6UL + +/* Initial hash value H for SHA-1: */ +const static sha_word32 sha1_initial_hash_value[5] = { + 0x67452301UL, + 0xefcdab89UL, + 0x98badcfeUL, + 0x10325476UL, + 0xc3d2e1f0UL +}; + +/* Hash constant words K for SHA-224 and SHA-256: */ +const static sha_word32 K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, @@ -245,8 +273,20 @@ const static sha2_word32 K256[64] = { 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; +/* Initial hash value H for SHA-224: */ +const static sha_word32 sha224_initial_hash_value[8] = { + 0xc1059ed8UL, + 0x367cd507UL, + 0x3070dd17UL, + 0xf70e5939UL, + 0xffc00b31UL, + 0x68581511UL, + 0x64f98fa7UL, + 0xbefa4fa4UL +}; + /* Initial hash value H for SHA-256: */ -const static sha2_word32 sha256_initial_hash_value[8] = { +const static sha_word32 sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, @@ -258,7 +298,7 @@ const static sha2_word32 sha256_initial_hash_value[8] = { }; /* Hash constant words K for SHA-384 and SHA-512: */ -const static sha2_word64 K512[80] = { +const static sha_word64 K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, @@ -302,7 +342,7 @@ const static sha2_word64 K512[80] = { }; /* Initial hash value H for SHA-384 */ -const static sha2_word64 sha384_initial_hash_value[8] = { +const static sha_word64 sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, @@ -314,7 +354,7 @@ const static sha2_word64 sha384_initial_hash_value[8] = { }; /* Initial hash value H for SHA-512 */ -const static sha2_word64 sha512_initial_hash_value[8] = { +const static sha_word64 sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, @@ -326,20 +366,439 @@ const static sha2_word64 sha512_initial_hash_value[8] = { }; /* - * Constant used by SHA256/384/512_End() functions for converting the + * Constant used by SHA224/256/384/512_End() functions for converting the * digest to a readable hexadecimal character string: */ -static const char *sha2_hex_digits = "0123456789abcdef"; +static const char *sha_hex_digits = "0123456789abcdef"; -/*** SHA-256: *********************************************************/ -void SHA256_Init(SHA256_CTX* context) { - if (context == (SHA256_CTX*)0) { +/*** SHA-1: ***********************************************************/ +void SHA1_Init(SHA_CTX* context) { + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + MEMCPY_BCOPY(context->s1.state, sha1_initial_hash_value, sizeof(sha_word32) * 5); + MEMSET_BZERO(context->s1.buffer, 64); + context->s1.bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-1 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND1_0_TO_15(a,b,c,d,e) \ + REVERSE32(*data++, W1[j]); \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ + K1_0_TO_19 + W1[j]; \ + (b) = ROTL32(30, (b)); \ + j++; + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND1_0_TO_15(a,b,c,d,e) \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ + K1_0_TO_19 + ( W1[j] = *data++ ); \ + (b) = ROTL32(30, (b)); \ + j++; + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND1_16_TO_19(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_20_TO_39(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_40_TO_59(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +#define ROUND1_60_TO_79(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + +void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + sha_word32 a, b, c, d, e; + sha_word32 T1, *W1; + int j; + + W1 = (sha_word32*)context->s1.buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->s1.state[0]; + b = context->s1.state[1]; + c = context->s1.state[2]; + d = context->s1.state[3]; + e = context->s1.state[4]; + + j = 0; + + /* Rounds 0 to 15 unrolled: */ + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + + /* Rounds 16 to 19 unrolled: */ + ROUND1_16_TO_19(e,a,b,c,d); + ROUND1_16_TO_19(d,e,a,b,c); + ROUND1_16_TO_19(c,d,e,a,b); + ROUND1_16_TO_19(b,c,d,e,a); + + /* Rounds 20 to 39 unrolled: */ + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + + /* Rounds 40 to 59 unrolled: */ + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + + /* Rounds 60 to 79 unrolled: */ + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + + /* Compute the current intermediate hash value */ + context->s1.state[0] += a; + context->s1.state[1] += b; + context->s1.state[2] += c; + context->s1.state[3] += d; + context->s1.state[4] += e; + + /* Clean up */ + a = b = c = d = e = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + sha_word32 a, b, c, d, e; + sha_word32 T1, *W1; + int j; + + W1 = (sha_word32*)context->s1.buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->s1.state[0]; + b = context->s1.state[1]; + c = context->s1.state[2]; + d = context->s1.state[3]; + e = context->s1.state[4]; + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + T1 = data[j]; + /* Copy data while converting to host byte order */ + REVERSE32(*data++, W1[j]); + T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + W1[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 16); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 20); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 40); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 60); + + do { + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; + T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + (W1[j&0x0f] = ROTL32(1, T1)); + e = d; + d = c; + c = ROTL32(30, b); + b = a; + a = T1; + j++; + } while (j < 80); + + + /* Compute the current intermediate hash value */ + context->s1.state[0] += a; + context->s1.state[1] += b; + context->s1.state[2] += c; + context->s1.state[3] += d; + context->s1.state[4] += e; + + /* Clean up */ + a = b = c = d = e = T1 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) { + unsigned int freespace, usedspace; + if (len == 0) { + /* Calling with no data is valid - we do nothing */ return; } - MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); - context->bitcount = 0; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); + + usedspace = (context->s1.bitcount >> 3) % 64; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = 64 - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, freespace); + context->s1.bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, len); + context->s1.bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= 64) { + /* Process as many complete blocks as we can */ + SHA1_Internal_Transform(context, (sha_word32*)data); + context->s1.bitcount += 512; + len -= 64; + data += 64; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->s1.buffer, data, len); + context->s1.bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA1_Final(sha_byte digest[], SHA_CTX* context) { + sha_word32 *d = (sha_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (digest == (sha_byte*)0) { + /* + * No digest buffer, so we can do nothing + * except clean up and go home + */ + MEMSET_BZERO(context, sizeof(context)); + return; + } + + usedspace = (context->s1.bitcount >> 3) % 64; + if (usedspace == 0) { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->s1.buffer, 56); + + /* Begin padding with a 1 bit: */ + *context->s1.buffer = 0x80; + } else { + /* Begin padding with a 1 bit: */ + context->s1.buffer[usedspace++] = 0x80; + + if (usedspace <= 56) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->s1.buffer[usedspace], 56 - usedspace); + } else { + if (usedspace < 64) { + MEMSET_BZERO(&context->s1.buffer[usedspace], 64 - usedspace); + } + /* Do second-to-last transform: */ + SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->s1.buffer, 56); + } + /* Clean up: */ + usedspace = 0; + } + /* Set the bit count: */ +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->s1.bitcount,context->s1.bitcount); +#endif + *(sha_word64*)&context->s1.buffer[56] = context->s1.bitcount; + + /* Final transform: */ + SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++) { + REVERSE32(context->s1.state[j],context->s1.state[j]); + *d++ = context->s1.state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->s1.state, SHA1_DIGEST_LENGTH); +#endif + + /* Clean up: */ + MEMSET_BZERO(context, sizeof(context)); +} + +char *SHA1_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA1_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (buffer != (char*)0) { + SHA1_Final(digest, context); + + for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA1_DIGEST_LENGTH); + return buffer; +} + +char* SHA1_Data(const sha_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) { + SHA_CTX context; + + SHA1_Init(&context); + SHA1_Update(&context, data, len); + return SHA1_End(&context, digest); +} + + +/*** SHA-256: *********************************************************/ +void SHA256_Internal_Init(SHA_CTX* context, const sha_word32* ihv) { + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + MEMCPY_BCOPY(context->s256.state, ihv, sizeof(sha_word32) * 8); + MEMSET_BZERO(context->s256.buffer, 64); + context->s256.bitcount = 0; +} + +void SHA256_Init(SHA_CTX* context) { + SHA256_Internal_Init(context, sha256_initial_hash_value); } #ifdef SHA2_UNROLL_TRANSFORM @@ -379,22 +838,22 @@ void SHA256_Init(SHA256_CTX* context) { (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ -void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, *W256; +void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + sha_word32 a, b, c, d, e, f, g, h, s0, s1; + sha_word32 T1, *W256; int j; - W256 = (sha2_word32*)context->buffer; + W256 = (sha_word32*)context->s256.buffer; /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; + a = context->s256.state[0]; + b = context->s256.state[1]; + c = context->s256.state[2]; + d = context->s256.state[3]; + e = context->s256.state[4]; + f = context->s256.state[5]; + g = context->s256.state[6]; + h = context->s256.state[7]; j = 0; do { @@ -422,14 +881,14 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { } while (j < 64); /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; + context->s256.state[0] += a; + context->s256.state[1] += b; + context->s256.state[2] += c; + context->s256.state[3] += d; + context->s256.state[4] += e; + context->s256.state[5] += f; + context->s256.state[6] += g; + context->s256.state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; @@ -437,22 +896,22 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { #else /* SHA2_UNROLL_TRANSFORM */ -void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, T2, *W256; +void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + sha_word32 a, b, c, d, e, f, g, h, s0, s1; + sha_word32 T1, T2, *W256; int j; - W256 = (sha2_word32*)context->buffer; + W256 = (sha_word32*)context->s256.buffer; /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; + a = context->s256.state[0]; + b = context->s256.state[1]; + c = context->s256.state[2]; + d = context->s256.state[3]; + e = context->s256.state[4]; + f = context->s256.state[5]; + g = context->s256.state[6]; + h = context->s256.state[7]; j = 0; do { @@ -502,14 +961,14 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { } while (j < 64); /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; + context->s256.state[0] += a; + context->s256.state[1] += b; + context->s256.state[2] += c; + context->s256.state[3] += d; + context->s256.state[4] += e; + context->s256.state[5] += f; + context->s256.state[6] += g; + context->s256.state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; @@ -517,7 +976,7 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { #endif /* SHA2_UNROLL_TRANSFORM */ -void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { +void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { @@ -526,121 +985,128 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { } /* Sanity check: */ - assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + usedspace = (context->s256.bitcount >> 3) % 64; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; + freespace = 64 - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - context->bitcount += freespace << 3; + MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, freespace); + context->s256.bitcount += freespace << 3; len -= freespace; data += freespace; - SHA256_Transform(context, (sha2_word32*)context->buffer); + SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); } else { /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - context->bitcount += len << 3; + MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, len); + context->s256.bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; return; } } - while (len >= SHA256_BLOCK_LENGTH) { + while (len >= 64) { /* Process as many complete blocks as we can */ - SHA256_Transform(context, (sha2_word32*)data); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; + SHA256_Internal_Transform(context, (sha_word32*)data); + context->s256.bitcount += 512; + len -= 64; + data += 64; } if (len > 0) { /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - context->bitcount += len << 3; + MEMCPY_BCOPY(context->s256.buffer, data, len); + context->s256.bitcount += len << 3; } /* Clean up: */ usedspace = freespace = 0; } -void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { - sha2_word32 *d = (sha2_word32*)digest; +void SHA256_Internal_Last(SHA_CTX* context) { unsigned int usedspace; - /* Sanity check: */ - assert(context != (SHA256_CTX*)0); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + usedspace = (context->s256.bitcount >> 3) % 64; #if BYTE_ORDER == LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount,context->bitcount); + /* Convert FROM host byte order */ + REVERSE64(context->s256.bitcount,context->s256.bitcount); #endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA256_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); - } - } else { + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->s256.buffer[usedspace++] = 0x80; + + if (usedspace <= 56) { /* Set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + MEMSET_BZERO(&context->s256.buffer[usedspace], 56 - usedspace); + } else { + if (usedspace < 64) { + MEMSET_BZERO(&context->s256.buffer[usedspace], 64 - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; + /* And set-up for the last transform: */ + MEMSET_BZERO(context->s256.buffer, 56); } - /* Set the bit count: */ - *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; + /* Clean up: */ + usedspace = 0; + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->s256.buffer, 56); - /* Final transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); + /* Begin padding with a 1 bit: */ + *context->s256.buffer = 0x80; + } + /* Set the bit count: */ + *(sha_word64*)&context->s256.buffer[56] = context->s256.bitcount; + + /* Final transform: */ + SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); +} + +void SHA256_Final(sha_byte digest[], SHA_CTX* context) { + sha_word32 *d = (sha_word32*)digest; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha_byte*)0) { + SHA256_Internal_Last(context); + + /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; - for (j = 0; j < 8; j++) { - REVERSE32(context->state[j],context->state[j]); - *d++ = context->state[j]; + for (j = 0; j < (SHA256_DIGEST_LENGTH >> 2); j++) { + REVERSE32(context->s256.state[j],context->s256.state[j]); + *d++ = context->s256.state[j]; } } #else - MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->s256.state, SHA256_DIGEST_LENGTH); #endif } /* Clean up state data: */ MEMSET_BZERO(context, sizeof(context)); - usedspace = 0; } -char *SHA256_End(SHA256_CTX* context, char buffer[]) { - sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; +char *SHA256_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA256_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ - assert(context != (SHA256_CTX*)0); + assert(context != (SHA_CTX*)0); if (buffer != (char*)0) { SHA256_Final(digest, context); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; @@ -651,8 +1117,8 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) { return buffer; } -char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { - SHA256_CTX context; +char* SHA256_Data(const sha_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA_CTX context; SHA256_Init(&context); SHA256_Update(&context, data, len); @@ -660,14 +1126,92 @@ char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_S } -/*** SHA-512: *********************************************************/ -void SHA512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return; +/*** SHA-224: *********************************************************/ +void SHA224_Init(SHA_CTX* context) { + SHA256_Internal_Init(context, sha224_initial_hash_value); +} + +void SHA224_Internal_Transform(SHA_CTX* context, const sha_word32* data) { + SHA256_Internal_Transform(context, data); +} + +void SHA224_Update(SHA_CTX* context, const sha_byte *data, size_t len) { + SHA256_Update(context, data, len); +} + +void SHA224_Final(sha_byte digest[], SHA_CTX* context) { + sha_word32 *d = (sha_word32*)digest; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha_byte*)0) { + SHA256_Internal_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < (SHA224_DIGEST_LENGTH >> 2); j++) { + REVERSE32(context->s256.state[j],context->s256.state[j]); + *d++ = context->s256.state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->s256.state, SHA224_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(context)); +} + +char *SHA224_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA224_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + if (buffer != (char*)0) { + SHA224_Final(digest, context); + + for (i = 0; i < SHA224_DIGEST_LENGTH; i++) { + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); } - MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; + MEMSET_BZERO(digest, SHA224_DIGEST_LENGTH); + return buffer; +} + +char* SHA224_Data(const sha_byte* data, size_t len, char digest[SHA224_DIGEST_STRING_LENGTH]) { + SHA_CTX context; + + SHA224_Init(&context); + SHA224_Update(&context, data, len); + return SHA224_End(&context, digest); +} + + +/*** SHA-512: *********************************************************/ +void SHA512_Internal_Init(SHA_CTX* context, const sha_word64* ihv) { + /* Sanity check: */ + assert(context != (SHA_CTX*)0); + + MEMCPY_BCOPY(context->s512.state, ihv, sizeof(sha_word64) * 8); + MEMSET_BZERO(context->s512.buffer, 128); + context->s512.bitcount[0] = context->s512.bitcount[1] = 0; +} + +void SHA512_Init(SHA_CTX* context) { + SHA512_Internal_Init(context, sha512_initial_hash_value); } #ifdef SHA2_UNROLL_TRANSFORM @@ -706,20 +1250,20 @@ void SHA512_Init(SHA512_CTX* context) { (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ -void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; +void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) { + sha_word64 a, b, c, d, e, f, g, h, s0, s1; + sha_word64 T1, *W512 = (sha_word64*)context->s512.buffer; int j; /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; + a = context->s512.state[0]; + b = context->s512.state[1]; + c = context->s512.state[2]; + d = context->s512.state[3]; + e = context->s512.state[4]; + f = context->s512.state[5]; + g = context->s512.state[6]; + h = context->s512.state[7]; j = 0; do { @@ -746,14 +1290,14 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { } while (j < 80); /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; + context->s512.state[0] += a; + context->s512.state[1] += b; + context->s512.state[2] += c; + context->s512.state[3] += d; + context->s512.state[4] += e; + context->s512.state[5] += f; + context->s512.state[6] += g; + context->s512.state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; @@ -761,20 +1305,20 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { #else /* SHA2_UNROLL_TRANSFORM */ -void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; +void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) { + sha_word64 a, b, c, d, e, f, g, h, s0, s1; + sha_word64 T1, T2, *W512 = (sha_word64*)context->s512.buffer; int j; /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; + a = context->s512.state[0]; + b = context->s512.state[1]; + c = context->s512.state[2]; + d = context->s512.state[3]; + e = context->s512.state[4]; + f = context->s512.state[5]; + g = context->s512.state[6]; + h = context->s512.state[7]; j = 0; do { @@ -824,14 +1368,14 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { } while (j < 80); /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; + context->s512.state[0] += a; + context->s512.state[1] += b; + context->s512.state[2] += c; + context->s512.state[3] += d; + context->s512.state[4] += e; + context->s512.state[5] += f; + context->s512.state[6] += g; + context->s512.state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; @@ -839,7 +1383,7 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { #endif /* SHA2_UNROLL_TRANSFORM */ -void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { +void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { @@ -848,108 +1392,110 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { } /* Sanity check: */ - assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + usedspace = (context->s512.bitcount[0] >> 3) % 128; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; + freespace = 128 - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - ADDINC128(context->bitcount, freespace << 3); + MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, freespace); + ADDINC128(context->s512.bitcount, freespace << 3); len -= freespace; data += freespace; - SHA512_Transform(context, (sha2_word64*)context->buffer); + SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); } else { /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - ADDINC128(context->bitcount, len << 3); + MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, len); + ADDINC128(context->s512.bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; return; } } - while (len >= SHA512_BLOCK_LENGTH) { + while (len >= 128) { /* Process as many complete blocks as we can */ - SHA512_Transform(context, (sha2_word64*)data); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; + SHA512_Internal_Transform(context, (sha_word64*)data); + ADDINC128(context->s512.bitcount, 1024); + len -= 128; + data += 128; } if (len > 0) { /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); + MEMCPY_BCOPY(context->s512.buffer, data, len); + ADDINC128(context->s512.bitcount, len << 3); } /* Clean up: */ usedspace = freespace = 0; } -void SHA512_Last(SHA512_CTX* context) { +void SHA512_Internal_Last(SHA_CTX* context) { unsigned int usedspace; - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + usedspace = (context->s512.bitcount[0] >> 3) % 128; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ - REVERSE64(context->bitcount[0],context->bitcount[0]); - REVERSE64(context->bitcount[1],context->bitcount[1]); + REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]); + REVERSE64(context->s512.bitcount[1],context->s512.bitcount[1]); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; + context->s512.buffer[usedspace++] = 0x80; - if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + if (usedspace <= 112) { /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + MEMSET_BZERO(&context->s512.buffer[usedspace], 112 - usedspace); } else { - if (usedspace < SHA512_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + if (usedspace < 128) { + MEMSET_BZERO(&context->s512.buffer[usedspace], 128 - usedspace); } /* Do second-to-last transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); + SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); + MEMSET_BZERO(context->s512.buffer, 112); } + /* Clean up: */ + usedspace = 0; } else { /* Prepare for final transform: */ - MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + MEMSET_BZERO(context->s512.buffer, 112); /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; + *context->s512.buffer = 0x80; } /* Store the length of input data (in bits): */ - *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; - *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; + *(sha_word64*)&context->s512.buffer[112] = context->s512.bitcount[1]; + *(sha_word64*)&context->s512.buffer[120] = context->s512.bitcount[0]; /* Final transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); + SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); } -void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; +void SHA512_Final(sha_byte digest[], SHA_CTX* context) { + sha_word64 *d = (sha_word64*)digest; /* Sanity check: */ - assert(context != (SHA512_CTX*)0); + assert(context != (SHA_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last(context); + if (digest != (sha_byte*)0) { + SHA512_Internal_Last(context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; - for (j = 0; j < 8; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; + for (j = 0; j < (SHA512_DIGEST_LENGTH >> 3); j++) { + REVERSE64(context->s512.state[j],context->s512.state[j]); + *d++ = context->s512.state[j]; } } #else - MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->s512.state, SHA512_DIGEST_LENGTH); #endif } @@ -957,19 +1503,19 @@ void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { MEMSET_BZERO(context, sizeof(context)); } -char *SHA512_End(SHA512_CTX* context, char buffer[]) { - sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; +char *SHA512_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA512_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ - assert(context != (SHA512_CTX*)0); + assert(context != (SHA_CTX*)0); if (buffer != (char*)0) { SHA512_Final(digest, context); for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; @@ -980,8 +1526,8 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) { return buffer; } -char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context; +char* SHA512_Data(const sha_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA_CTX context; SHA512_Init(&context); SHA512_Update(&context, data, len); @@ -990,41 +1536,36 @@ char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_S /*** SHA-384: *********************************************************/ -void SHA384_Init(SHA384_CTX* context) { - if (context == (SHA384_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; +void SHA384_Init(SHA_CTX* context) { + SHA512_Internal_Init(context, sha384_initial_hash_value); } -void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { - SHA512_Update((SHA512_CTX*)context, data, len); +void SHA384_Update(SHA_CTX* context, const sha_byte* data, size_t len) { + SHA512_Update(context, data, len); } -void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; +void SHA384_Final(sha_byte digest[], SHA_CTX* context) { + sha_word64 *d = (sha_word64*)digest; /* Sanity check: */ - assert(context != (SHA384_CTX*)0); + assert(context != (SHA_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - SHA512_Last((SHA512_CTX*)context); + if (digest != (sha_byte*)0) { + SHA512_Internal_Last(context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; - for (j = 0; j < 6; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; + for (j = 0; j < (SHA384_DIGEST_LENGTH >> 3); j++) { + REVERSE64(context->s512.state[j],context->s512.state[j]); + *d++ = context->s512.state[j]; } } #else - MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); + MEMCPY_BCOPY(d, context->s512.state, SHA384_DIGEST_LENGTH); #endif } @@ -1032,19 +1573,19 @@ void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { MEMSET_BZERO(context, sizeof(context)); } -char *SHA384_End(SHA384_CTX* context, char buffer[]) { - sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; +char *SHA384_End(SHA_CTX* context, char buffer[]) { + sha_byte digest[SHA384_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ - assert(context != (SHA384_CTX*)0); + assert(context != (SHA_CTX*)0); if (buffer != (char*)0) { SHA384_Final(digest, context); for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; + *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; @@ -1055,8 +1596,8 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) { return buffer; } -char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { - SHA384_CTX context; +char* SHA384_Data(const sha_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA_CTX context; SHA384_Init(&context); SHA384_Update(&context, data, len); diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h index 3a55b33..9459f75 100644 --- a/Source/cm_sha2.h +++ b/Source/cm_sha2.h @@ -1,8 +1,9 @@ /* - * FILE: sha2.h - * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * FILE: sha2.h + * AUTHOR: Aaron D. Gifford + * http://www.aarongifford.com/computers/sha.html * - * Copyright (c) 2000-2001, Aaron D. Gifford + * Copyright (c) 2000-2003, Aaron D. Gifford * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ + * $Id: sha2.h,v 1.4 2004/01/07 19:06:18 adg Exp $ */ #ifndef __SHA2_H__ @@ -54,27 +55,30 @@ extern "C" { #endif /* SHA2_USE_INTTYPES_H */ -/*** SHA-256/384/512 Various Length Definitions ***********************/ -#define SHA256_BLOCK_LENGTH 64 -#define SHA256_DIGEST_LENGTH 32 -#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) -#define SHA384_BLOCK_LENGTH 128 -#define SHA384_DIGEST_LENGTH 48 -#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) -#define SHA512_BLOCK_LENGTH 128 -#define SHA512_DIGEST_LENGTH 64 -#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) +/*** SHA-224/256/384/512 Various Length Definitions *******************/ +/* Digest lengths for SHA-1/224/256/384/512 */ +#define SHA1_DIGEST_LENGTH 20 +#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) +#define SHA224_DIGEST_LENGTH 28 +#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1) +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) -/*** SHA-256/384/512 Context Structures *******************************/ + +/*** SHA-224/256/384/512 Context Structures ***************************/ /* NOTE: If your architecture does not define either u_intXX_t types or * uintXX_t (from inttypes.h), you may need to define things by hand * for your system: */ #if 0 -typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ -typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ -typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ +typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ #endif /* * Most BSD systems already define u_intXX_t types, as does Linux. @@ -94,81 +98,139 @@ typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ */ #ifdef SHA2_USE_INTTYPES_H -typedef struct _SHA256_CTX { - uint32_t state[8]; - uint64_t bitcount; - uint8_t buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; -typedef struct _SHA512_CTX { - uint64_t state[8]; - uint64_t bitcount[2]; - uint8_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; +typedef union _SHA_CTX { + /* SHA-1 uses this part of the union: */ + struct { + uint32_t state[5]; + uint64_t bitcount; + uint8_t buffer[64]; + } s1; + + /* SHA-224 and SHA-256 use this part of the union: */ + struct { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[64]; + } s256; + + /* SHA-384 and SHA-512 use this part of the union: */ + struct { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[128]; + } s512; +} SHA_CTX; #else /* SHA2_USE_INTTYPES_H */ -typedef struct _SHA256_CTX { - u_int32_t state[8]; - u_int64_t bitcount; - u_int8_t buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; -typedef struct _SHA512_CTX { - u_int64_t state[8]; - u_int64_t bitcount[2]; - u_int8_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; +typedef union _SHA_CTX { + /* SHA-1 uses this part of the union: */ + struct { + u_int32_t state[5]; + u_int64_t bitcount; + u_int8_t buffer[64]; + } s1; + + /* SHA-224 and SHA-256 use this part of the union: */ + struct { + u_int32_t state[8]; + u_int64_t bitcount; + u_int8_t buffer[64]; + } s256; + + /* SHA-384 and SHA-512 use this part of the union: */ + struct { + u_int64_t state[8]; + u_int64_t bitcount[2]; + u_int8_t buffer[128]; + } s512; +} SHA_CTX; #endif /* SHA2_USE_INTTYPES_H */ -typedef SHA512_CTX SHA384_CTX; - /*** SHA-256/384/512 Function Prototypes ******************************/ #ifndef NOPROTO #ifdef SHA2_USE_INTTYPES_H -void SHA256_Init(SHA256_CTX *); -void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); -void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +void SHA1_Init(SHA_CTX*); +void SHA1_Update(SHA_CTX*, const uint8_t*, size_t); +void SHA1_Final(uint8_t[SHA1_DIGEST_LENGTH], SHA_CTX*); +char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); +char* SHA1_Data(const uint8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); + +void SHA224_Init(SHA_CTX*); +void SHA224_Update(SHA_CTX*, const uint8_t*, size_t); +void SHA224_Final(uint8_t[SHA224_DIGEST_LENGTH], SHA_CTX*); +char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]); +char* SHA224_Data(const uint8_t*, size_t, char[SHA224_DIGEST_STRING_LENGTH]); + +void SHA256_Init(SHA_CTX*); +void SHA256_Update(SHA_CTX*, const uint8_t*, size_t); +void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA_CTX*); +char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); -void SHA384_Init(SHA384_CTX*); -void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); -void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +void SHA384_Init(SHA_CTX*); +void SHA384_Update(SHA_CTX*, const uint8_t*, size_t); +void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA_CTX*); +char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); -void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +void SHA512_Init(SHA_CTX*); +void SHA512_Update(SHA_CTX*, const uint8_t*, size_t); +void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA_CTX*); +char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #else /* SHA2_USE_INTTYPES_H */ -void SHA256_Init(SHA256_CTX *); -void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); -void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +void SHA1_Init(SHA_CTX*); +void SHA1_Update(SHA_CTX*, const u_int8_t*, size_t); +void SHA1_Final(u_int8_t[SHA1_DIGEST_LENGTH], SHA_CTX*); +char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); +char* SHA1_Data(const u_int8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); + +void SHA224_Init(SHA_CTX*); +void SHA224_Update(SHA_CTX*, const u_int8_t*, size_t); +void SHA224_Final(u_int8_t[SHA224_DIGEST_LENGTH], SHA_CTX*); +char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]); +char* SHA224_Data(const u_int8_t*, size_t, char[SHA224_DIGEST_STRING_LENGTH]); + +void SHA256_Init(SHA_CTX*); +void SHA256_Update(SHA_CTX*, const u_int8_t*, size_t); +void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA_CTX*); +char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); -void SHA384_Init(SHA384_CTX*); -void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); -void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +void SHA384_Init(SHA_CTX*); +void SHA384_Update(SHA_CTX*, const u_int8_t*, size_t); +void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA_CTX*); +char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); -void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +void SHA512_Init(SHA_CTX*); +void SHA512_Update(SHA_CTX*, const u_int8_t*, size_t); +void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA_CTX*); +char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #endif /* SHA2_USE_INTTYPES_H */ #else /* NOPROTO */ +void SHA1_Init(); +void SHA1_Update(); +void SHA1_Final(); +char* SHA1_End(); +char* SHA1_Data(); + +void SHA224_Init(); +void SHA224_Update(); +void SHA224_Final(); +char* SHA224_End(); +char* SHA224_Data(); + void SHA256_Init(); void SHA256_Update(); void SHA256_Final(); @@ -189,7 +251,7 @@ char* SHA512_Data(); #endif /* NOPROTO */ -#ifdef __cplusplus +#ifdef __cplusplus } #endif /* __cplusplus */ -- cgit v0.12 From ed7cef563445644684af47720c2f7c6fb0a2e440 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 15 Nov 2011 19:37:38 -0500 Subject: Factor Compute(File|String)MD5 into cmCryptoHash helper Define an abstract API around the backend hash algorithm. Expose ifstream errors to HashFile callers. Always try opening the file. Succeed only if the end of file is reached without error. --- Source/CMakeLists.txt | 2 ++ Source/cmCryptoHash.cxx | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ Source/cmCryptoHash.h | 40 +++++++++++++++++++++ Source/cmSystemTools.cxx | 57 ++++-------------------------- 4 files changed, 139 insertions(+), 50 deletions(-) create mode 100644 Source/cmCryptoHash.cxx create mode 100644 Source/cmCryptoHash.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ba41d98..284c84d 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -129,6 +129,8 @@ SET(SRCS cmComputeLinkInformation.h cmComputeTargetDepends.h cmComputeTargetDepends.cxx + cmCryptoHash.cxx + cmCryptoHash.h cmCustomCommand.cxx cmCustomCommand.h cmCustomCommandGenerator.cxx diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx new file mode 100644 index 0000000..3a73398 --- /dev/null +++ b/Source/cmCryptoHash.cxx @@ -0,0 +1,90 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmCryptoHash.h" + +#include + +//---------------------------------------------------------------------------- +std::string cmCryptoHash::HashString(const char* input) +{ + this->Initialize(); + this->Append(reinterpret_cast(input), + static_cast(strlen(input))); + return this->Finalize(); +} + +//---------------------------------------------------------------------------- +std::string cmCryptoHash::HashFile(const char* file) +{ + std::ifstream fin(file, std::ios::in | cmsys_ios_binary); + if(!fin) + { + return ""; + } + + this->Initialize(); + + // Should be efficient enough on most system: + const int bufferSize = 4096; + char buffer[bufferSize]; + unsigned char const* buffer_uc = + reinterpret_cast(buffer); + // This copy loop is very sensitive on certain platforms with + // slightly broken stream libraries (like HPUX). Normally, it is + // incorrect to not check the error condition on the fin.read() + // before using the data, but the fin.gcount() will be zero if an + // error occurred. Therefore, the loop should be safe everywhere. + while(fin) + { + fin.read(buffer, bufferSize); + if(int gcount = static_cast(fin.gcount())) + { + this->Append(buffer_uc, gcount); + } + } + if(fin.eof()) + { + return this->Finalize(); + } + return ""; +} + +//---------------------------------------------------------------------------- +cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New()) +{ +} + +//---------------------------------------------------------------------------- +cmCryptoHashMD5::~cmCryptoHashMD5() +{ + cmsysMD5_Delete(this->MD5); +} + +//---------------------------------------------------------------------------- +void cmCryptoHashMD5::Initialize() +{ + cmsysMD5_Initialize(this->MD5); +} + +//---------------------------------------------------------------------------- +void cmCryptoHashMD5::Append(unsigned char const* buf, int sz) +{ + cmsysMD5_Append(this->MD5, buf, sz); +} + +//---------------------------------------------------------------------------- +std::string cmCryptoHashMD5::Finalize() +{ + char md5out[32]; + cmsysMD5_FinalizeHex(this->MD5, md5out); + return std::string(md5out, 32); +} diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h new file mode 100644 index 0000000..670624c --- /dev/null +++ b/Source/cmCryptoHash.h @@ -0,0 +1,40 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmCryptoHash_h +#define cmCryptoHash_h + +#include "cmStandardIncludes.h" + +class cmCryptoHash +{ +public: + std::string HashString(const char* input); + std::string HashFile(const char* file); +protected: + virtual void Initialize()=0; + virtual void Append(unsigned char const*, int)=0; + virtual std::string Finalize()=0; +}; + +class cmCryptoHashMD5: public cmCryptoHash +{ + struct cmsysMD5_s* MD5; +public: + cmCryptoHashMD5(); + ~cmCryptoHashMD5(); +protected: + virtual void Initialize(); + virtual void Append(unsigned char const* buf, int sz); + virtual std::string Finalize(); +}; + +#endif diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 03364bd..8eec1e2 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -54,7 +54,7 @@ #if defined(CMAKE_BUILD_WITH_CMAKE) # include // auto_ptr # include -# include +# include "cmCryptoHash.h" #endif #if defined(CMAKE_USE_ELF_PARSER) @@ -1197,48 +1197,10 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname) bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) { #if defined(CMAKE_BUILD_WITH_CMAKE) - if(!cmSystemTools::FileExists(source)) - { - return false; - } - - // Open files -#if defined(_WIN32) || defined(__CYGWIN__) - cmsys_ios::ifstream fin(source, cmsys_ios::ios::binary | cmsys_ios::ios::in); -#else - cmsys_ios::ifstream fin(source); -#endif - if(!fin) - { - return false; - } - - cmsysMD5* md5 = cmsysMD5_New(); - cmsysMD5_Initialize(md5); - - // Should be efficient enough on most system: - const int bufferSize = 4096; - char buffer[bufferSize]; - unsigned char const* buffer_uc = - reinterpret_cast(buffer); - // This copy loop is very sensitive on certain platforms with - // slightly broken stream libraries (like HPUX). Normally, it is - // incorrect to not check the error condition on the fin.read() - // before using the data, but the fin.gcount() will be zero if an - // error occurred. Therefore, the loop should be safe everywhere. - while(fin) - { - fin.read(buffer, bufferSize); - if(int gcount = static_cast(fin.gcount())) - { - cmsysMD5_Append(md5, buffer_uc, gcount); - } - } - cmsysMD5_FinalizeHex(md5, md5out); - cmsysMD5_Delete(md5); - - fin.close(); - return true; + cmCryptoHashMD5 md5; + std::string str = md5.HashFile(source); + strncpy(md5out, str.c_str(), 32); + return !str.empty(); #else (void)source; (void)md5out; @@ -1250,13 +1212,8 @@ bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) std::string cmSystemTools::ComputeStringMD5(const char* input) { #if defined(CMAKE_BUILD_WITH_CMAKE) - char md5out[32]; - cmsysMD5* md5 = cmsysMD5_New(); - cmsysMD5_Initialize(md5); - cmsysMD5_Append(md5, reinterpret_cast(input), -1); - cmsysMD5_FinalizeHex(md5, md5out); - cmsysMD5_Delete(md5); - return std::string(md5out, 32); + cmCryptoHashMD5 md5; + return md5.HashString(input); #else (void)input; cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error"); -- cgit v0.12 From 042f7965c3a5db7420363fdb76f9ebaa8e93efdc Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 15 Nov 2011 20:39:36 -0500 Subject: Add file(MD5) command to compute cryptographic hash Provide a CMake-language binding to the md5sum function previously available only by "cmake -E md5sum". --- Source/cmFileCommand.cxx | 36 +++++++++++++++++++++++++++++++++ Source/cmFileCommand.h | 4 ++++ Tests/CMakeTests/CheckCMakeTest.cmake | 2 +- Tests/CMakeTests/File-MD5-BadArg1.cmake | 1 + Tests/CMakeTests/File-MD5-BadArg2.cmake | 1 + Tests/CMakeTests/File-MD5-BadArg4.cmake | 1 + Tests/CMakeTests/File-MD5-NoFile.cmake | 1 + Tests/CMakeTests/File-MD5-Works.cmake | 2 ++ Tests/CMakeTests/FileTest.cmake.in | 15 ++++++++++++++ 9 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 Tests/CMakeTests/File-MD5-BadArg1.cmake create mode 100644 Tests/CMakeTests/File-MD5-BadArg2.cmake create mode 100644 Tests/CMakeTests/File-MD5-BadArg4.cmake create mode 100644 Tests/CMakeTests/File-MD5-NoFile.cmake create mode 100644 Tests/CMakeTests/File-MD5-Works.cmake diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index f933666..32454f5 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -13,6 +13,7 @@ #include "cmake.h" #include "cmHexFileConverter.h" #include "cmFileTimeComparison.h" +#include "cmCryptoHash.h" #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cm_curl.h" @@ -22,6 +23,7 @@ #include #include +#include #include #include #include @@ -83,6 +85,10 @@ bool cmFileCommand { return this->HandleReadCommand(args); } + else if ( subCommand == "MD5" ) + { + return this->HandleHashCommand(args); + } else if ( subCommand == "STRINGS" ) { return this->HandleStringsCommand(args); @@ -339,6 +345,36 @@ bool cmFileCommand::HandleReadCommand(std::vector const& args) } //---------------------------------------------------------------------------- +bool cmFileCommand::HandleHashCommand(std::vector const& args) +{ + if(args.size() != 3) + { + cmOStringStream e; + e << args[0] << " requires a file name and output variable"; + this->SetError(e.str().c_str()); + return false; + } + + cmsys::auto_ptr hash; + if(args[0] == "MD5") + { hash.reset(new cmCryptoHashMD5); } + if(hash.get()) + { + std::string out = hash->HashFile(args[1].c_str()); + if(!out.empty()) + { + this->Makefile->AddDefinition(args[2].c_str(), out.c_str()); + return true; + } + cmOStringStream e; + e << args[0] << " failed to read file \"" << args[1] << "\": " + << cmSystemTools::GetLastSystemError(); + this->SetError(e.str().c_str()); + } + return false; +} + +//---------------------------------------------------------------------------- bool cmFileCommand::HandleStringsCommand(std::vector const& args) { if(args.size() < 3) diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 162890a..dce6478 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -65,6 +65,7 @@ public: " file(WRITE filename \"message to write\"... )\n" " file(APPEND filename \"message to write\"... )\n" " file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX])\n" + " file(MD5 filename variable)\n" " file(STRINGS filename variable [LIMIT_COUNT num]\n" " [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes]\n" " [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes]\n" @@ -94,6 +95,8 @@ public: "variable. It will start at the given offset and read up to numBytes. " "If the argument HEX is given, the binary data will be converted to " "hexadecimal representation and this will be stored in the variable.\n" + "MD5 " + "will compute a cryptographic hash of the content of a file.\n" "STRINGS will parse a list of ASCII strings from a file and " "store it in a variable. Binary data in the file are ignored. Carriage " "return (CR) characters are ignored. It works also for Intel Hex and " @@ -227,6 +230,7 @@ protected: bool HandleRemove(std::vector const& args, bool recurse); bool HandleWriteCommand(std::vector const& args, bool append); bool HandleReadCommand(std::vector const& args); + bool HandleHashCommand(std::vector const& args); bool HandleStringsCommand(std::vector const& args); bool HandleGlobCommand(std::vector const& args, bool recurse); bool HandleMakeDirectoryCommand(std::vector const& args); diff --git a/Tests/CMakeTests/CheckCMakeTest.cmake b/Tests/CMakeTests/CheckCMakeTest.cmake index 2e4fedd..db92905 100644 --- a/Tests/CMakeTests/CheckCMakeTest.cmake +++ b/Tests/CMakeTests/CheckCMakeTest.cmake @@ -12,7 +12,7 @@ function(check_cmake_test prefix) ) string(REGEX REPLACE "\n" "\n out> " out " out> ${stdout}") string(REGEX REPLACE "\n" "\n err> " err " err> ${stderr}") - if(NOT "${result}" STREQUAL ${${test}-RESULT}) + if(NOT "${result}" STREQUAL "${${test}-RESULT}") message(FATAL_ERROR "Test ${test} result is [${result}], not [${${test}-RESULT}].\n" "Test ${test} output:\n" diff --git a/Tests/CMakeTests/File-MD5-BadArg1.cmake b/Tests/CMakeTests/File-MD5-BadArg1.cmake new file mode 100644 index 0000000..ac5f67a --- /dev/null +++ b/Tests/CMakeTests/File-MD5-BadArg1.cmake @@ -0,0 +1 @@ +file(MD5) diff --git a/Tests/CMakeTests/File-MD5-BadArg2.cmake b/Tests/CMakeTests/File-MD5-BadArg2.cmake new file mode 100644 index 0000000..68a172f --- /dev/null +++ b/Tests/CMakeTests/File-MD5-BadArg2.cmake @@ -0,0 +1 @@ +file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake) diff --git a/Tests/CMakeTests/File-MD5-BadArg4.cmake b/Tests/CMakeTests/File-MD5-BadArg4.cmake new file mode 100644 index 0000000..a11efcb --- /dev/null +++ b/Tests/CMakeTests/File-MD5-BadArg4.cmake @@ -0,0 +1 @@ +file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake md5 extra_arg) diff --git a/Tests/CMakeTests/File-MD5-NoFile.cmake b/Tests/CMakeTests/File-MD5-NoFile.cmake new file mode 100644 index 0000000..1b91bc8 --- /dev/null +++ b/Tests/CMakeTests/File-MD5-NoFile.cmake @@ -0,0 +1 @@ +file(MD5 ${CMAKE_CURRENT_LIST_DIR}/DoesNotExist.cmake md5) diff --git a/Tests/CMakeTests/File-MD5-Works.cmake b/Tests/CMakeTests/File-MD5-Works.cmake new file mode 100644 index 0000000..2989e98 --- /dev/null +++ b/Tests/CMakeTests/File-MD5-Works.cmake @@ -0,0 +1,2 @@ +file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake md5) +message("${md5}") diff --git a/Tests/CMakeTests/FileTest.cmake.in b/Tests/CMakeTests/FileTest.cmake.in index b6dcaa6..3aa88a7 100644 --- a/Tests/CMakeTests/FileTest.cmake.in +++ b/Tests/CMakeTests/FileTest.cmake.in @@ -12,6 +12,16 @@ set(Copy-NoDest-RESULT 1) set(Copy-NoDest-STDERR "given no DESTINATION") set(Copy-NoFile-RESULT 1) set(Copy-NoFile-STDERR "COPY cannot find.*/does_not_exist\\.txt") +set(MD5-NoFile-RESULT 1) +set(MD5-NoFile-STDERR "file MD5 failed to read file") +set(MD5-BadArg1-RESULT 1) +set(MD5-BadArg1-STDERR "file must be called with at least two arguments") +set(MD5-BadArg2-RESULT 1) +set(MD5-BadArg2-STDERR "file MD5 requires a file name and output variable") +set(MD5-BadArg4-RESULT 1) +set(MD5-BadArg4-STDERR "file MD5 requires a file name and output variable") +set(MD5-Works-RESULT 0) +set(MD5-Works-STDERR "a28a44fb5b58a6acf0cbec46557bc775") include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") check_cmake_test(File @@ -22,6 +32,11 @@ check_cmake_test(File Copy-LateArg Copy-NoDest Copy-NoFile + MD5-NoFile + MD5-BadArg1 + MD5-BadArg2 + MD5-BadArg4 + MD5-Works ) # Also execute each test listed in FileTestScript.cmake: -- cgit v0.12 From c1856a33d46384307884ab6ba6db886a7bca0fd2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 15 Nov 2011 20:18:58 -0500 Subject: sha2: Use KWIML fixed-size integer types and endian-ness These are more portable than those named in the original sha2 code. --- Source/cm_sha2.c | 41 ++++-------- Source/cm_sha2.h | 185 +++++++++---------------------------------------------- 2 files changed, 42 insertions(+), 184 deletions(-) diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index 855a5bb..0bf62f2 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -87,37 +87,20 @@ * made). */ #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) -#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +/* CMake modification: use byte order from cmIML. */ +# include "cmIML/ABI.h" +# undef BYTE_ORDER +# undef BIG_ENDIAN +# undef LITTLE_ENDIAN +# define BYTE_ORDER cmIML_ABI_ENDIAN_ID +# define BIG_ENDIAN cmIML_ABI_ENDIAN_ID_BIG +# define LITTLE_ENDIAN cmIML_ABI_ENDIAN_ID_LITTLE #endif -/* - * Define the following sha_* types to types of the correct length on - * the native archtecture. Most BSD systems and Linux define u_intXX_t - * types. Machines with very recent ANSI C headers, can use the - * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H - * during compile or in the sha.h header file. - * - * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t - * will need to define these three typedefs below (and the appropriate - * ones in sha.h too) by hand according to their system architecture. - * - * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t - * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. - */ -#ifdef SHA2_USE_INTTYPES_H - -typedef uint8_t sha_byte; /* Exactly 1 byte */ -typedef uint32_t sha_word32; /* Exactly 4 bytes */ -typedef uint64_t sha_word64; /* Exactly 8 bytes */ - -#else /* SHA2_USE_INTTYPES_H */ - -typedef u_int8_t sha_byte; /* Exactly 1 byte */ -typedef u_int32_t sha_word32; /* Exactly 4 bytes */ -typedef u_int64_t sha_word64; /* Exactly 8 bytes */ - -#endif /* SHA2_USE_INTTYPES_H */ - +/* CMake modification: use types computed in header. */ +typedef cm_sha2_uint8_t sha_byte; /* Exactly 1 byte */ +typedef cm_sha2_uint32_t sha_word32; /* Exactly 4 bytes */ +typedef cm_sha2_uint64_t sha_word64; /* Exactly 8 bytes */ /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h index 9459f75..284ee6a 100644 --- a/Source/cm_sha2.h +++ b/Source/cm_sha2.h @@ -36,6 +36,12 @@ #ifndef __SHA2_H__ #define __SHA2_H__ +/* CMake modification: use integer types from cmIML. */ +#include "cmIML/INT.h" +typedef cmIML_INT_uint8_t cm_sha2_uint8_t; +typedef cmIML_INT_uint32_t cm_sha2_uint32_t; +typedef cmIML_INT_uint64_t cm_sha2_uint64_t; + #ifdef __cplusplus extern "C" { #endif @@ -48,13 +54,6 @@ extern "C" { */ #include -#ifdef SHA2_USE_INTTYPES_H - -#include - -#endif /* SHA2_USE_INTTYPES_H */ - - /*** SHA-224/256/384/512 Various Length Definitions *******************/ /* Digest lengths for SHA-1/224/256/384/512 */ @@ -71,185 +70,61 @@ extern "C" { /*** SHA-224/256/384/512 Context Structures ***************************/ -/* NOTE: If your architecture does not define either u_intXX_t types or - * uintXX_t (from inttypes.h), you may need to define things by hand - * for your system: - */ -#if 0 -typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ -typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ -typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ -#endif -/* - * Most BSD systems already define u_intXX_t types, as does Linux. - * Some systems, however, like Compaq's Tru64 Unix instead can use - * uintXX_t types defined by very recent ANSI C standards and included - * in the file: - * - * #include - * - * If you choose to use then please define: - * - * #define SHA2_USE_INTTYPES_H - * - * Or on the command line during compile: - * - * cc -DSHA2_USE_INTTYPES_H ... - */ -#ifdef SHA2_USE_INTTYPES_H typedef union _SHA_CTX { /* SHA-1 uses this part of the union: */ struct { - uint32_t state[5]; - uint64_t bitcount; - uint8_t buffer[64]; + cm_sha2_uint32_t state[5]; + cm_sha2_uint64_t bitcount; + cm_sha2_uint8_t buffer[64]; } s1; /* SHA-224 and SHA-256 use this part of the union: */ struct { - uint32_t state[8]; - uint64_t bitcount; - uint8_t buffer[64]; + cm_sha2_uint32_t state[8]; + cm_sha2_uint64_t bitcount; + cm_sha2_uint8_t buffer[64]; } s256; /* SHA-384 and SHA-512 use this part of the union: */ struct { - uint64_t state[8]; - uint64_t bitcount[2]; - uint8_t buffer[128]; + cm_sha2_uint64_t state[8]; + cm_sha2_uint64_t bitcount[2]; + cm_sha2_uint8_t buffer[128]; } s512; } SHA_CTX; -#else /* SHA2_USE_INTTYPES_H */ - -typedef union _SHA_CTX { - /* SHA-1 uses this part of the union: */ - struct { - u_int32_t state[5]; - u_int64_t bitcount; - u_int8_t buffer[64]; - } s1; - - /* SHA-224 and SHA-256 use this part of the union: */ - struct { - u_int32_t state[8]; - u_int64_t bitcount; - u_int8_t buffer[64]; - } s256; - - /* SHA-384 and SHA-512 use this part of the union: */ - struct { - u_int64_t state[8]; - u_int64_t bitcount[2]; - u_int8_t buffer[128]; - } s512; -} SHA_CTX; - -#endif /* SHA2_USE_INTTYPES_H */ - - /*** SHA-256/384/512 Function Prototypes ******************************/ -#ifndef NOPROTO -#ifdef SHA2_USE_INTTYPES_H void SHA1_Init(SHA_CTX*); -void SHA1_Update(SHA_CTX*, const uint8_t*, size_t); -void SHA1_Final(uint8_t[SHA1_DIGEST_LENGTH], SHA_CTX*); +void SHA1_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA1_Final(cm_sha2_uint8_t[SHA1_DIGEST_LENGTH], SHA_CTX*); char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); -char* SHA1_Data(const uint8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); +char* SHA1_Data(const cm_sha2_uint8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); void SHA224_Init(SHA_CTX*); -void SHA224_Update(SHA_CTX*, const uint8_t*, size_t); -void SHA224_Final(uint8_t[SHA224_DIGEST_LENGTH], SHA_CTX*); +void SHA224_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA224_Final(cm_sha2_uint8_t[SHA224_DIGEST_LENGTH], SHA_CTX*); char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]); -char* SHA224_Data(const uint8_t*, size_t, char[SHA224_DIGEST_STRING_LENGTH]); +char* SHA224_Data(const cm_sha2_uint8_t*, size_t, char[SHA224_DIGEST_STRING_LENGTH]); void SHA256_Init(SHA_CTX*); -void SHA256_Update(SHA_CTX*, const uint8_t*, size_t); -void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA_CTX*); +void SHA256_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA256_Final(cm_sha2_uint8_t[SHA256_DIGEST_LENGTH], SHA_CTX*); char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const cm_sha2_uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA_CTX*); -void SHA384_Update(SHA_CTX*, const uint8_t*, size_t); -void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA_CTX*); +void SHA384_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA384_Final(cm_sha2_uint8_t[SHA384_DIGEST_LENGTH], SHA_CTX*); char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const cm_sha2_uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA_CTX*); -void SHA512_Update(SHA_CTX*, const uint8_t*, size_t); -void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA_CTX*); +void SHA512_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); +void SHA512_Final(cm_sha2_uint8_t[SHA512_DIGEST_LENGTH], SHA_CTX*); char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); - -#else /* SHA2_USE_INTTYPES_H */ - -void SHA1_Init(SHA_CTX*); -void SHA1_Update(SHA_CTX*, const u_int8_t*, size_t); -void SHA1_Final(u_int8_t[SHA1_DIGEST_LENGTH], SHA_CTX*); -char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); -char* SHA1_Data(const u_int8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); - -void SHA224_Init(SHA_CTX*); -void SHA224_Update(SHA_CTX*, const u_int8_t*, size_t); -void SHA224_Final(u_int8_t[SHA224_DIGEST_LENGTH], SHA_CTX*); -char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]); -char* SHA224_Data(const u_int8_t*, size_t, char[SHA224_DIGEST_STRING_LENGTH]); - -void SHA256_Init(SHA_CTX*); -void SHA256_Update(SHA_CTX*, const u_int8_t*, size_t); -void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA_CTX*); -char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); - -void SHA384_Init(SHA_CTX*); -void SHA384_Update(SHA_CTX*, const u_int8_t*, size_t); -void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA_CTX*); -char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); - -void SHA512_Init(SHA_CTX*); -void SHA512_Update(SHA_CTX*, const u_int8_t*, size_t); -void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA_CTX*); -char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); - -#endif /* SHA2_USE_INTTYPES_H */ - -#else /* NOPROTO */ - -void SHA1_Init(); -void SHA1_Update(); -void SHA1_Final(); -char* SHA1_End(); -char* SHA1_Data(); - -void SHA224_Init(); -void SHA224_Update(); -void SHA224_Final(); -char* SHA224_End(); -char* SHA224_Data(); - -void SHA256_Init(); -void SHA256_Update(); -void SHA256_Final(); -char* SHA256_End(); -char* SHA256_Data(); - -void SHA384_Init(); -void SHA384_Update(); -void SHA384_Final(); -char* SHA384_End(); -char* SHA384_Data(); - -void SHA512_Init(); -void SHA512_Update(); -void SHA512_Final(); -char* SHA512_End(); -char* SHA512_Data(); - -#endif /* NOPROTO */ +char* SHA512_Data(const cm_sha2_uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #ifdef __cplusplus } -- cgit v0.12 From 73efd4a5044d2346e14d019197e2ddced3f9b7a8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 15 Nov 2011 20:22:51 -0500 Subject: sha2: Build as part of CMakeLib Mangle sha2 symbols to avoid conflict with system libs. --- Source/CMakeLists.txt | 2 ++ Source/cm_sha2.h | 2 ++ Source/cm_sha2_mangle.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 Source/cm_sha2_mangle.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 284c84d..5205738 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -261,6 +261,8 @@ SET(SRCS cmakewizard.cxx cmakewizard.h + cm_sha2.h + cm_sha2.c cm_utf8.h cm_utf8.c ) diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h index 284ee6a..ebe5e5a 100644 --- a/Source/cm_sha2.h +++ b/Source/cm_sha2.h @@ -36,6 +36,8 @@ #ifndef __SHA2_H__ #define __SHA2_H__ +#include "cm_sha2_mangle.h" + /* CMake modification: use integer types from cmIML. */ #include "cmIML/INT.h" typedef cmIML_INT_uint8_t cm_sha2_uint8_t; diff --git a/Source/cm_sha2_mangle.h b/Source/cm_sha2_mangle.h new file mode 100644 index 0000000..e73d131 --- /dev/null +++ b/Source/cm_sha2_mangle.h @@ -0,0 +1,51 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2011 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cm_sha2_mangle_h +#define cm_sha2_mangle_h + +/* Mangle sha2 symbol names to avoid possible conflict with + implementations in other libraries to which CMake links. */ +#define SHA1_Data cmSHA1_Data +#define SHA1_End cmSHA1_End +#define SHA1_Final cmSHA1_Final +#define SHA1_Init cmSHA1_Init +#define SHA1_Internal_Transform cmSHA1_Internal_Transform +#define SHA1_Update cmSHA1_Update +#define SHA224_Data cmSHA224_Data +#define SHA224_End cmSHA224_End +#define SHA224_Final cmSHA224_Final +#define SHA224_Init cmSHA224_Init +#define SHA224_Internal_Transform cmSHA224_Internal_Transform +#define SHA224_Update cmSHA224_Update +#define SHA256_Data cmSHA256_Data +#define SHA256_End cmSHA256_End +#define SHA256_Final cmSHA256_Final +#define SHA256_Init cmSHA256_Init +#define SHA256_Internal_Init cmSHA256_Internal_Init +#define SHA256_Internal_Last cmSHA256_Internal_Last +#define SHA256_Internal_Transform cmSHA256_Internal_Transform +#define SHA256_Update cmSHA256_Update +#define SHA384_Data cmSHA384_Data +#define SHA384_End cmSHA384_End +#define SHA384_Final cmSHA384_Final +#define SHA384_Init cmSHA384_Init +#define SHA384_Update cmSHA384_Update +#define SHA512_Data cmSHA512_Data +#define SHA512_End cmSHA512_End +#define SHA512_Final cmSHA512_Final +#define SHA512_Init cmSHA512_Init +#define SHA512_Internal_Init cmSHA512_Internal_Init +#define SHA512_Internal_Last cmSHA512_Internal_Last +#define SHA512_Internal_Transform cmSHA512_Internal_Transform +#define SHA512_Update cmSHA512_Update + +#endif -- cgit v0.12 From 38771d3bdf51b81d46578e0c81ebddbdea0ce3b2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 15 Nov 2011 20:32:43 -0500 Subject: Add file(SHA*) commands to compute cryptographic hashes Add a file() command API for SHA1, SHA224, SHA256, SHA384, and SHA512. --- Source/cmCryptoHash.cxx | 21 +++++++++++++++++++++ Source/cmCryptoHash.h | 21 +++++++++++++++++++++ Source/cmFileCommand.cxx | 17 ++++++++++++++++- Source/cmFileCommand.h | 4 ++-- Tests/CMakeTests/File-SHA1-Works.cmake | 2 ++ Tests/CMakeTests/File-SHA224-Works.cmake | 2 ++ Tests/CMakeTests/File-SHA256-Works.cmake | 2 ++ Tests/CMakeTests/File-SHA384-Works.cmake | 2 ++ Tests/CMakeTests/File-SHA512-Works.cmake | 2 ++ Tests/CMakeTests/FileTest.cmake.in | 15 +++++++++++++++ 10 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 Tests/CMakeTests/File-SHA1-Works.cmake create mode 100644 Tests/CMakeTests/File-SHA224-Works.cmake create mode 100644 Tests/CMakeTests/File-SHA256-Works.cmake create mode 100644 Tests/CMakeTests/File-SHA384-Works.cmake create mode 100644 Tests/CMakeTests/File-SHA512-Works.cmake diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx index 3a73398..411da58 100644 --- a/Source/cmCryptoHash.cxx +++ b/Source/cmCryptoHash.cxx @@ -12,6 +12,7 @@ #include "cmCryptoHash.h" #include +#include "cm_sha2.h" //---------------------------------------------------------------------------- std::string cmCryptoHash::HashString(const char* input) @@ -88,3 +89,23 @@ std::string cmCryptoHashMD5::Finalize() cmsysMD5_FinalizeHex(this->MD5, md5out); return std::string(md5out, 32); } + + +#define cmCryptoHash_SHA_CLASS_IMPL(SHA) \ +cmCryptoHash##SHA::cmCryptoHash##SHA(): SHA(new SHA_CTX) {} \ +cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; } \ +void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); } \ +void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz) \ +{ SHA##_Update(this->SHA, buf, sz); } \ +std::string cmCryptoHash##SHA::Finalize() \ +{ \ + char out[SHA##_DIGEST_STRING_LENGTH]; \ + SHA##_End(this->SHA, out); \ + return std::string(out, SHA##_DIGEST_STRING_LENGTH-1); \ +} + +cmCryptoHash_SHA_CLASS_IMPL(SHA1) +cmCryptoHash_SHA_CLASS_IMPL(SHA224) +cmCryptoHash_SHA_CLASS_IMPL(SHA256) +cmCryptoHash_SHA_CLASS_IMPL(SHA384) +cmCryptoHash_SHA_CLASS_IMPL(SHA512) diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h index 670624c..c17104b 100644 --- a/Source/cmCryptoHash.h +++ b/Source/cmCryptoHash.h @@ -37,4 +37,25 @@ protected: virtual std::string Finalize(); }; +#define cmCryptoHash_SHA_CLASS_DECL(SHA) \ + class cmCryptoHash##SHA: public cmCryptoHash \ + { \ + union _SHA_CTX* SHA; \ + public: \ + cmCryptoHash##SHA(); \ + ~cmCryptoHash##SHA(); \ + protected: \ + virtual void Initialize(); \ + virtual void Append(unsigned char const* buf, int sz); \ + virtual std::string Finalize(); \ + } + +cmCryptoHash_SHA_CLASS_DECL(SHA1); +cmCryptoHash_SHA_CLASS_DECL(SHA224); +cmCryptoHash_SHA_CLASS_DECL(SHA256); +cmCryptoHash_SHA_CLASS_DECL(SHA384); +cmCryptoHash_SHA_CLASS_DECL(SHA512); + +#undef cmCryptoHash_SHA_CLASS_DECL + #endif diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 32454f5..35c743d 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -85,7 +85,12 @@ bool cmFileCommand { return this->HandleReadCommand(args); } - else if ( subCommand == "MD5" ) + else if ( subCommand == "MD5" || + subCommand == "SHA1" || + subCommand == "SHA224" || + subCommand == "SHA256" || + subCommand == "SHA384" || + subCommand == "SHA512" ) { return this->HandleHashCommand(args); } @@ -358,6 +363,16 @@ bool cmFileCommand::HandleHashCommand(std::vector const& args) cmsys::auto_ptr hash; if(args[0] == "MD5") { hash.reset(new cmCryptoHashMD5); } + else if(args[0] == "SHA1") + { hash.reset(new cmCryptoHashSHA1); } + else if(args[0] == "SHA224") + { hash.reset(new cmCryptoHashSHA224); } + else if(args[0] == "SHA256") + { hash.reset(new cmCryptoHashSHA256); } + else if(args[0] == "SHA384") + { hash.reset(new cmCryptoHashSHA384); } + else if(args[0] == "SHA512") + { hash.reset(new cmCryptoHashSHA512); } if(hash.get()) { std::string out = hash->HashFile(args[1].c_str()); diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index dce6478..9e2ed0f 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -65,7 +65,7 @@ public: " file(WRITE filename \"message to write\"... )\n" " file(APPEND filename \"message to write\"... )\n" " file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX])\n" - " file(MD5 filename variable)\n" + " file( filename variable)\n" " file(STRINGS filename variable [LIMIT_COUNT num]\n" " [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes]\n" " [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes]\n" @@ -95,7 +95,7 @@ public: "variable. It will start at the given offset and read up to numBytes. " "If the argument HEX is given, the binary data will be converted to " "hexadecimal representation and this will be stored in the variable.\n" - "MD5 " + "MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 " "will compute a cryptographic hash of the content of a file.\n" "STRINGS will parse a list of ASCII strings from a file and " "store it in a variable. Binary data in the file are ignored. Carriage " diff --git a/Tests/CMakeTests/File-SHA1-Works.cmake b/Tests/CMakeTests/File-SHA1-Works.cmake new file mode 100644 index 0000000..03ea3ac --- /dev/null +++ b/Tests/CMakeTests/File-SHA1-Works.cmake @@ -0,0 +1,2 @@ +file(SHA1 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha1) +message("${sha1}") diff --git a/Tests/CMakeTests/File-SHA224-Works.cmake b/Tests/CMakeTests/File-SHA224-Works.cmake new file mode 100644 index 0000000..0295346 --- /dev/null +++ b/Tests/CMakeTests/File-SHA224-Works.cmake @@ -0,0 +1,2 @@ +file(SHA224 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha224) +message("${sha224}") diff --git a/Tests/CMakeTests/File-SHA256-Works.cmake b/Tests/CMakeTests/File-SHA256-Works.cmake new file mode 100644 index 0000000..32bc9fe --- /dev/null +++ b/Tests/CMakeTests/File-SHA256-Works.cmake @@ -0,0 +1,2 @@ +file(SHA256 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha256) +message("${sha256}") diff --git a/Tests/CMakeTests/File-SHA384-Works.cmake b/Tests/CMakeTests/File-SHA384-Works.cmake new file mode 100644 index 0000000..5c56de2 --- /dev/null +++ b/Tests/CMakeTests/File-SHA384-Works.cmake @@ -0,0 +1,2 @@ +file(SHA384 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha384) +message("${sha384}") diff --git a/Tests/CMakeTests/File-SHA512-Works.cmake b/Tests/CMakeTests/File-SHA512-Works.cmake new file mode 100644 index 0000000..cf10706 --- /dev/null +++ b/Tests/CMakeTests/File-SHA512-Works.cmake @@ -0,0 +1,2 @@ +file(SHA512 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha512) +message("${sha512}") diff --git a/Tests/CMakeTests/FileTest.cmake.in b/Tests/CMakeTests/FileTest.cmake.in index 3aa88a7..824aba7 100644 --- a/Tests/CMakeTests/FileTest.cmake.in +++ b/Tests/CMakeTests/FileTest.cmake.in @@ -22,6 +22,16 @@ set(MD5-BadArg4-RESULT 1) set(MD5-BadArg4-STDERR "file MD5 requires a file name and output variable") set(MD5-Works-RESULT 0) set(MD5-Works-STDERR "a28a44fb5b58a6acf0cbec46557bc775") +set(SHA1-Works-RESULT 0) +set(SHA1-Works-STDERR "e0ce452a7e34e9c705b46e4e7c9cd959082c0777") +set(SHA224-Works-RESULT 0) +set(SHA224-Works-STDERR "d1f1c9db3df73586a5a200014505ef03b70da5e0539eb35c11b4ef6f") +set(SHA256-Works-RESULT 0) +set(SHA256-Works-STDERR "bb38de1c34713f750a4f84404ef5fb1efb93cf815cb09182db457ba91de19195") +set(SHA384-Works-RESULT 0) +set(SHA384-Works-STDERR "2f01d58436bd04a40ec2c938a15f2bb661bf1bf1560a5f2d40a3ebbb716a58e400ab2992c23ba19fa96dc519e0042c26") +set(SHA512-Works-RESULT 0) +set(SHA512-Works-STDERR "349d02e347ddb133afb4557c9e541163f54b6eaa9eb345672bfd7bbce90c9872bf1fad9c6662248eb7b092aef719e4b8c3b8bb1cf47f287abbde12360c073686") include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") check_cmake_test(File @@ -37,6 +47,11 @@ check_cmake_test(File MD5-BadArg2 MD5-BadArg4 MD5-Works + SHA1-Works + SHA224-Works + SHA256-Works + SHA384-Works + SHA512-Works ) # Also execute each test listed in FileTestScript.cmake: -- cgit v0.12 From 46ab0561fc29446a736985816b005200aad9489c Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 07:56:31 -0500 Subject: sha2: Use "static const" instead of "const static" declarations Fix old-style declarations in the original code. --- Source/cm_sha2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index 0bf62f2..ecb2d9c 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -228,7 +228,7 @@ void SHA512_Internal_Transform(SHA_CTX*, const sha_word64*); #define K1_60_TO_79 0xca62c1d6UL /* Initial hash value H for SHA-1: */ -const static sha_word32 sha1_initial_hash_value[5] = { +static const sha_word32 sha1_initial_hash_value[5] = { 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, @@ -237,7 +237,7 @@ const static sha_word32 sha1_initial_hash_value[5] = { }; /* Hash constant words K for SHA-224 and SHA-256: */ -const static sha_word32 K256[64] = { +static const sha_word32 K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, @@ -257,7 +257,7 @@ const static sha_word32 K256[64] = { }; /* Initial hash value H for SHA-224: */ -const static sha_word32 sha224_initial_hash_value[8] = { +static const sha_word32 sha224_initial_hash_value[8] = { 0xc1059ed8UL, 0x367cd507UL, 0x3070dd17UL, @@ -269,7 +269,7 @@ const static sha_word32 sha224_initial_hash_value[8] = { }; /* Initial hash value H for SHA-256: */ -const static sha_word32 sha256_initial_hash_value[8] = { +static const sha_word32 sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, @@ -281,7 +281,7 @@ const static sha_word32 sha256_initial_hash_value[8] = { }; /* Hash constant words K for SHA-384 and SHA-512: */ -const static sha_word64 K512[80] = { +static const sha_word64 K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, @@ -325,7 +325,7 @@ const static sha_word64 K512[80] = { }; /* Initial hash value H for SHA-384 */ -const static sha_word64 sha384_initial_hash_value[8] = { +static const sha_word64 sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, @@ -337,7 +337,7 @@ const static sha_word64 sha384_initial_hash_value[8] = { }; /* Initial hash value H for SHA-512 */ -const static sha_word64 sha512_initial_hash_value[8] = { +static const sha_word64 sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, -- cgit v0.12 From 293a7f4e2ae9b458d3efefcfe133d0ad5320a1b2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 10:04:41 -0500 Subject: cmCryptoHash: Provide factory "New" method Construct a cmCryptoHash subclass instance based on the name of the desired hash algorithm. --- Source/cmCryptoHash.cxx | 19 +++++++++++++++++++ Source/cmCryptoHash.h | 3 +++ Source/cmFileCommand.cxx | 14 +------------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx index 411da58..a1505bd 100644 --- a/Source/cmCryptoHash.cxx +++ b/Source/cmCryptoHash.cxx @@ -15,6 +15,25 @@ #include "cm_sha2.h" //---------------------------------------------------------------------------- +cmsys::auto_ptr cmCryptoHash::New(const char* algo) +{ + if(strcmp(algo,"MD5") == 0) + { return cmsys::auto_ptr(new cmCryptoHashMD5); } + else if(strcmp(algo,"SHA1") == 0) + { return cmsys::auto_ptr(new cmCryptoHashSHA1); } + else if(strcmp(algo,"SHA224") == 0) + { return cmsys::auto_ptr(new cmCryptoHashSHA224); } + else if(strcmp(algo,"SHA256") == 0) + { return cmsys::auto_ptr(new cmCryptoHashSHA256); } + else if(strcmp(algo,"SHA384") == 0) + { return cmsys::auto_ptr(new cmCryptoHashSHA384); } + else if(strcmp(algo,"SHA512") == 0) + { return cmsys::auto_ptr(new cmCryptoHashSHA512); } + else + { return cmsys::auto_ptr(0); } +} + +//---------------------------------------------------------------------------- std::string cmCryptoHash::HashString(const char* input) { this->Initialize(); diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h index c17104b..0a33365 100644 --- a/Source/cmCryptoHash.h +++ b/Source/cmCryptoHash.h @@ -14,9 +14,12 @@ #include "cmStandardIncludes.h" +#include + class cmCryptoHash { public: + static cmsys::auto_ptr New(const char* algo); std::string HashString(const char* input); std::string HashFile(const char* file); protected: diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 35c743d..bab3116 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -360,19 +360,7 @@ bool cmFileCommand::HandleHashCommand(std::vector const& args) return false; } - cmsys::auto_ptr hash; - if(args[0] == "MD5") - { hash.reset(new cmCryptoHashMD5); } - else if(args[0] == "SHA1") - { hash.reset(new cmCryptoHashSHA1); } - else if(args[0] == "SHA224") - { hash.reset(new cmCryptoHashSHA224); } - else if(args[0] == "SHA256") - { hash.reset(new cmCryptoHashSHA256); } - else if(args[0] == "SHA384") - { hash.reset(new cmCryptoHashSHA384); } - else if(args[0] == "SHA512") - { hash.reset(new cmCryptoHashSHA512); } + cmsys::auto_ptr hash(cmCryptoHash::New(args[0].c_str())); if(hash.get()) { std::string out = hash->HashFile(args[1].c_str()); -- cgit v0.12 From 2e9c26cf9616fead92ec65eefc696bcf9761b996 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 10:12:18 -0500 Subject: Add string(MD5) and string(SHA*) commands to compute hashes Provide a CMake-language binding to these cryptographic hashes. Add a string() command API for MD5, SHA1, SHA224, SHA256, SHA384, and SHA512. --- Source/cmStringCommand.cxx | 32 ++++++++++++++++++++++++++++++ Source/cmStringCommand.h | 5 +++++ Tests/CMakeTests/String-MD5-BadArg1.cmake | 1 + Tests/CMakeTests/String-MD5-BadArg2.cmake | 1 + Tests/CMakeTests/String-MD5-BadArg4.cmake | 1 + Tests/CMakeTests/String-MD5-Works.cmake | 2 ++ Tests/CMakeTests/String-SHA1-Works.cmake | 2 ++ Tests/CMakeTests/String-SHA224-Works.cmake | 2 ++ Tests/CMakeTests/String-SHA256-Works.cmake | 2 ++ Tests/CMakeTests/String-SHA384-Works.cmake | 2 ++ Tests/CMakeTests/String-SHA512-Works.cmake | 2 ++ Tests/CMakeTests/StringTest.cmake.in | 32 ++++++++++++++++++++++++++++++ 12 files changed, 84 insertions(+) create mode 100644 Tests/CMakeTests/String-MD5-BadArg1.cmake create mode 100644 Tests/CMakeTests/String-MD5-BadArg2.cmake create mode 100644 Tests/CMakeTests/String-MD5-BadArg4.cmake create mode 100644 Tests/CMakeTests/String-MD5-Works.cmake create mode 100644 Tests/CMakeTests/String-SHA1-Works.cmake create mode 100644 Tests/CMakeTests/String-SHA224-Works.cmake create mode 100644 Tests/CMakeTests/String-SHA256-Works.cmake create mode 100644 Tests/CMakeTests/String-SHA384-Works.cmake create mode 100644 Tests/CMakeTests/String-SHA512-Works.cmake diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index d239c06..f2f2681 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -10,6 +10,8 @@ See the License for more information. ============================================================================*/ #include "cmStringCommand.h" +#include "cmCryptoHash.h" + #include #include @@ -36,6 +38,15 @@ bool cmStringCommand { return this->HandleReplaceCommand(args); } + else if ( subCommand == "MD5" || + subCommand == "SHA1" || + subCommand == "SHA224" || + subCommand == "SHA256" || + subCommand == "SHA384" || + subCommand == "SHA512" ) + { + return this->HandleHashCommand(args); + } else if(subCommand == "TOLOWER") { return this->HandleToUpperLowerCommand(args, false); @@ -83,6 +94,27 @@ bool cmStringCommand } //---------------------------------------------------------------------------- +bool cmStringCommand::HandleHashCommand(std::vector const& args) +{ + if(args.size() != 3) + { + cmOStringStream e; + e << args[0] << " requires an output variable and an input string"; + this->SetError(e.str().c_str()); + return false; + } + + cmsys::auto_ptr hash(cmCryptoHash::New(args[0].c_str())); + if(hash.get()) + { + std::string out = hash->HashString(args[2].c_str()); + this->Makefile->AddDefinition(args[1].c_str(), out.c_str()); + return true; + } + return false; +} + +//---------------------------------------------------------------------------- bool cmStringCommand::HandleToUpperLowerCommand( std::vector const& args, bool toUpper) { diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 52b83d9..452f4a1 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -76,6 +76,8 @@ public: " string(REPLACE \n" " \n" " [...])\n" + " string(\n" + " )\n" " string(COMPARE EQUAL )\n" " string(COMPARE NOTEQUAL )\n" " string(COMPARE LESS )\n" @@ -103,6 +105,8 @@ public: "backslash through argument parsing.\n" "REPLACE will replace all occurrences of match_string in the input with " "replace_string and store the result in the output.\n" + "MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 " + "will compute a cryptographic hash of the input string.\n" "COMPARE EQUAL/NOTEQUAL/LESS/GREATER will compare the strings and " "store true or false in the output variable.\n" "ASCII will convert all numbers into corresponding ASCII characters.\n" @@ -150,6 +154,7 @@ protected: bool RegexMatch(std::vector const& args); bool RegexMatchAll(std::vector const& args); bool RegexReplace(std::vector const& args); + bool HandleHashCommand(std::vector const& args); bool HandleToUpperLowerCommand(std::vector const& args, bool toUpper); bool HandleCompareCommand(std::vector const& args); diff --git a/Tests/CMakeTests/String-MD5-BadArg1.cmake b/Tests/CMakeTests/String-MD5-BadArg1.cmake new file mode 100644 index 0000000..8946476 --- /dev/null +++ b/Tests/CMakeTests/String-MD5-BadArg1.cmake @@ -0,0 +1 @@ +string(MD5) diff --git a/Tests/CMakeTests/String-MD5-BadArg2.cmake b/Tests/CMakeTests/String-MD5-BadArg2.cmake new file mode 100644 index 0000000..abbbf87 --- /dev/null +++ b/Tests/CMakeTests/String-MD5-BadArg2.cmake @@ -0,0 +1 @@ +string(MD5 md5) diff --git a/Tests/CMakeTests/String-MD5-BadArg4.cmake b/Tests/CMakeTests/String-MD5-BadArg4.cmake new file mode 100644 index 0000000..edd4427 --- /dev/null +++ b/Tests/CMakeTests/String-MD5-BadArg4.cmake @@ -0,0 +1 @@ +string(MD5 md5 input extra_arg) diff --git a/Tests/CMakeTests/String-MD5-Works.cmake b/Tests/CMakeTests/String-MD5-Works.cmake new file mode 100644 index 0000000..4ef7a07 --- /dev/null +++ b/Tests/CMakeTests/String-MD5-Works.cmake @@ -0,0 +1,2 @@ +string(MD5 md5 "sample input string\n") +message("${md5}") diff --git a/Tests/CMakeTests/String-SHA1-Works.cmake b/Tests/CMakeTests/String-SHA1-Works.cmake new file mode 100644 index 0000000..2f3b51b --- /dev/null +++ b/Tests/CMakeTests/String-SHA1-Works.cmake @@ -0,0 +1,2 @@ +string(SHA1 sha1 "sample input string\n") +message("${sha1}") diff --git a/Tests/CMakeTests/String-SHA224-Works.cmake b/Tests/CMakeTests/String-SHA224-Works.cmake new file mode 100644 index 0000000..5b7f880 --- /dev/null +++ b/Tests/CMakeTests/String-SHA224-Works.cmake @@ -0,0 +1,2 @@ +string(SHA224 sha224 "sample input string\n") +message("${sha224}") diff --git a/Tests/CMakeTests/String-SHA256-Works.cmake b/Tests/CMakeTests/String-SHA256-Works.cmake new file mode 100644 index 0000000..e3e89ae --- /dev/null +++ b/Tests/CMakeTests/String-SHA256-Works.cmake @@ -0,0 +1,2 @@ +string(SHA256 sha256 "sample input string\n") +message("${sha256}") diff --git a/Tests/CMakeTests/String-SHA384-Works.cmake b/Tests/CMakeTests/String-SHA384-Works.cmake new file mode 100644 index 0000000..828a190 --- /dev/null +++ b/Tests/CMakeTests/String-SHA384-Works.cmake @@ -0,0 +1,2 @@ +string(SHA384 sha384 "sample input string\n") +message("${sha384}") diff --git a/Tests/CMakeTests/String-SHA512-Works.cmake b/Tests/CMakeTests/String-SHA512-Works.cmake new file mode 100644 index 0000000..e17db5c --- /dev/null +++ b/Tests/CMakeTests/String-SHA512-Works.cmake @@ -0,0 +1,2 @@ +string(SHA512 sha512 "sample input string\n") +message("${sha512}") diff --git a/Tests/CMakeTests/StringTest.cmake.in b/Tests/CMakeTests/StringTest.cmake.in index 6bb60f4..49e7dc9 100644 --- a/Tests/CMakeTests/StringTest.cmake.in +++ b/Tests/CMakeTests/StringTest.cmake.in @@ -1,3 +1,35 @@ +set(MD5-BadArg1-RESULT 1) +set(MD5-BadArg1-STDERR "string MD5 requires an output variable") +set(MD5-BadArg2-RESULT 1) +set(MD5-BadArg2-STDERR "string MD5 requires an output variable and an input string") +set(MD5-BadArg4-RESULT 1) +set(MD5-BadArg4-STDERR "string MD5 requires an output variable and an input string") +set(MD5-Works-RESULT 0) +set(MD5-Works-STDERR "10d20ddb981a6202b84aa1ce1cb7fce3") +set(SHA1-Works-RESULT 0) +set(SHA1-Works-STDERR "83f093e04289b21a9415f408ad50be8b57ad2f34") +set(SHA224-Works-RESULT 0) +set(SHA224-Works-STDERR "e995a7789922c4ef9279d94e763c8375934180a51baa7147bc48edf7") +set(SHA256-Works-RESULT 0) +set(SHA256-Works-STDERR "d1c5915d8b71150726a1eef75a29ec6bea8fd1bef6b7299ef8048760b0402025") +set(SHA384-Works-RESULT 0) +set(SHA384-Works-STDERR "1de9560b4e030e02051ea408200ffc55d70c97ac64ebf822461a5c786f495c36df43259b14483bc8d364f0106f4971ee") +set(SHA512-Works-RESULT 0) +set(SHA512-Works-STDERR "3982a1b4e651768bec70ab1fb97045cb7a659f4ba7203d501c52ab2e803071f9d5fd272022df15f27727fc67f8cd022e710e29010b2a9c0b467c111e2f6abf51") + +include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") +check_cmake_test(String + MD5-BadArg1 + MD5-BadArg2 + MD5-BadArg4 + MD5-Works + SHA1-Works + SHA224-Works + SHA256-Works + SHA384-Works + SHA512-Works + ) + # Execute each test listed in StringTestScript.cmake: # set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/StringTestScript.cmake") -- cgit v0.12 From 23b3df76a069ab314a4828ad651f1a14319ff660 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 10:48:10 -0500 Subject: sha2: Use KWIML fixed-size integer constant macros Define SHA_UINT32_C and SHA_UINT64_C using the KWIML versions. Use them in place of hard-coded UL and ULL constant suffixes. --- Source/cm_sha2.c | 223 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 121 insertions(+), 102 deletions(-) diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index ecb2d9c..c64a597 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -101,21 +101,24 @@ typedef cm_sha2_uint8_t sha_byte; /* Exactly 1 byte */ typedef cm_sha2_uint32_t sha_word32; /* Exactly 4 bytes */ typedef cm_sha2_uint64_t sha_word64; /* Exactly 8 bytes */ +#define SHA_UINT32_C(x) cmIML_INT_UINT32_C(x) +#define SHA_UINT64_C(x) cmIML_INT_UINT64_C(x) /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #define REVERSE32(w,x) { \ sha_word32 tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ + (x) = ((tmp & SHA_UINT32_C(0xff00ff00)) >> 8) | \ + ((tmp & SHA_UINT32_C(0x00ff00ff)) << 8); \ } #define REVERSE64(w,x) { \ sha_word64 tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ - ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ - (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ - ((tmp & 0x0000ffff0000ffffULL) << 16); \ + tmp = ((tmp & SHA_UINT64_C(0xff00ff00ff00ff00)) >> 8) | \ + ((tmp & SHA_UINT64_C(0x00ff00ff00ff00ff)) << 8); \ + (x) = ((tmp & SHA_UINT64_C(0xffff0000ffff0000)) >> 16) | \ + ((tmp & SHA_UINT64_C(0x0000ffff0000ffff)) << 16); \ } #endif /* BYTE_ORDER == LITTLE_ENDIAN */ @@ -222,130 +225,146 @@ void SHA512_Internal_Transform(SHA_CTX*, const sha_word64*); /*** SHA2 INITIAL HASH VALUES AND CONSTANTS ***************************/ /* Hash constant words K for SHA-1: */ -#define K1_0_TO_19 0x5a827999UL -#define K1_20_TO_39 0x6ed9eba1UL -#define K1_40_TO_59 0x8f1bbcdcUL -#define K1_60_TO_79 0xca62c1d6UL +#define K1_0_TO_19 SHA_UINT32_C(0x5a827999) +#define K1_20_TO_39 SHA_UINT32_C(0x6ed9eba1) +#define K1_40_TO_59 SHA_UINT32_C(0x8f1bbcdc) +#define K1_60_TO_79 SHA_UINT32_C(0xca62c1d6) /* Initial hash value H for SHA-1: */ static const sha_word32 sha1_initial_hash_value[5] = { - 0x67452301UL, - 0xefcdab89UL, - 0x98badcfeUL, - 0x10325476UL, - 0xc3d2e1f0UL + SHA_UINT32_C(0x67452301), + SHA_UINT32_C(0xefcdab89), + SHA_UINT32_C(0x98badcfe), + SHA_UINT32_C(0x10325476), + SHA_UINT32_C(0xc3d2e1f0) }; /* Hash constant words K for SHA-224 and SHA-256: */ static const sha_word32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL + SHA_UINT32_C(0x428a2f98), SHA_UINT32_C(0x71374491), + SHA_UINT32_C(0xb5c0fbcf), SHA_UINT32_C(0xe9b5dba5), + SHA_UINT32_C(0x3956c25b), SHA_UINT32_C(0x59f111f1), + SHA_UINT32_C(0x923f82a4), SHA_UINT32_C(0xab1c5ed5), + SHA_UINT32_C(0xd807aa98), SHA_UINT32_C(0x12835b01), + SHA_UINT32_C(0x243185be), SHA_UINT32_C(0x550c7dc3), + SHA_UINT32_C(0x72be5d74), SHA_UINT32_C(0x80deb1fe), + SHA_UINT32_C(0x9bdc06a7), SHA_UINT32_C(0xc19bf174), + SHA_UINT32_C(0xe49b69c1), SHA_UINT32_C(0xefbe4786), + SHA_UINT32_C(0x0fc19dc6), SHA_UINT32_C(0x240ca1cc), + SHA_UINT32_C(0x2de92c6f), SHA_UINT32_C(0x4a7484aa), + SHA_UINT32_C(0x5cb0a9dc), SHA_UINT32_C(0x76f988da), + SHA_UINT32_C(0x983e5152), SHA_UINT32_C(0xa831c66d), + SHA_UINT32_C(0xb00327c8), SHA_UINT32_C(0xbf597fc7), + SHA_UINT32_C(0xc6e00bf3), SHA_UINT32_C(0xd5a79147), + SHA_UINT32_C(0x06ca6351), SHA_UINT32_C(0x14292967), + SHA_UINT32_C(0x27b70a85), SHA_UINT32_C(0x2e1b2138), + SHA_UINT32_C(0x4d2c6dfc), SHA_UINT32_C(0x53380d13), + SHA_UINT32_C(0x650a7354), SHA_UINT32_C(0x766a0abb), + SHA_UINT32_C(0x81c2c92e), SHA_UINT32_C(0x92722c85), + SHA_UINT32_C(0xa2bfe8a1), SHA_UINT32_C(0xa81a664b), + SHA_UINT32_C(0xc24b8b70), SHA_UINT32_C(0xc76c51a3), + SHA_UINT32_C(0xd192e819), SHA_UINT32_C(0xd6990624), + SHA_UINT32_C(0xf40e3585), SHA_UINT32_C(0x106aa070), + SHA_UINT32_C(0x19a4c116), SHA_UINT32_C(0x1e376c08), + SHA_UINT32_C(0x2748774c), SHA_UINT32_C(0x34b0bcb5), + SHA_UINT32_C(0x391c0cb3), SHA_UINT32_C(0x4ed8aa4a), + SHA_UINT32_C(0x5b9cca4f), SHA_UINT32_C(0x682e6ff3), + SHA_UINT32_C(0x748f82ee), SHA_UINT32_C(0x78a5636f), + SHA_UINT32_C(0x84c87814), SHA_UINT32_C(0x8cc70208), + SHA_UINT32_C(0x90befffa), SHA_UINT32_C(0xa4506ceb), + SHA_UINT32_C(0xbef9a3f7), SHA_UINT32_C(0xc67178f2) }; /* Initial hash value H for SHA-224: */ static const sha_word32 sha224_initial_hash_value[8] = { - 0xc1059ed8UL, - 0x367cd507UL, - 0x3070dd17UL, - 0xf70e5939UL, - 0xffc00b31UL, - 0x68581511UL, - 0x64f98fa7UL, - 0xbefa4fa4UL + SHA_UINT32_C(0xc1059ed8), + SHA_UINT32_C(0x367cd507), + SHA_UINT32_C(0x3070dd17), + SHA_UINT32_C(0xf70e5939), + SHA_UINT32_C(0xffc00b31), + SHA_UINT32_C(0x68581511), + SHA_UINT32_C(0x64f98fa7), + SHA_UINT32_C(0xbefa4fa4) }; /* Initial hash value H for SHA-256: */ static const sha_word32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL + SHA_UINT32_C(0x6a09e667), + SHA_UINT32_C(0xbb67ae85), + SHA_UINT32_C(0x3c6ef372), + SHA_UINT32_C(0xa54ff53a), + SHA_UINT32_C(0x510e527f), + SHA_UINT32_C(0x9b05688c), + SHA_UINT32_C(0x1f83d9ab), + SHA_UINT32_C(0x5be0cd19) }; /* Hash constant words K for SHA-384 and SHA-512: */ static const sha_word64 K512[80] = { - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, - 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, - 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, - 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, - 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, - 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, - 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, - 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, - 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, - 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, - 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, - 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, - 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, - 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, - 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, - 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, - 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, - 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, - 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, - 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, - 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, - 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, - 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, - 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, - 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, - 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, - 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, - 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, - 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, - 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, - 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, - 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, - 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL + SHA_UINT64_C(0x428a2f98d728ae22), SHA_UINT64_C(0x7137449123ef65cd), + SHA_UINT64_C(0xb5c0fbcfec4d3b2f), SHA_UINT64_C(0xe9b5dba58189dbbc), + SHA_UINT64_C(0x3956c25bf348b538), SHA_UINT64_C(0x59f111f1b605d019), + SHA_UINT64_C(0x923f82a4af194f9b), SHA_UINT64_C(0xab1c5ed5da6d8118), + SHA_UINT64_C(0xd807aa98a3030242), SHA_UINT64_C(0x12835b0145706fbe), + SHA_UINT64_C(0x243185be4ee4b28c), SHA_UINT64_C(0x550c7dc3d5ffb4e2), + SHA_UINT64_C(0x72be5d74f27b896f), SHA_UINT64_C(0x80deb1fe3b1696b1), + SHA_UINT64_C(0x9bdc06a725c71235), SHA_UINT64_C(0xc19bf174cf692694), + SHA_UINT64_C(0xe49b69c19ef14ad2), SHA_UINT64_C(0xefbe4786384f25e3), + SHA_UINT64_C(0x0fc19dc68b8cd5b5), SHA_UINT64_C(0x240ca1cc77ac9c65), + SHA_UINT64_C(0x2de92c6f592b0275), SHA_UINT64_C(0x4a7484aa6ea6e483), + SHA_UINT64_C(0x5cb0a9dcbd41fbd4), SHA_UINT64_C(0x76f988da831153b5), + SHA_UINT64_C(0x983e5152ee66dfab), SHA_UINT64_C(0xa831c66d2db43210), + SHA_UINT64_C(0xb00327c898fb213f), SHA_UINT64_C(0xbf597fc7beef0ee4), + SHA_UINT64_C(0xc6e00bf33da88fc2), SHA_UINT64_C(0xd5a79147930aa725), + SHA_UINT64_C(0x06ca6351e003826f), SHA_UINT64_C(0x142929670a0e6e70), + SHA_UINT64_C(0x27b70a8546d22ffc), SHA_UINT64_C(0x2e1b21385c26c926), + SHA_UINT64_C(0x4d2c6dfc5ac42aed), SHA_UINT64_C(0x53380d139d95b3df), + SHA_UINT64_C(0x650a73548baf63de), SHA_UINT64_C(0x766a0abb3c77b2a8), + SHA_UINT64_C(0x81c2c92e47edaee6), SHA_UINT64_C(0x92722c851482353b), + SHA_UINT64_C(0xa2bfe8a14cf10364), SHA_UINT64_C(0xa81a664bbc423001), + SHA_UINT64_C(0xc24b8b70d0f89791), SHA_UINT64_C(0xc76c51a30654be30), + SHA_UINT64_C(0xd192e819d6ef5218), SHA_UINT64_C(0xd69906245565a910), + SHA_UINT64_C(0xf40e35855771202a), SHA_UINT64_C(0x106aa07032bbd1b8), + SHA_UINT64_C(0x19a4c116b8d2d0c8), SHA_UINT64_C(0x1e376c085141ab53), + SHA_UINT64_C(0x2748774cdf8eeb99), SHA_UINT64_C(0x34b0bcb5e19b48a8), + SHA_UINT64_C(0x391c0cb3c5c95a63), SHA_UINT64_C(0x4ed8aa4ae3418acb), + SHA_UINT64_C(0x5b9cca4f7763e373), SHA_UINT64_C(0x682e6ff3d6b2b8a3), + SHA_UINT64_C(0x748f82ee5defb2fc), SHA_UINT64_C(0x78a5636f43172f60), + SHA_UINT64_C(0x84c87814a1f0ab72), SHA_UINT64_C(0x8cc702081a6439ec), + SHA_UINT64_C(0x90befffa23631e28), SHA_UINT64_C(0xa4506cebde82bde9), + SHA_UINT64_C(0xbef9a3f7b2c67915), SHA_UINT64_C(0xc67178f2e372532b), + SHA_UINT64_C(0xca273eceea26619c), SHA_UINT64_C(0xd186b8c721c0c207), + SHA_UINT64_C(0xeada7dd6cde0eb1e), SHA_UINT64_C(0xf57d4f7fee6ed178), + SHA_UINT64_C(0x06f067aa72176fba), SHA_UINT64_C(0x0a637dc5a2c898a6), + SHA_UINT64_C(0x113f9804bef90dae), SHA_UINT64_C(0x1b710b35131c471b), + SHA_UINT64_C(0x28db77f523047d84), SHA_UINT64_C(0x32caab7b40c72493), + SHA_UINT64_C(0x3c9ebe0a15c9bebc), SHA_UINT64_C(0x431d67c49c100d4c), + SHA_UINT64_C(0x4cc5d4becb3e42b6), SHA_UINT64_C(0x597f299cfc657e2a), + SHA_UINT64_C(0x5fcb6fab3ad6faec), SHA_UINT64_C(0x6c44198c4a475817) }; /* Initial hash value H for SHA-384 */ static const sha_word64 sha384_initial_hash_value[8] = { - 0xcbbb9d5dc1059ed8ULL, - 0x629a292a367cd507ULL, - 0x9159015a3070dd17ULL, - 0x152fecd8f70e5939ULL, - 0x67332667ffc00b31ULL, - 0x8eb44a8768581511ULL, - 0xdb0c2e0d64f98fa7ULL, - 0x47b5481dbefa4fa4ULL + SHA_UINT64_C(0xcbbb9d5dc1059ed8), + SHA_UINT64_C(0x629a292a367cd507), + SHA_UINT64_C(0x9159015a3070dd17), + SHA_UINT64_C(0x152fecd8f70e5939), + SHA_UINT64_C(0x67332667ffc00b31), + SHA_UINT64_C(0x8eb44a8768581511), + SHA_UINT64_C(0xdb0c2e0d64f98fa7), + SHA_UINT64_C(0x47b5481dbefa4fa4) }; /* Initial hash value H for SHA-512 */ static const sha_word64 sha512_initial_hash_value[8] = { - 0x6a09e667f3bcc908ULL, - 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, - 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, - 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, - 0x5be0cd19137e2179ULL + SHA_UINT64_C(0x6a09e667f3bcc908), + SHA_UINT64_C(0xbb67ae8584caa73b), + SHA_UINT64_C(0x3c6ef372fe94f82b), + SHA_UINT64_C(0xa54ff53a5f1d36f1), + SHA_UINT64_C(0x510e527fade682d1), + SHA_UINT64_C(0x9b05688c2b3e6c1f), + SHA_UINT64_C(0x1f83d9abfb41bd6b), + SHA_UINT64_C(0x5be0cd19137e2179) }; /* -- cgit v0.12 From 9da8340a6d68ec1dce9248d0d83f59ba6f41003e Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 10:54:56 -0500 Subject: sha2: Suppress Borland warnings in third-party code The sha2 implementation performs cleanup on local variables. Suppress the warning instead of fixing it to minimize modification. --- Source/cm_sha2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index c64a597..b89f8fe 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -103,6 +103,9 @@ typedef cm_sha2_uint32_t sha_word32; /* Exactly 4 bytes */ typedef cm_sha2_uint64_t sha_word64; /* Exactly 8 bytes */ #define SHA_UINT32_C(x) cmIML_INT_UINT32_C(x) #define SHA_UINT64_C(x) cmIML_INT_UINT64_C(x) +#if defined(__BORLANDC__) +# pragma warn -8004 /* variable assigned value that is never used */ +#endif /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN -- cgit v0.12 From b0853b5fae2681f31f023a37d04cea1209b34dbd Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 11:03:30 -0500 Subject: Disable file() and string() hash commands during bootstrap We do not compile support for the cryptographic hashes during bootstrap. Disable the APIs that use them. --- Source/cmFileCommand.cxx | 7 +++++++ Source/cmStringCommand.cxx | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index bab3116..6df5ab3 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -352,6 +352,7 @@ bool cmFileCommand::HandleReadCommand(std::vector const& args) //---------------------------------------------------------------------------- bool cmFileCommand::HandleHashCommand(std::vector const& args) { +#if defined(CMAKE_BUILD_WITH_CMAKE) if(args.size() != 3) { cmOStringStream e; @@ -375,6 +376,12 @@ bool cmFileCommand::HandleHashCommand(std::vector const& args) this->SetError(e.str().c_str()); } return false; +#else + cmOStringStream e; + e << args[0] << " not available during bootstrap"; + this->SetError(e.str().c_str()); + return false; +#endif } //---------------------------------------------------------------------------- diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index f2f2681..ec10d57 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -96,6 +96,7 @@ bool cmStringCommand //---------------------------------------------------------------------------- bool cmStringCommand::HandleHashCommand(std::vector const& args) { +#if defined(CMAKE_BUILD_WITH_CMAKE) if(args.size() != 3) { cmOStringStream e; @@ -112,6 +113,12 @@ bool cmStringCommand::HandleHashCommand(std::vector const& args) return true; } return false; +#else + cmOStringStream e; + e << args[0] << " not available during bootstrap"; + this->SetError(e.str().c_str()); + return false; +#endif } //---------------------------------------------------------------------------- -- cgit v0.12 From 9fb1a9cf1dc45672b38350f2c4ae560359521566 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 11:05:13 -0500 Subject: sha2: Wrap long lines in third-party declarations --- Source/cm_sha2.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h index ebe5e5a..71395f0 100644 --- a/Source/cm_sha2.h +++ b/Source/cm_sha2.h @@ -102,31 +102,36 @@ void SHA1_Init(SHA_CTX*); void SHA1_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); void SHA1_Final(cm_sha2_uint8_t[SHA1_DIGEST_LENGTH], SHA_CTX*); char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]); -char* SHA1_Data(const cm_sha2_uint8_t*, size_t, char[SHA1_DIGEST_STRING_LENGTH]); +char* SHA1_Data(const cm_sha2_uint8_t*, size_t, + char[SHA1_DIGEST_STRING_LENGTH]); void SHA224_Init(SHA_CTX*); void SHA224_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); void SHA224_Final(cm_sha2_uint8_t[SHA224_DIGEST_LENGTH], SHA_CTX*); char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]); -char* SHA224_Data(const cm_sha2_uint8_t*, size_t, char[SHA224_DIGEST_STRING_LENGTH]); +char* SHA224_Data(const cm_sha2_uint8_t*, size_t, + char[SHA224_DIGEST_STRING_LENGTH]); void SHA256_Init(SHA_CTX*); void SHA256_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); void SHA256_Final(cm_sha2_uint8_t[SHA256_DIGEST_LENGTH], SHA_CTX*); char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const cm_sha2_uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const cm_sha2_uint8_t*, size_t, + char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA_CTX*); void SHA384_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); void SHA384_Final(cm_sha2_uint8_t[SHA384_DIGEST_LENGTH], SHA_CTX*); char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const cm_sha2_uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const cm_sha2_uint8_t*, size_t, + char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA_CTX*); void SHA512_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t); void SHA512_Final(cm_sha2_uint8_t[SHA512_DIGEST_LENGTH], SHA_CTX*); char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const cm_sha2_uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const cm_sha2_uint8_t*, size_t, + char[SHA512_DIGEST_STRING_LENGTH]); #ifdef __cplusplus } -- cgit v0.12 From 8302608a744c3a4df3495f8db88784fb3f04660f Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 11:26:10 -0500 Subject: Fix CMake.File hash test for CRLF checkouts Use a dedicated test input file for the file() hash API tests. Set attribute crlf=input so it is always checked out correctly. --- Tests/CMakeTests/.gitattributes | 1 + Tests/CMakeTests/File-HASH-Input.txt | 1 + Tests/CMakeTests/File-MD5-BadArg2.cmake | 2 +- Tests/CMakeTests/File-MD5-BadArg4.cmake | 2 +- Tests/CMakeTests/File-MD5-Works.cmake | 2 +- Tests/CMakeTests/File-SHA1-Works.cmake | 2 +- Tests/CMakeTests/File-SHA224-Works.cmake | 2 +- Tests/CMakeTests/File-SHA256-Works.cmake | 2 +- Tests/CMakeTests/File-SHA384-Works.cmake | 2 +- Tests/CMakeTests/File-SHA512-Works.cmake | 2 +- Tests/CMakeTests/FileTest.cmake.in | 12 ++++++------ 11 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 Tests/CMakeTests/.gitattributes create mode 100644 Tests/CMakeTests/File-HASH-Input.txt diff --git a/Tests/CMakeTests/.gitattributes b/Tests/CMakeTests/.gitattributes new file mode 100644 index 0000000..c34e350 --- /dev/null +++ b/Tests/CMakeTests/.gitattributes @@ -0,0 +1 @@ +File-HASH-Input.txt crlf=input diff --git a/Tests/CMakeTests/File-HASH-Input.txt b/Tests/CMakeTests/File-HASH-Input.txt new file mode 100644 index 0000000..a1d315b --- /dev/null +++ b/Tests/CMakeTests/File-HASH-Input.txt @@ -0,0 +1 @@ +sample input string diff --git a/Tests/CMakeTests/File-MD5-BadArg2.cmake b/Tests/CMakeTests/File-MD5-BadArg2.cmake index 68a172f..2acc075 100644 --- a/Tests/CMakeTests/File-MD5-BadArg2.cmake +++ b/Tests/CMakeTests/File-MD5-BadArg2.cmake @@ -1 +1 @@ -file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake) +file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt) diff --git a/Tests/CMakeTests/File-MD5-BadArg4.cmake b/Tests/CMakeTests/File-MD5-BadArg4.cmake index a11efcb..79b2755 100644 --- a/Tests/CMakeTests/File-MD5-BadArg4.cmake +++ b/Tests/CMakeTests/File-MD5-BadArg4.cmake @@ -1 +1 @@ -file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake md5 extra_arg) +file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt md5 extra_arg) diff --git a/Tests/CMakeTests/File-MD5-Works.cmake b/Tests/CMakeTests/File-MD5-Works.cmake index 2989e98..0fabe54 100644 --- a/Tests/CMakeTests/File-MD5-Works.cmake +++ b/Tests/CMakeTests/File-MD5-Works.cmake @@ -1,2 +1,2 @@ -file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake md5) +file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt md5) message("${md5}") diff --git a/Tests/CMakeTests/File-SHA1-Works.cmake b/Tests/CMakeTests/File-SHA1-Works.cmake index 03ea3ac..f2ab5d7 100644 --- a/Tests/CMakeTests/File-SHA1-Works.cmake +++ b/Tests/CMakeTests/File-SHA1-Works.cmake @@ -1,2 +1,2 @@ -file(SHA1 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha1) +file(SHA1 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha1) message("${sha1}") diff --git a/Tests/CMakeTests/File-SHA224-Works.cmake b/Tests/CMakeTests/File-SHA224-Works.cmake index 0295346..3e86b17 100644 --- a/Tests/CMakeTests/File-SHA224-Works.cmake +++ b/Tests/CMakeTests/File-SHA224-Works.cmake @@ -1,2 +1,2 @@ -file(SHA224 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha224) +file(SHA224 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha224) message("${sha224}") diff --git a/Tests/CMakeTests/File-SHA256-Works.cmake b/Tests/CMakeTests/File-SHA256-Works.cmake index 32bc9fe..b72d89e 100644 --- a/Tests/CMakeTests/File-SHA256-Works.cmake +++ b/Tests/CMakeTests/File-SHA256-Works.cmake @@ -1,2 +1,2 @@ -file(SHA256 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha256) +file(SHA256 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha256) message("${sha256}") diff --git a/Tests/CMakeTests/File-SHA384-Works.cmake b/Tests/CMakeTests/File-SHA384-Works.cmake index 5c56de2..0eeca33 100644 --- a/Tests/CMakeTests/File-SHA384-Works.cmake +++ b/Tests/CMakeTests/File-SHA384-Works.cmake @@ -1,2 +1,2 @@ -file(SHA384 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha384) +file(SHA384 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha384) message("${sha384}") diff --git a/Tests/CMakeTests/File-SHA512-Works.cmake b/Tests/CMakeTests/File-SHA512-Works.cmake index cf10706..d74ee44 100644 --- a/Tests/CMakeTests/File-SHA512-Works.cmake +++ b/Tests/CMakeTests/File-SHA512-Works.cmake @@ -1,2 +1,2 @@ -file(SHA512 ${CMAKE_CURRENT_LIST_DIR}/File-Copy-NoDest.cmake sha512) +file(SHA512 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha512) message("${sha512}") diff --git a/Tests/CMakeTests/FileTest.cmake.in b/Tests/CMakeTests/FileTest.cmake.in index 824aba7..3c3d85d 100644 --- a/Tests/CMakeTests/FileTest.cmake.in +++ b/Tests/CMakeTests/FileTest.cmake.in @@ -21,17 +21,17 @@ set(MD5-BadArg2-STDERR "file MD5 requires a file name and output variable") set(MD5-BadArg4-RESULT 1) set(MD5-BadArg4-STDERR "file MD5 requires a file name and output variable") set(MD5-Works-RESULT 0) -set(MD5-Works-STDERR "a28a44fb5b58a6acf0cbec46557bc775") +set(MD5-Works-STDERR "10d20ddb981a6202b84aa1ce1cb7fce3") set(SHA1-Works-RESULT 0) -set(SHA1-Works-STDERR "e0ce452a7e34e9c705b46e4e7c9cd959082c0777") +set(SHA1-Works-STDERR "83f093e04289b21a9415f408ad50be8b57ad2f34") set(SHA224-Works-RESULT 0) -set(SHA224-Works-STDERR "d1f1c9db3df73586a5a200014505ef03b70da5e0539eb35c11b4ef6f") +set(SHA224-Works-STDERR "e995a7789922c4ef9279d94e763c8375934180a51baa7147bc48edf7") set(SHA256-Works-RESULT 0) -set(SHA256-Works-STDERR "bb38de1c34713f750a4f84404ef5fb1efb93cf815cb09182db457ba91de19195") +set(SHA256-Works-STDERR "d1c5915d8b71150726a1eef75a29ec6bea8fd1bef6b7299ef8048760b0402025") set(SHA384-Works-RESULT 0) -set(SHA384-Works-STDERR "2f01d58436bd04a40ec2c938a15f2bb661bf1bf1560a5f2d40a3ebbb716a58e400ab2992c23ba19fa96dc519e0042c26") +set(SHA384-Works-STDERR "1de9560b4e030e02051ea408200ffc55d70c97ac64ebf822461a5c786f495c36df43259b14483bc8d364f0106f4971ee") set(SHA512-Works-RESULT 0) -set(SHA512-Works-STDERR "349d02e347ddb133afb4557c9e541163f54b6eaa9eb345672bfd7bbce90c9872bf1fad9c6662248eb7b092aef719e4b8c3b8bb1cf47f287abbde12360c073686") +set(SHA512-Works-STDERR "3982a1b4e651768bec70ab1fb97045cb7a659f4ba7203d501c52ab2e803071f9d5fd272022df15f27727fc67f8cd022e710e29010b2a9c0b467c111e2f6abf51") include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") check_cmake_test(File -- cgit v0.12 From 6495b595c4953ce29e66ff4919d69a74300c3532 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 16 Nov 2011 11:32:01 -0500 Subject: cmCryptoHash: Add virtual destructor Instances of this class are always subclasses. Use a virtual destructor to ensure the subclasses cleanup correctly. --- Source/cmCryptoHash.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h index 0a33365..1bea9ab 100644 --- a/Source/cmCryptoHash.h +++ b/Source/cmCryptoHash.h @@ -19,6 +19,7 @@ class cmCryptoHash { public: + virtual ~cmCryptoHash() {} static cmsys::auto_ptr New(const char* algo); std::string HashString(const char* input); std::string HashFile(const char* file); -- cgit v0.12 From 24b1feb5ca9dbc3461d373e4de30a33157f81375 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 17 Nov 2011 11:07:43 -0500 Subject: sha2: Cast safe conversions to smaller integer types Add a cast to lines converting "uint64_t" to "unsigned int" that are known safe due to use of modulus with a small integer. This avoids compiler warnings such as conversion from 'cm_sha2_uint64_t' to 'unsigned int', possible loss of data from MSVC. --- Source/cm_sha2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index b89f8fe..7991d27 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -652,7 +652,7 @@ void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) { /* Sanity check: */ assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); - usedspace = (context->s1.bitcount >> 3) % 64; + usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = 64 - usedspace; @@ -705,7 +705,7 @@ void SHA1_Final(sha_byte digest[], SHA_CTX* context) { return; } - usedspace = (context->s1.bitcount >> 3) % 64; + usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64); if (usedspace == 0) { /* Set-up for the last transform: */ MEMSET_BZERO(context->s1.buffer, 56); @@ -992,7 +992,7 @@ void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) { /* Sanity check: */ assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); - usedspace = (context->s256.bitcount >> 3) % 64; + usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = 64 - usedspace; @@ -1032,7 +1032,7 @@ void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) { void SHA256_Internal_Last(SHA_CTX* context) { unsigned int usedspace; - usedspace = (context->s256.bitcount >> 3) % 64; + usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64); #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->s256.bitcount,context->s256.bitcount); @@ -1399,7 +1399,7 @@ void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) { /* Sanity check: */ assert(context != (SHA_CTX*)0 && data != (sha_byte*)0); - usedspace = (context->s512.bitcount[0] >> 3) % 128; + usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = 128 - usedspace; @@ -1439,7 +1439,7 @@ void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) { void SHA512_Internal_Last(SHA_CTX* context) { unsigned int usedspace; - usedspace = (context->s512.bitcount[0] >> 3) % 128; + usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128); #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]); -- cgit v0.12 From 0a6705cbda8171667c4b37872136cd102ccc328c Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 17 Nov 2011 11:12:00 -0500 Subject: sha2: Suppress -Wcast-align warning from Clang The code does contain a cast that increases alignment but only for pointers into structures known to be sufficiently aligned. --- Source/cm_sha2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index 7991d27..b1798a8 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -106,6 +106,9 @@ typedef cm_sha2_uint64_t sha_word64; /* Exactly 8 bytes */ #if defined(__BORLANDC__) # pragma warn -8004 /* variable assigned value that is never used */ #endif +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wcast-align" +#endif /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN -- cgit v0.12 From 0599c5f546c8b3e04c0dd9fcdc19a6b3825849a7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 17 Nov 2011 11:18:08 -0500 Subject: sha2: Zero entire SHA_CTX structure during cleanup Convert lines of the form MEMSET_BZERO(context, sizeof(context)); to the correct form MEMSET_BZERO(context, sizeof(*context)); as suggested by Clang. --- Source/cm_sha2.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index b1798a8..12c39ed 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -704,7 +704,7 @@ void SHA1_Final(sha_byte digest[], SHA_CTX* context) { * No digest buffer, so we can do nothing * except clean up and go home */ - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); return; } @@ -760,7 +760,7 @@ void SHA1_Final(sha_byte digest[], SHA_CTX* context) { #endif /* Clean up: */ - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } char *SHA1_End(SHA_CTX* context, char buffer[]) { @@ -780,7 +780,7 @@ char *SHA1_End(SHA_CTX* context, char buffer[]) { } *buffer = (char)0; } else { - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } MEMSET_BZERO(digest, SHA1_DIGEST_LENGTH); return buffer; @@ -1099,7 +1099,7 @@ void SHA256_Final(sha_byte digest[], SHA_CTX* context) { } /* Clean up state data: */ - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } char *SHA256_End(SHA_CTX* context, char buffer[]) { @@ -1119,7 +1119,7 @@ char *SHA256_End(SHA_CTX* context, char buffer[]) { } *buffer = (char)0; } else { - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); return buffer; @@ -1173,7 +1173,7 @@ void SHA224_Final(sha_byte digest[], SHA_CTX* context) { } /* Clean up state data: */ - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } char *SHA224_End(SHA_CTX* context, char buffer[]) { @@ -1193,7 +1193,7 @@ char *SHA224_End(SHA_CTX* context, char buffer[]) { } *buffer = (char)0; } else { - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } MEMSET_BZERO(digest, SHA224_DIGEST_LENGTH); return buffer; @@ -1508,7 +1508,7 @@ void SHA512_Final(sha_byte digest[], SHA_CTX* context) { } /* Zero out state data */ - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } char *SHA512_End(SHA_CTX* context, char buffer[]) { @@ -1528,7 +1528,7 @@ char *SHA512_End(SHA_CTX* context, char buffer[]) { } *buffer = (char)0; } else { - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); return buffer; @@ -1578,7 +1578,7 @@ void SHA384_Final(sha_byte digest[], SHA_CTX* context) { } /* Zero out state data */ - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } char *SHA384_End(SHA_CTX* context, char buffer[]) { @@ -1598,7 +1598,7 @@ char *SHA384_End(SHA_CTX* context, char buffer[]) { } *buffer = (char)0; } else { - MEMSET_BZERO(context, sizeof(context)); + MEMSET_BZERO(context, sizeof(*context)); } MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); return buffer; -- cgit v0.12