diff --git a/include/cryb/md2.h b/include/cryb/md2.h index 69d83cf..c31065a 100644 --- a/include/cryb/md2.h +++ b/include/cryb/md2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2007 Christophe Devine + * Copyright (c) 2014-2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,49 +50,17 @@ CRYB_BEGIN extern digest_algorithm md2_digest; -/** - * \brief MD2 context structure - */ -typedef struct -{ - uint8_t cksum[16]; /*!< checksum of the data block */ - uint8_t state[48]; /*!< intermediate digest state */ - uint8_t buffer[16]; /*!< data block being processed */ - int left; /*!< amount of data in buffer */ +typedef struct { + uint8_t state[48]; + uint8_t cksum[16]; + uint8_t block[16]; + unsigned int blocklen; } md2_ctx; -/** - * \brief MD2 context setup - * - * \param ctx context to be initialized - */ -void md2_init( md2_ctx *ctx ); - -/** - * \brief MD2 process buffer - * - * \param ctx MD2 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md2_update( md2_ctx *ctx, const void *input, int ilen ); - -/** - * \brief MD2 final digest - * - * \param ctx MD2 context - * \param output MD2 checksum result - */ -void md2_final( md2_ctx *ctx, uint8_t *output ); - -/** - * \brief Output = MD2( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD2 checksum result - */ -void md2_complete( const void *input, int ilen, uint8_t *output ); +void md2_init(md2_ctx *); +void md2_update(md2_ctx *, const void *, size_t); +void md2_final(md2_ctx *, uint8_t *); +void md2_complete(const void *, size_t, uint8_t *); CRYB_END diff --git a/include/cryb/md4.h b/include/cryb/md4.h index 3da1222..56b27f3 100644 --- a/include/cryb/md4.h +++ b/include/cryb/md4.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2007 Christophe Devine + * Copyright (c) 2014-2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,57 +50,17 @@ CRYB_BEGIN extern digest_algorithm md4_digest; -/** - * \brief MD4 context structure - */ -typedef struct -{ - uint64_t total; /*!< number of bytes processed */ - uint32_t state[4]; /*!< intermediate digest state */ - uint8_t buffer[64]; /*!< data block being processed */ -} -md4_ctx; +typedef struct { + uint8_t block[64]; + size_t blocklen; + uint32_t state[4]; + uint64_t bitlen; +} md4_ctx; -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD4 context setup - * - * \param ctx context to be initialized - */ -void md4_init( md4_ctx *ctx ); - -/** - * \brief MD4 process buffer - * - * \param ctx MD4 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md4_update( md4_ctx *ctx, const void *input, int ilen ); - -/** - * \brief MD4 final digest - * - * \param ctx MD4 context - * \param output MD4 checksum result - */ -void md4_final( md4_ctx *ctx, uint8_t *output ); - -/** - * \brief Output = MD4( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD4 checksum result - */ -void md4_complete( const void *input, int ilen, uint8_t *output ); - -#ifdef __cplusplus -} -#endif +void md4_init(md4_ctx *); +void md4_update(md4_ctx *, const void *, size_t); +void md4_final(md4_ctx *, uint8_t *); +void md4_complete(const void *, size_t, uint8_t *); CRYB_END diff --git a/include/cryb/md5.h b/include/cryb/md5.h index 3d28629..06a4dcf 100644 --- a/include/cryb/md5.h +++ b/include/cryb/md5.h @@ -54,8 +54,8 @@ extern digest_algorithm md5_digest; typedef struct { uint8_t block[64]; size_t blocklen; + uint32_t state[4]; uint64_t bitlen; - uint32_t h[4]; } md5_ctx; void md5_init(md5_ctx *); diff --git a/include/cryb/sha1.h b/include/cryb/sha1.h index d5ef28c..eaf78ef 100644 --- a/include/cryb/sha1.h +++ b/include/cryb/sha1.h @@ -52,10 +52,10 @@ CRYB_BEGIN extern digest_algorithm sha1_digest; typedef struct { - uint8_t block[64]; - uint32_t blocklen; - uint32_t h[5]; - uint64_t bitlen; + uint8_t block[64]; + unsigned int blocklen; + uint32_t h[5]; + uint64_t bitlen; } sha1_ctx; void sha1_init(sha1_ctx *); diff --git a/include/cryb/sha224.h b/include/cryb/sha224.h index 59510c7..edd9bcc 100644 --- a/include/cryb/sha224.h +++ b/include/cryb/sha224.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005-2013 Colin Percival + * Copyright (c) 2014-2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,6 +11,9 @@ * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -38,10 +42,6 @@ CRYB_BEGIN #define SHA224_BLOCK_LEN 64 #define SHA224_DIGEST_LEN 28 -/* - * Use #defines in order to avoid namespace collisions with anyone else's - * SHA224 code (e.g., the code in OpenSSL). - */ #define sha224_digest cryb_sha224_digest #define sha224_ctx cryb_sha224_ctx #define sha224_init cryb_sha224_init @@ -51,46 +51,17 @@ CRYB_BEGIN extern digest_algorithm sha224_digest; -/* Context structure for SHA224 operations. */ typedef struct { - uint32_t state[8]; - uint64_t count; - uint8_t buf[64]; + uint32_t state[8]; + uint64_t count; + uint8_t buf[64]; } sha224_ctx; -/** - * sha224_init(ctx): - * Initialize the SHA224 context ${ctx}. - */ void sha224_init(sha224_ctx *); - -/** - * sha224_update(ctx, in, len): - * Input ${len} bytes from ${in} into the SHA224 context ${ctx}. - */ void sha224_update(sha224_ctx *, const void *, size_t); - -/** - * sha224_final(ctx, digest): - * Output the SHA224 hash of the data input to the context ${ctx} into the - * buffer ${digest}. - */ void sha224_final(sha224_ctx *, uint8_t *); - -/** - * sha224_complete(in, len, digest): - * Compute the SHA224 hash of ${len} bytes from $in} and write it to ${digest}. - */ void sha224_complete(const void *, size_t, uint8_t *); -/** - * PBKDF2_SHA224(passwd, passwdlen, salt, saltlen, c, buf, dkLen): - * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA224 as the PRF, and - * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). - */ -void pbkdf2_sha224(const uint8_t *, size_t, const uint8_t *, size_t, - uint64_t, uint8_t *, size_t); - CRYB_END #endif diff --git a/include/cryb/sha256.h b/include/cryb/sha256.h index 22f15c8..306c795 100644 --- a/include/cryb/sha256.h +++ b/include/cryb/sha256.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005-2013 Colin Percival + * Copyright (c) 2014-2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,6 +11,9 @@ * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -38,10 +42,6 @@ CRYB_BEGIN #define SHA256_BLOCK_LEN 64 #define SHA256_DIGEST_LEN 32 -/* - * Use #defines in order to avoid namespace collisions with anyone else's - * SHA256 code (e.g., the code in OpenSSL). - */ #define sha256_digest cryb_sha256_digest #define sha256_ctx cryb_sha256_ctx #define sha256_init cryb_sha256_init @@ -51,46 +51,17 @@ CRYB_BEGIN extern digest_algorithm sha256_digest; -/* Context structure for SHA256 operations. */ typedef struct { - uint32_t state[8]; - uint64_t count; - uint8_t buf[64]; + uint32_t state[8]; + uint64_t count; + uint8_t buf[64]; } sha256_ctx; -/** - * sha256_init(ctx): - * Initialize the SHA256 context ${ctx}. - */ void sha256_init(sha256_ctx *); - -/** - * sha256_update(ctx, in, len): - * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. - */ void sha256_update(sha256_ctx *, const void *, size_t); - -/** - * sha256_final(ctx, digest): - * Output the SHA256 hash of the data input to the context ${ctx} into the - * buffer ${digest}. - */ void sha256_final(sha256_ctx *, uint8_t *); - -/** - * sha256_complete(in, len, digest): - * Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}. - */ void sha256_complete(const void *, size_t, uint8_t *); -/** - * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): - * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and - * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). - */ -void pbkdf2_sha256(const uint8_t *, size_t, const uint8_t *, size_t, - uint64_t, uint8_t *, size_t); - CRYB_END #endif diff --git a/include/cryb/sha384.h b/include/cryb/sha384.h index af809a5..12dd207 100644 --- a/include/cryb/sha384.h +++ b/include/cryb/sha384.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2006-2007 Christophe Devine + * Copyright (c) 2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,49 +51,17 @@ CRYB_BEGIN extern digest_algorithm sha384_digest; -/** - * \brief SHA-384 context structure - */ -typedef struct -{ - uint64_t total[2]; /*!< number of bytes processed */ - uint64_t state[8]; /*!< intermediate digest state */ - uint8_t buffer[128]; /*!< data block being processed */ -} -sha384_ctx; +typedef struct { + uint8_t block[128]; + unsigned int blocklen; + uint64_t h[8]; + uint64_t bitlen[2]; +} sha384_ctx; -/** - * \brief SHA-384 context setup - * - * \param ctx context to be initialized - */ -void sha384_init( sha384_ctx *ctx ); - -/** - * \brief SHA-384 process buffer - * - * \param ctx SHA-384 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha384_update( sha384_ctx *ctx, const void *input, int ilen ); - -/** - * \brief SHA-384 final digest - * - * \param ctx SHA-384 context - * \param output SHA-384/384 checksum result - */ -void sha384_final( sha384_ctx *ctx, uint8_t *output ); - -/** - * \brief Output = SHA-384( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-384/384 checksum result - */ -void sha384_complete( const void *input, int ilen, uint8_t *output ); +void sha384_init(sha384_ctx *); +void sha384_update(sha384_ctx *, const void *, size_t); +void sha384_final(sha384_ctx *, uint8_t *); +void sha384_complete(const void *, size_t, uint8_t *); CRYB_END diff --git a/include/cryb/sha512.h b/include/cryb/sha512.h index a2b3c57..504bd31 100644 --- a/include/cryb/sha512.h +++ b/include/cryb/sha512.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2006-2007 Christophe Devine + * Copyright (c) 2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,49 +51,17 @@ CRYB_BEGIN extern digest_algorithm sha512_digest; -/** - * \brief SHA-512 context structure - */ -typedef struct -{ - uint64_t total[2]; /*!< number of bytes processed */ - uint64_t state[8]; /*!< intermediate digest state */ - uint8_t buffer[128]; /*!< data block being processed */ -} -sha512_ctx; +typedef struct { + uint8_t block[128]; + unsigned int blocklen; + uint64_t h[8]; + uint64_t bitlen[2]; +} sha512_ctx; -/** - * \brief SHA-512 context setup - * - * \param ctx context to be initialized - */ -void sha512_init( sha512_ctx *ctx ); - -/** - * \brief SHA-512 process buffer - * - * \param ctx SHA-512 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha512_update( sha512_ctx *ctx, const void *input, int ilen ); - -/** - * \brief SHA-512 final digest - * - * \param ctx SHA-512 context - * \param output SHA-384/512 checksum result - */ -void sha512_final( sha512_ctx *ctx, uint8_t *output ); - -/** - * \brief Output = SHA-512( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-384/512 checksum result - */ -void sha512_complete( const void *input, int ilen, uint8_t *output ); +void sha512_init(sha512_ctx *); +void sha512_update(sha512_ctx *, const void *, size_t); +void sha512_final(sha512_ctx *, uint8_t *); +void sha512_complete(const void *, size_t, uint8_t *); CRYB_END diff --git a/lib/digest/cryb_md2.c b/lib/digest/cryb_md2.c index 07b6fe5..668cea2 100644 --- a/lib/digest/cryb_md2.c +++ b/lib/digest/cryb_md2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2007 Christophe Devine + * Copyright (c) 2014-2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,153 +26,147 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * The MD2 algorithm was designed by Ron Rivest in 1989. - * - * http://www.ietf.org/rfc/rfc1115.txt - * http://www.ietf.org/rfc/rfc1319.txt - */ #include "cryb/impl.h" #include #include +#include + #include -static const uint8_t PI_SUBST[256] = -{ - 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, - 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, - 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, - 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, - 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, - 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, - 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, - 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, - 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, - 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, - 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, - 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, - 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, - 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, - 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, - 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, - 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, - 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, - 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, - 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, - 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, - 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, - 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, - 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, - 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, - 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 +/* + * MD2 - RFC 1319 + * + * Note 1: the pseudocode for the checksum calculation in the RFC contains + * a significant error - consult the errata. + * + * Note 2: the RFC describes the algorithm as having five steps: 1) append + * padding, 2) compute checksum, 3) initialize state, 4) compute digest + * and 5) output. This implementation merges the checksum and digest + * computations, which are independent of eachother, which avoids + * processing the message twice. The padding is then appended and fed + * through the checksum and digest computation, and finally the checksum + * itself is fed through. Note that we update the checksum *after* the + * digest, otherwise the final step (mixing the checksum into the digest) + * would clobber the checksum before it was used. + */ + +static const uint8_t md2_s[256] = { + 0x29, 0x2e, 0x43, 0xc9, 0xa2, 0xd8, 0x7c, 0x01, + 0x3d, 0x36, 0x54, 0xa1, 0xec, 0xf0, 0x06, 0x13, + 0x62, 0xa7, 0x05, 0xf3, 0xc0, 0xc7, 0x73, 0x8c, + 0x98, 0x93, 0x2b, 0xd9, 0xbc, 0x4c, 0x82, 0xca, + 0x1e, 0x9b, 0x57, 0x3c, 0xfd, 0xd4, 0xe0, 0x16, + 0x67, 0x42, 0x6f, 0x18, 0x8a, 0x17, 0xe5, 0x12, + 0xbe, 0x4e, 0xc4, 0xd6, 0xda, 0x9e, 0xde, 0x49, + 0xa0, 0xfb, 0xf5, 0x8e, 0xbb, 0x2f, 0xee, 0x7a, + 0xa9, 0x68, 0x79, 0x91, 0x15, 0xb2, 0x07, 0x3f, + 0x94, 0xc2, 0x10, 0x89, 0x0b, 0x22, 0x5f, 0x21, + 0x80, 0x7f, 0x5d, 0x9a, 0x5a, 0x90, 0x32, 0x27, + 0x35, 0x3e, 0xcc, 0xe7, 0xbf, 0xf7, 0x97, 0x03, + 0xff, 0x19, 0x30, 0xb3, 0x48, 0xa5, 0xb5, 0xd1, + 0xd7, 0x5e, 0x92, 0x2a, 0xac, 0x56, 0xaa, 0xc6, + 0x4f, 0xb8, 0x38, 0xd2, 0x96, 0xa4, 0x7d, 0xb6, + 0x76, 0xfc, 0x6b, 0xe2, 0x9c, 0x74, 0x04, 0xf1, + 0x45, 0x9d, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, + 0x86, 0x5b, 0xcf, 0x65, 0xe6, 0x2d, 0xa8, 0x02, + 0x1b, 0x60, 0x25, 0xad, 0xae, 0xb0, 0xb9, 0xf6, + 0x1c, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7e, 0x0f, + 0x55, 0x47, 0xa3, 0x23, 0xdd, 0x51, 0xaf, 0x3a, + 0xc3, 0x5c, 0xf9, 0xce, 0xba, 0xc5, 0xea, 0x26, + 0x2c, 0x53, 0x0d, 0x6e, 0x85, 0x28, 0x84, 0x09, + 0xd3, 0xdf, 0xcd, 0xf4, 0x41, 0x81, 0x4d, 0x52, + 0x6a, 0xdc, 0x37, 0xc8, 0x6c, 0xc1, 0xab, 0xfa, + 0x24, 0xe1, 0x7b, 0x08, 0x0c, 0xbd, 0xb1, 0x4a, + 0x78, 0x88, 0x95, 0x8b, 0xe3, 0x63, 0xe8, 0x6d, + 0xe9, 0xcb, 0xd5, 0xfe, 0x3b, 0x00, 0x1d, 0x39, + 0xf2, 0xef, 0xb7, 0x0e, 0x66, 0x58, 0xd0, 0xe4, + 0xa6, 0x77, 0x72, 0xf8, 0xeb, 0x75, 0x4b, 0x0a, + 0x31, 0x44, 0x50, 0xb4, 0x8f, 0xed, 0x1f, 0x1a, + 0xdb, 0x99, 0x8d, 0x33, 0x9f, 0x11, 0x83, 0x14, }; -/* - * MD2 context setup - */ -void md2_init( md2_ctx *ctx ) +void +md2_init(md2_ctx *ctx) { - memset( ctx, 0, sizeof( md2_ctx ) ); + + memset(ctx, 0, sizeof *ctx); } -static void md2_process( md2_ctx *ctx ) +static void +md2_compute(md2_ctx *ctx, const uint8_t *block) { - int i, j; - uint8_t t = 0; + unsigned int j, k; + uint8_t l, t; - for( i = 0; i < 16; i++ ) - { - ctx->state[i + 16] = ctx->buffer[i]; - ctx->state[i + 32] = - (uint8_t)( ctx->buffer[i] ^ ctx->state[i]); - } - - for( i = 0; i < 18; i++ ) - { - for( j = 0; j < 48; j++ ) - { - ctx->state[j] = (uint8_t) - ( ctx->state[j] ^ PI_SUBST[t] ); - t = ctx->state[j]; + for (j = 0; j < 16; j++) { + ctx->state[j + 16] = block[j]; + ctx->state[j + 32] = block[j] ^ ctx->state[j]; } - - t = (uint8_t)( t + i ); - } - - t = ctx->cksum[15]; - - for( i = 0; i < 16; i++ ) - { - ctx->cksum[i] = (uint8_t) - ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] ); - t = ctx->cksum[i]; - } -} - -/* - * MD2 process buffer - */ -void md2_update( md2_ctx *ctx, const void *input, int ilen ) -{ - int fill; - - while( ilen > 0 ) - { - if( ctx->left + ilen > 16 ) - fill = 16 - ctx->left; - else - fill = ilen; - - memcpy( ctx->buffer + ctx->left, input, fill ); - - ctx->left += fill; - input += fill; - ilen -= fill; - - if( ctx->left == 16 ) - { - ctx->left = 0; - md2_process( ctx ); + t = 0; + for (j = 0; j < 18; ++j) { + for (k = 0; k < 48; ++k) { + ctx->state[k] = ctx->state[k] ^ md2_s[t]; + t = ctx->state[k]; + } + t = t + j; + } + l = ctx->cksum[15]; + for (j = 0; j < 16; ++j) { + ctx->cksum[j] ^= md2_s[block[j] ^ l]; + l = ctx->cksum[j]; } - } } -/* - * MD2 final digest - */ -void md2_final( md2_ctx *ctx, uint8_t *output ) +void +md2_update(md2_ctx *ctx, const void *buf, size_t len) { - int i; - uint8_t x; + size_t copylen; - x = (uint8_t)( 16 - ctx->left ); - - for( i = ctx->left; i < 16; i++ ) - ctx->buffer[i] = x; - - md2_process( ctx ); - - memcpy( ctx->buffer, ctx->cksum, sizeof ctx->cksum ); - md2_process( ctx ); - - memcpy( output, ctx->state, MD2_DIGEST_LEN ); + while (len) { + if (ctx->blocklen > 0 || len < sizeof ctx->block) { + copylen = sizeof ctx->block - ctx->blocklen; + if (copylen > len) + copylen = len; + memcpy(ctx->block + ctx->blocklen, buf, copylen); + ctx->blocklen += copylen; + if (ctx->blocklen == sizeof ctx->block) { + md2_compute(ctx, ctx->block); + ctx->blocklen = 0; + } + } else { + copylen = sizeof ctx->block; + md2_compute(ctx, buf); + } + buf += copylen; + len -= copylen; + } } -/* - * output = MD2( input buffer ) - */ -void md2_complete( const void *input, int ilen, uint8_t *output ) +void +md2_final(md2_ctx *ctx, uint8_t *digest) { - md2_ctx ctx; + unsigned int i; + uint8_t x; - md2_init( &ctx ); - md2_update( &ctx, input, ilen ); - md2_final( &ctx, output ); + x = sizeof ctx->block - ctx->blocklen; + for (i = ctx->blocklen; i < sizeof ctx->block; i++) + ctx->block[i] = x; + md2_compute(ctx, ctx->block); + md2_compute(ctx, ctx->cksum); + memcpy(digest, ctx->state, MD2_DIGEST_LEN); + memset_s(&ctx, 0, sizeof ctx, sizeof ctx); +} - memset( &ctx, 0, sizeof( md2_ctx ) ); +void md2_complete(const void *buf, size_t len, uint8_t *digest) +{ + md2_ctx ctx; + + md2_init(&ctx); + md2_update(&ctx, buf, len); + md2_final(&ctx, digest); } digest_algorithm md2_digest = { diff --git a/lib/digest/cryb_md4.c b/lib/digest/cryb_md4.c index 47e8ffd..6e0d027 100644 --- a/lib/digest/cryb_md4.c +++ b/lib/digest/cryb_md4.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2007 Christophe Devine + * Copyright (c) 2014-2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,217 +26,169 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * The MD4 algorithm was designed by Ron Rivest in 1990. - * - * http://www.ietf.org/rfc/rfc1186.txt - * http://www.ietf.org/rfc/rfc1320.txt - */ #include "cryb/impl.h" #include #include +#include #include +#include + #include /* - * MD4 context setup + * MD4 - RFC 1320 */ -void md4_init( md4_ctx *ctx ) -{ - ctx->total = 0; - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md4_process( md4_ctx *ctx, const uint8_t *data ) -{ - uint32_t X[16], A, B, C, D; - - X[ 0] = le32dec(data + 0); - X[ 1] = le32dec(data + 4); - X[ 2] = le32dec(data + 8); - X[ 3] = le32dec(data + 12); - X[ 4] = le32dec(data + 16); - X[ 5] = le32dec(data + 20); - X[ 6] = le32dec(data + 24); - X[ 7] = le32dec(data + 28); - X[ 8] = le32dec(data + 32); - X[ 9] = le32dec(data + 36); - X[10] = le32dec(data + 40); - X[11] = le32dec(data + 44); - X[12] = le32dec(data + 48); - X[13] = le32dec(data + 52); - X[14] = le32dec(data + 56); - X[15] = le32dec(data + 60); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x, y, z) ((x & y) | ((~x) & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 1], 7 ); - P( C, D, A, B, X[ 2], 11 ); - P( B, C, D, A, X[ 3], 19 ); - P( A, B, C, D, X[ 4], 3 ); - P( D, A, B, C, X[ 5], 7 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[ 7], 19 ); - P( A, B, C, D, X[ 8], 3 ); - P( D, A, B, C, X[ 9], 7 ); - P( C, D, A, B, X[10], 11 ); - P( B, C, D, A, X[11], 19 ); - P( A, B, C, D, X[12], 3 ); - P( D, A, B, C, X[13], 7 ); - P( C, D, A, B, X[14], 11 ); - P( B, C, D, A, X[15], 19 ); - -#undef P -#undef F - -#define F(x,y,z) ((x & y) | (x & z) | (y & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 4], 5 ); - P( C, D, A, B, X[ 8], 9 ); - P( B, C, D, A, X[12], 13 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 5], 5 ); - P( C, D, A, B, X[ 9], 9 ); - P( B, C, D, A, X[13], 13 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[ 6], 5 ); - P( C, D, A, B, X[10], 9 ); - P( B, C, D, A, X[14], 13 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[ 7], 5 ); - P( C, D, A, B, X[11], 9 ); - P( B, C, D, A, X[15], 13 ); - -#undef P -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 8], 9 ); - P( C, D, A, B, X[ 4], 11 ); - P( B, C, D, A, X[12], 15 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[10], 9 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[14], 15 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 9], 9 ); - P( C, D, A, B, X[ 5], 11 ); - P( B, C, D, A, X[13], 15 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[11], 9 ); - P( C, D, A, B, X[ 7], 11 ); - P( B, C, D, A, X[15], 15 ); - -#undef F -#undef P - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -/* - * MD4 process buffer - */ -void md4_update( md4_ctx *ctx, const void *input, int ilen ) -{ - int fill; - uint32_t left; - - if( ilen <= 0 ) - return; - - left = ctx->total & 0x3F; - fill = 64 - left; - - ctx->total += ilen; - - if( left && ilen >= fill ) - { - memcpy( (ctx->buffer + left), input, fill ); - md4_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - md4_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (ctx->buffer + left), input, ilen ); - } -} - -static const uint8_t md4_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +/* initial state */ +static const uint32_t md4_h[4] = { + 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, }; -/* - * MD4 final digest - */ -void md4_final( md4_ctx *ctx, uint8_t *output ) +void +md4_init(md4_ctx *ctx) { - uint32_t last, padn; - uint8_t msglen[8]; - le64enc(msglen, ctx->total << 3); - - last = ctx->total & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md4_update( ctx, md4_padding, padn ); - md4_update( ctx, msglen, 8 ); - - le32enc(output + 0, ctx->state[0]); - le32enc(output + 4, ctx->state[1]); - le32enc(output + 8, ctx->state[2]); - le32enc(output + 12, ctx->state[3]); + memset(ctx, 0, sizeof *ctx); + memcpy(ctx->state, md4_h, sizeof ctx->state); } -/* - * output = MD4( input buffer ) - */ -void md4_complete( const void *input, int ilen, uint8_t *output ) +static void +md4_compute(md4_ctx *ctx, const uint8_t *data) { - md4_ctx ctx; + uint32_t X[16]; + uint32_t A, B, C, D; - md4_init( &ctx ); - md4_update( &ctx, input, ilen ); - md4_final( &ctx, output ); + le32decv(X, data, 16); - memset( &ctx, 0, sizeof( md4_ctx ) ); + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) (x & y | ~x & z) +#define md4_round1(a, b, c, d, k, s) \ + a = rol32(a + F(b, c, d) + X[k], s) + +#define G(x, y, z) (x & y | x & z | y & z) +#define md4_round2(a, b, c, d, k, s) \ + a = rol32(a + G(b, c, d) + X[k] + 0x5a827999, s) + +#define H(x, y, z) (x ^ y ^ z) +#define md4_round3(a, b, c, d, k, s) \ + a = rol32(a + H(b,c,d) + X[k] + 0x6ed9eba1, s) + + md4_round1(A, B, C, D, 0, 3); + md4_round1(D, A, B, C, 1, 7); + md4_round1(C, D, A, B, 2, 11); + md4_round1(B, C, D, A, 3, 19); + md4_round1(A, B, C, D, 4, 3); + md4_round1(D, A, B, C, 5, 7); + md4_round1(C, D, A, B, 6, 11); + md4_round1(B, C, D, A, 7, 19); + md4_round1(A, B, C, D, 8, 3); + md4_round1(D, A, B, C, 9, 7); + md4_round1(C, D, A, B, 10, 11); + md4_round1(B, C, D, A, 11, 19); + md4_round1(A, B, C, D, 12, 3); + md4_round1(D, A, B, C, 13, 7); + md4_round1(C, D, A, B, 14, 11); + md4_round1(B, C, D, A, 15, 19); + + md4_round2(A, B, C, D, 0, 3); + md4_round2(D, A, B, C, 4, 5); + md4_round2(C, D, A, B, 8, 9); + md4_round2(B, C, D, A, 12, 13); + md4_round2(A, B, C, D, 1, 3); + md4_round2(D, A, B, C, 5, 5); + md4_round2(C, D, A, B, 9, 9); + md4_round2(B, C, D, A, 13, 13); + md4_round2(A, B, C, D, 2, 3); + md4_round2(D, A, B, C, 6, 5); + md4_round2(C, D, A, B, 10, 9); + md4_round2(B, C, D, A, 14, 13); + md4_round2(A, B, C, D, 3, 3); + md4_round2(D, A, B, C, 7, 5); + md4_round2(C, D, A, B, 11, 9); + md4_round2(B, C, D, A, 15, 13); + + md4_round3(A, B, C, D, 0, 3); + md4_round3(D, A, B, C, 8, 9); + md4_round3(C, D, A, B, 4, 11); + md4_round3(B, C, D, A, 12, 15); + md4_round3(A, B, C, D, 2, 3); + md4_round3(D, A, B, C, 10, 9); + md4_round3(C, D, A, B, 6, 11); + md4_round3(B, C, D, A, 14, 15); + md4_round3(A, B, C, D, 1, 3); + md4_round3(D, A, B, C, 9, 9); + md4_round3(C, D, A, B, 5, 11); + md4_round3(B, C, D, A, 13, 15); + md4_round3(A, B, C, D, 3, 3); + md4_round3(D, A, B, C, 11, 9); + md4_round3(C, D, A, B, 7, 11); + md4_round3(B, C, D, A, 15, 15); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +void +md4_update(md4_ctx *ctx, const void *buf, size_t len) +{ + size_t copylen; + + while (len) { + if (ctx->blocklen > 0 || len < sizeof ctx->block) { + copylen = sizeof ctx->block - ctx->blocklen; + if (copylen > len) + copylen = len; + memcpy(ctx->block + ctx->blocklen, buf, copylen); + ctx->blocklen += copylen; + if (ctx->blocklen == sizeof ctx->block) { + md4_compute(ctx, ctx->block); + ctx->blocklen = 0; + } + } else { + copylen = sizeof ctx->block; + md4_compute(ctx, buf); + } + ctx->bitlen += copylen * 8; + buf += copylen; + len -= copylen; + } +} + +void +md4_final(md4_ctx *ctx, uint8_t *digest) +{ + + ctx->block[ctx->blocklen++] = 0x80; + memset(ctx->block + ctx->blocklen, 0, + sizeof ctx->block - ctx->blocklen); + if (ctx->blocklen > 56) { + md4_compute(ctx, ctx->block); + ctx->blocklen = 0; + memset(ctx->block, 0, sizeof ctx->block); + } + le64enc(ctx->block + 56, ctx->bitlen); + md4_compute(ctx, ctx->block); + le32encv(digest, ctx->state, 4); + memset_s(ctx, 0, sizeof *ctx, sizeof *ctx); +} + +void +md4_complete(const void *buf, size_t len, uint8_t *digest) +{ + md4_ctx ctx; + + md4_init(&ctx); + md4_update(&ctx, buf, len); + md4_final(&ctx, digest); } digest_algorithm md4_digest = { diff --git a/lib/digest/cryb_md5.c b/lib/digest/cryb_md5.c index 91ec713..4df3495 100644 --- a/lib/digest/cryb_md5.c +++ b/lib/digest/cryb_md5.c @@ -35,30 +35,36 @@ #include #include +#include + #include +/* + * MD5 - RFC 1321 + */ + /* initial state */ static const uint32_t md5_h[4] = { - 0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, + 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, }; static const uint32_t md5_k[64] = { - 0xd76aa478U, 0xe8c7b756U, 0x242070dbU, 0xc1bdceeeU, - 0xf57c0fafU, 0x4787c62aU, 0xa8304613U, 0xfd469501U, - 0x698098d8U, 0x8b44f7afU, 0xffff5bb1U, 0x895cd7beU, - 0x6b901122U, 0xfd987193U, 0xa679438eU, 0x49b40821U, - 0xf61e2562U, 0xc040b340U, 0x265e5a51U, 0xe9b6c7aaU, - 0xd62f105dU, 0x02441453U, 0xd8a1e681U, 0xe7d3fbc8U, - 0x21e1cde6U, 0xc33707d6U, 0xf4d50d87U, 0x455a14edU, - 0xa9e3e905U, 0xfcefa3f8U, 0x676f02d9U, 0x8d2a4c8aU, - 0xfffa3942U, 0x8771f681U, 0x6d9d6122U, 0xfde5380cU, - 0xa4beea44U, 0x4bdecfa9U, 0xf6bb4b60U, 0xbebfbc70U, - 0x289b7ec6U, 0xeaa127faU, 0xd4ef3085U, 0x04881d05U, - 0xd9d4d039U, 0xe6db99e5U, 0x1fa27cf8U, 0xc4ac5665U, - 0xf4292244U, 0x432aff97U, 0xab9423a7U, 0xfc93a039U, - 0x655b59c3U, 0x8f0ccc92U, 0xffeff47dU, 0x85845dd1U, - 0x6fa87e4fU, 0xfe2ce6e0U, 0xa3014314U, 0x4e0811a1U, - 0xf7537e82U, 0xbd3af235U, 0x2ad7d2bbU, 0xeb86d391U, + 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, + 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, + 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, + 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL, + 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, + 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, + 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, + 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL, + 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, + 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL, + 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, + 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, + 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, + 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL, + 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, + 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL, }; void @@ -66,7 +72,7 @@ md5_init(md5_ctx *ctx) { memset(ctx, 0, sizeof *ctx); - memcpy(ctx->h, md5_h, sizeof ctx->h); + memcpy(ctx->state, md5_h, sizeof ctx->state); } #define md5_f(i, a, b, c, d, x, s) do { \ @@ -98,13 +104,11 @@ md5_compute(md5_ctx *ctx, const uint8_t *block) { uint32_t w[16], a, b, c, d; - memcpy(w, block, 64); - for (int i = 0; i < 16; ++i) - w[i] = le32toh(w[i]); - a = ctx->h[0]; - b = ctx->h[1]; - c = ctx->h[2]; - d = ctx->h[3]; + le32decv(w, block, 16); + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; md5_f( 0, a, b, c, d, w, 7); md5_f( 1, d, a, b, c, w, 12); @@ -174,10 +178,10 @@ md5_compute(md5_ctx *ctx, const uint8_t *block) md5_i(62, c, d, a, b, w, 15); md5_i(63, b, c, d, a, w, 21); - ctx->h[0] += a; - ctx->h[1] += b; - ctx->h[2] += c; - ctx->h[3] += d; + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; } void @@ -195,7 +199,6 @@ md5_update(md5_ctx *ctx, const void *buf, size_t len) if (ctx->blocklen == sizeof ctx->block) { md5_compute(ctx, ctx->block); ctx->blocklen = 0; - memset(ctx->block, 0, sizeof ctx->block); } } else { copylen = sizeof ctx->block; @@ -212,19 +215,17 @@ md5_final(md5_ctx *ctx, uint8_t *digest) { ctx->block[ctx->blocklen++] = 0x80; + memset(ctx->block + ctx->blocklen, 0, + sizeof ctx->block - ctx->blocklen); if (ctx->blocklen > 56) { md5_compute(ctx, ctx->block); ctx->blocklen = 0; memset(ctx->block, 0, sizeof ctx->block); } - le32enc(ctx->block + 56, ctx->bitlen & 0xffffffffUL); - le32enc(ctx->block + 60, ctx->bitlen >> 32); + le64enc(ctx->block + 56, ctx->bitlen); md5_compute(ctx, ctx->block); - le32enc(digest, ctx->h[0]); - le32enc(digest + 4, ctx->h[1]); - le32enc(digest + 8, ctx->h[2]); - le32enc(digest + 12, ctx->h[3]); - memset(ctx, 0, sizeof *ctx); + le32encv(digest, ctx->state, 4); + memset_s(ctx, 0, sizeof *ctx, sizeof *ctx); } void diff --git a/lib/digest/cryb_sha1.c b/lib/digest/cryb_sha1.c index fa8bfde..a095e30 100644 --- a/lib/digest/cryb_sha1.c +++ b/lib/digest/cryb_sha1.c @@ -35,6 +35,8 @@ #include #include +#include + #include static uint32_t sha1_h[5] = { @@ -70,11 +72,10 @@ static void sha1_compute(sha1_ctx *ctx, const uint8_t *block) { uint32_t w[80], a, b, c, d, e; + unsigned int i; - memcpy(w, block, 64); - for (int i = 0; i < 16; ++i) - w[i] = be32toh(w[i]); - for (int i = 16; i < 80; ++i) { + be32decv(w, block, 16); + for (i = 16; i < 80; ++i) { w[i] = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]; w[i] = rol32(w[i], 1); } @@ -190,7 +191,6 @@ sha1_update(sha1_ctx *ctx, const void *buf, size_t len) if (ctx->blocklen == sizeof ctx->block) { sha1_compute(ctx, ctx->block); ctx->blocklen = 0; - memset(ctx->block, 0, sizeof ctx->block); } } else { copylen = sizeof ctx->block; @@ -205,24 +205,19 @@ sha1_update(sha1_ctx *ctx, const void *buf, size_t len) void sha1_final(sha1_ctx *ctx, uint8_t *digest) { - uint32_t hi, lo; ctx->block[ctx->blocklen++] = 0x80; + memset(ctx->block + ctx->blocklen, 0, + sizeof ctx->block - ctx->blocklen); if (ctx->blocklen > 56) { sha1_compute(ctx, ctx->block); ctx->blocklen = 0; memset(ctx->block, 0, sizeof ctx->block); } - hi = htobe32(ctx->bitlen >> 32); - lo = htobe32(ctx->bitlen & 0xffffffffUL); - memcpy(ctx->block + 56, &hi, 4); - memcpy(ctx->block + 60, &lo, 4); - ctx->blocklen = 64; + be64enc(ctx->block + 56, ctx->bitlen); sha1_compute(ctx, ctx->block); - for (int i = 0; i < 5; ++i) - ctx->h[i] = htobe32(ctx->h[i]); - memcpy(digest, ctx->h, 20); - memset(ctx, 0, sizeof *ctx); + be32encv(digest, ctx->h, 5); + memset_s(ctx, 0, sizeof *ctx, sizeof *ctx); } void diff --git a/lib/digest/cryb_sha224.c b/lib/digest/cryb_sha224.c index 67666df..5fa58c7 100644 --- a/lib/digest/cryb_sha224.c +++ b/lib/digest/cryb_sha224.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005-2013 Colin Percival + * Copyright (c) 2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,6 +11,9 @@ * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -29,44 +33,20 @@ #include #include +#include #include +#include + #include -/* - * Encode a length len/4 vector of (uint32_t) into a length len vector of - * (uint8_t) in big-endian form. Assumes len is a multiple of 4. - */ -static void -be32enc_vect(uint8_t *dst, const uint32_t *src, size_t len) -{ - size_t i; - - for (i = 0; i < len / 4; i++) - be32enc(dst + i * 4, src[i]); -} - -/* - * Decode a big-endian length len vector of (uint8_t) into a length - * len/4 vector of (uint32_t). Assumes len is a multiple of 4. - */ -static void -be32dec_vect(uint32_t *dst, const uint8_t *src, size_t len) -{ - size_t i; - - for (i = 0; i < len / 4; i++) - dst[i] = be32dec(src + i * 4); -} - /* Elementary functions used by SHA224 */ #define Ch(x, y, z) ((x & (y ^ z)) ^ z) #define Maj(x, y, z) ((x & (y | z)) | (y & z)) #define SHR(x, n) (x >> n) -#define ROTR(x, n) ((x >> n) | (x << (32 - n))) -#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) -#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) -#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) -#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) +#define S0(x) (ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22)) +#define S1(x) (ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25)) +#define s0(x) (ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3)) +#define s1(x) (ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10)) /* SHA224 round function */ #define RND(a, b, c, d, e, f, g, h, k) \ @@ -88,7 +68,7 @@ be32dec_vect(uint32_t *dst, const uint8_t *src, size_t len) * the 512-bit input block to produce a new state. */ static void -sha224_Transform(uint32_t * state, const uint8_t block[64]) +sha224_Transform(uint32_t *state, const uint8_t block[64]) { uint32_t W[64]; uint32_t S[8]; @@ -96,7 +76,7 @@ sha224_Transform(uint32_t * state, const uint8_t block[64]) int i; /* 1. Prepare message schedule W. */ - be32dec_vect(W, block, 64); + be32decv(W, block, 16); for (i = 16; i < 64; i++) W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; @@ -104,16 +84,16 @@ sha224_Transform(uint32_t * state, const uint8_t block[64]) memcpy(S, state, 32); /* 3. Mix. */ - RNDr(S, W, 0, 0x428a2f98); - RNDr(S, W, 1, 0x71374491); - RNDr(S, W, 2, 0xb5c0fbcf); - RNDr(S, W, 3, 0xe9b5dba5); - RNDr(S, W, 4, 0x3956c25b); - RNDr(S, W, 5, 0x59f111f1); - RNDr(S, W, 6, 0x923f82a4); - RNDr(S, W, 7, 0xab1c5ed5); - RNDr(S, W, 8, 0xd807aa98); - RNDr(S, W, 9, 0x12835b01); + RNDr(S, W, 0, 0x428a2f98); + RNDr(S, W, 1, 0x71374491); + RNDr(S, W, 2, 0xb5c0fbcf); + RNDr(S, W, 3, 0xe9b5dba5); + RNDr(S, W, 4, 0x3956c25b); + RNDr(S, W, 5, 0x59f111f1); + RNDr(S, W, 6, 0x923f82a4); + RNDr(S, W, 7, 0xab1c5ed5); + RNDr(S, W, 8, 0xd807aa98); + RNDr(S, W, 9, 0x12835b01); RNDr(S, W, 10, 0x243185be); RNDr(S, W, 11, 0x550c7dc3); RNDr(S, W, 12, 0x72be5d74); @@ -172,23 +152,22 @@ sha224_Transform(uint32_t * state, const uint8_t block[64]) /* 4. Mix local working variables into global state. */ for (i = 0; i < 8; i++) state[i] += S[i]; - - /* Clean the stack. */ - memset(W, 0, 256); - memset(S, 0, 32); - t0 = t1 = 0; } static uint8_t PAD[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; /* Add padding and terminating bit-count. */ static void -sha224_pad(sha224_ctx * ctx) +sha224_pad(sha224_ctx *ctx) { uint8_t len[8]; uint32_t r, plen; @@ -213,7 +192,7 @@ sha224_pad(sha224_ctx * ctx) * Initialize the SHA224 context ${ctx}. */ void -sha224_init(sha224_ctx * ctx) +sha224_init(sha224_ctx *ctx) { /* Zero bits processed so far. */ @@ -235,7 +214,7 @@ sha224_init(sha224_ctx * ctx) * Input ${len} bytes from ${in} into the SHA224 context ${ctx}. */ void -sha224_update(sha224_ctx * ctx, const void *in, size_t len) +sha224_update(sha224_ctx *ctx, const void *in, size_t len) { uint32_t r; const uint8_t *src = in; @@ -279,17 +258,17 @@ sha224_update(sha224_ctx * ctx, const void *in, size_t len) * buffer ${digest}. */ void -sha224_final(sha224_ctx * ctx, uint8_t *digest) +sha224_final(sha224_ctx *ctx, uint8_t *digest) { /* Add padding. */ sha224_pad(ctx); /* Write the hash. */ - be32enc_vect(digest, ctx->state, SHA224_DIGEST_LEN); + be32encv(digest, ctx->state, SHA224_DIGEST_LEN / 4); /* Clear the context state. */ - memset(ctx, 0, sizeof(*ctx)); + memset_s(ctx, 0, sizeof *ctx, sizeof *ctx); } /** @@ -297,7 +276,7 @@ sha224_final(sha224_ctx * ctx, uint8_t *digest) * Compute the SHA224 hash of ${len} bytes from $in} and write it to ${digest}. */ void -sha224_complete(const void * in, size_t len, uint8_t *digest) +sha224_complete(const void *in, size_t len, uint8_t *digest) { sha224_ctx ctx; @@ -306,65 +285,6 @@ sha224_complete(const void * in, size_t len, uint8_t *digest) sha224_final(&ctx, digest); } -#if 0 -/** - * PBKDF2_SHA224(passwd, passwdlen, salt, saltlen, c, buf, dkLen): - * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA224 as the PRF, and - * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). - */ -void -pbkdf2_sha224(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, - size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) -{ - hmac_sha224_ctx PShctx, hctx; - size_t i; - uint8_t ivec[4]; - uint8_t U[SHA224_DIGEST_LEN]; - uint8_t T[SHA224_DIGEST_LEN]; - uint64_t j; - unsigned int k; - size_t clen; - - /* Compute HMAC state after processing P and S. */ - hmac_sha224_init(&PShctx, passwd, passwdlen); - hmac_sha224_update(&PShctx, salt, saltlen); - - /* Iterate through the blocks. */ - for (i = 0; i * 32 < dkLen; i++) { - /* Generate INT(i + 1). */ - be32enc(ivec, (uint32_t)(i + 1)); - - /* Compute U_1 = PRF(P, S || INT(i)). */ - memcpy(&hctx, &PShctx, sizeof(hmac_sha224_ctx)); - hmac_sha224_update(&hctx, ivec, 4); - hmac_sha224_final(&hctx, U); - - /* T_i = U_1 ... */ - memcpy(T, U, sizeof T); - - for (j = 2; j <= c; j++) { - /* Compute U_j. */ - hmac_sha224_init(&hctx, passwd, passwdlen); - hmac_sha224_update(&hctx, U, 32); - hmac_sha224_final(&hctx, U); - - /* ... xor U_j ... */ - for (k = 0; k < sizeof T; k++) - T[k] ^= U[k]; - } - - /* Copy as many bytes as necessary into buf. */ - clen = dkLen - i * 32; - if (clen > 32) - clen = 32; - memcpy(&buf[i * 32], T, clen); - } - - /* Clean PShctx, since we never called _final on it. */ - memset(&PShctx, 0, sizeof(hmac_sha224_ctx)); -} -#endif - digest_algorithm sha224_digest = { .name = "sha224", .contextlen = sizeof(sha224_ctx), diff --git a/lib/digest/cryb_sha256.c b/lib/digest/cryb_sha256.c index af7f21f..0537b82 100644 --- a/lib/digest/cryb_sha256.c +++ b/lib/digest/cryb_sha256.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005-2013 Colin Percival + * Copyright (c) 2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,6 +11,9 @@ * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -29,44 +33,19 @@ #include #include +#include #include +#include + #include -/* - * Encode a length len/4 vector of (uint32_t) into a length len vector of - * (uint8_t) in big-endian form. Assumes len is a multiple of 4. - */ -static void -be32enc_vect(uint8_t *dst, const uint32_t *src, size_t len) -{ - size_t i; - - for (i = 0; i < len / 4; i++) - be32enc(dst + i * 4, src[i]); -} - -/* - * Decode a big-endian length len vector of (uint8_t) into a length - * len/4 vector of (uint32_t). Assumes len is a multiple of 4. - */ -static void -be32dec_vect(uint32_t *dst, const uint8_t *src, size_t len) -{ - size_t i; - - for (i = 0; i < len / 4; i++) - dst[i] = be32dec(src + i * 4); -} - /* Elementary functions used by SHA256 */ #define Ch(x, y, z) ((x & (y ^ z)) ^ z) #define Maj(x, y, z) ((x & (y | z)) | (y & z)) -#define SHR(x, n) (x >> n) -#define ROTR(x, n) ((x >> n) | (x << (32 - n))) -#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) -#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) -#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) -#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) +#define S0(x) (ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22)) +#define S1(x) (ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25)) +#define s0(x) (ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3)) +#define s1(x) (ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10)) /* SHA256 round function */ #define RND(a, b, c, d, e, f, g, h, k) \ @@ -96,7 +75,7 @@ sha256_Transform(uint32_t * state, const uint8_t block[64]) int i; /* 1. Prepare message schedule W. */ - be32dec_vect(W, block, 64); + be32decv(W, block, 16); for (i = 16; i < 64; i++) W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; @@ -104,16 +83,16 @@ sha256_Transform(uint32_t * state, const uint8_t block[64]) memcpy(S, state, 32); /* 3. Mix. */ - RNDr(S, W, 0, 0x428a2f98); - RNDr(S, W, 1, 0x71374491); - RNDr(S, W, 2, 0xb5c0fbcf); - RNDr(S, W, 3, 0xe9b5dba5); - RNDr(S, W, 4, 0x3956c25b); - RNDr(S, W, 5, 0x59f111f1); - RNDr(S, W, 6, 0x923f82a4); - RNDr(S, W, 7, 0xab1c5ed5); - RNDr(S, W, 8, 0xd807aa98); - RNDr(S, W, 9, 0x12835b01); + RNDr(S, W, 0, 0x428a2f98); + RNDr(S, W, 1, 0x71374491); + RNDr(S, W, 2, 0xb5c0fbcf); + RNDr(S, W, 3, 0xe9b5dba5); + RNDr(S, W, 4, 0x3956c25b); + RNDr(S, W, 5, 0x59f111f1); + RNDr(S, W, 6, 0x923f82a4); + RNDr(S, W, 7, 0xab1c5ed5); + RNDr(S, W, 8, 0xd807aa98); + RNDr(S, W, 9, 0x12835b01); RNDr(S, W, 10, 0x243185be); RNDr(S, W, 11, 0x550c7dc3); RNDr(S, W, 12, 0x72be5d74); @@ -172,18 +151,17 @@ sha256_Transform(uint32_t * state, const uint8_t block[64]) /* 4. Mix local working variables into global state. */ for (i = 0; i < 8; i++) state[i] += S[i]; - - /* Clean the stack. */ - memset(W, 0, 256); - memset(S, 0, 32); - t0 = t1 = 0; } static uint8_t PAD[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; /* Add padding and terminating bit-count. */ @@ -286,10 +264,10 @@ sha256_final(sha256_ctx * ctx, uint8_t *digest) sha256_pad(ctx); /* Write the hash. */ - be32enc_vect(digest, ctx->state, SHA256_DIGEST_LEN); + be32encv(digest, ctx->state, SHA256_DIGEST_LEN / 4); /* Clear the context state. */ - memset(ctx, 0, sizeof(*ctx)); + memset_s(ctx, 0, sizeof *ctx, sizeof *ctx); } /** @@ -297,7 +275,7 @@ sha256_final(sha256_ctx * ctx, uint8_t *digest) * Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}. */ void -sha256_complete(const void * in, size_t len, uint8_t *digest) +sha256_complete(const void *in, size_t len, uint8_t *digest) { sha256_ctx ctx; @@ -306,65 +284,6 @@ sha256_complete(const void * in, size_t len, uint8_t *digest) sha256_final(&ctx, digest); } -#if 0 -/** - * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): - * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and - * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). - */ -void -pbkdf2_sha256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, - size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) -{ - hmac_sha256_ctx PShctx, hctx; - size_t i; - uint8_t ivec[4]; - uint8_t U[SHA256_DIGEST_LEN]; - uint8_t T[SHA256_DIGEST_LEN]; - uint64_t j; - unsigned int k; - size_t clen; - - /* Compute HMAC state after processing P and S. */ - hmac_sha256_init(&PShctx, passwd, passwdlen); - hmac_sha256_update(&PShctx, salt, saltlen); - - /* Iterate through the blocks. */ - for (i = 0; i * 32 < dkLen; i++) { - /* Generate INT(i + 1). */ - be32enc(ivec, (uint32_t)(i + 1)); - - /* Compute U_1 = PRF(P, S || INT(i)). */ - memcpy(&hctx, &PShctx, sizeof(hmac_sha256_ctx)); - hmac_sha256_update(&hctx, ivec, 4); - hmac_sha256_final(&hctx, U); - - /* T_i = U_1 ... */ - memcpy(T, U, sizeof T); - - for (j = 2; j <= c; j++) { - /* Compute U_j. */ - hmac_sha256_init(&hctx, passwd, passwdlen); - hmac_sha256_update(&hctx, U, 32); - hmac_sha256_final(&hctx, U); - - /* ... xor U_j ... */ - for (k = 0; k < sizeof T; k++) - T[k] ^= U[k]; - } - - /* Copy as many bytes as necessary into buf. */ - clen = dkLen - i * 32; - if (clen > 32) - clen = 32; - memcpy(&buf[i * 32], T, clen); - } - - /* Clean PShctx, since we never called _final on it. */ - memset(&PShctx, 0, sizeof(hmac_sha256_ctx)); -} -#endif - digest_algorithm sha256_digest = { .name = "sha256", .contextlen = sizeof(sha256_ctx), diff --git a/lib/digest/cryb_sha384.c b/lib/digest/cryb_sha384.c index ba3b219..f4406eb 100644 --- a/lib/digest/cryb_sha384.c +++ b/lib/digest/cryb_sha384.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2006-2007 Christophe Devine + * Copyright (c) 2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,282 +27,263 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * The SHA-384 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ #include "cryb/impl.h" #include #include +#include +#include +#include + #include -/* - * 64-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT64_BE -#define GET_UINT64_BE(n,b,i) \ -do { \ - (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ - | ( (uint64_t) (b)[(i) + 1] << 48 ) \ - | ( (uint64_t) (b)[(i) + 2] << 40 ) \ - | ( (uint64_t) (b)[(i) + 3] << 32 ) \ - | ( (uint64_t) (b)[(i) + 4] << 24 ) \ - | ( (uint64_t) (b)[(i) + 5] << 16 ) \ - | ( (uint64_t) (b)[(i) + 6] << 8 ) \ - | ( (uint64_t) (b)[(i) + 7] ); \ -} while (0) -#endif - -#ifndef PUT_UINT64_BE -#define PUT_UINT64_BE(n,b,i) \ -do { \ - (b)[(i) ] = (uint8_t) ( (n) >> 56 ); \ - (b)[(i) + 1] = (uint8_t) ( (n) >> 48 ); \ - (b)[(i) + 2] = (uint8_t) ( (n) >> 40 ); \ - (b)[(i) + 3] = (uint8_t) ( (n) >> 32 ); \ - (b)[(i) + 4] = (uint8_t) ( (n) >> 24 ); \ - (b)[(i) + 5] = (uint8_t) ( (n) >> 16 ); \ - (b)[(i) + 6] = (uint8_t) ( (n) >> 8 ); \ - (b)[(i) + 7] = (uint8_t) ( (n) ); \ -} while (0) -#endif - -/* XXX */ -#define UL64(x) x##ULL - -/* - * Round constants - */ -static const uint64_t K[80] = -{ - UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), - UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), - UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), - UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), - UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), - UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), - UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), - UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), - UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), - UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), - UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), - UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), - UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), - UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), - UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), - UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), - UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), - UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), - UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), - UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), - UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), - UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), - UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), - UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), - UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), - UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), - UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), - UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), - UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), - UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), - UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), - UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), - UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), - UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), - UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), - UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), - UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), - UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), - UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), - UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +static const uint64_t sha384_h[8] = { + 0xCBBB9D5DC1059ED8ULL, 0x629A292A367CD507ULL, + 0x9159015A3070DD17ULL, 0x152FECD8F70E5939ULL, + 0x67332667FFC00B31ULL, 0x8EB44A8768581511ULL, + 0xDB0C2E0D64F98FA7ULL, 0x47B5481DBEFA4FA4ULL, }; -/* - * SHA-384 context setup - */ -void sha384_init( sha384_ctx *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); - ctx->state[1] = UL64(0x629A292A367CD507); - ctx->state[2] = UL64(0x9159015A3070DD17); - ctx->state[3] = UL64(0x152FECD8F70E5939); - ctx->state[4] = UL64(0x67332667FFC00B31); - ctx->state[5] = UL64(0x8EB44A8768581511); - ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); - ctx->state[7] = UL64(0x47B5481DBEFA4FA4); -} - -static void sha384_process( sha384_ctx *ctx, const uint8_t *data ) -{ - int i; - uint64_t temp1, temp2, W[80]; - uint64_t A, B, C, D, E, F, G, H; - -#define SHR(x,n) (x >> n) -#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) - -#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) -#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) - -#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) -#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) - -#define F0(x,y,z) ((x & y) | (z & (x | y))) -#define F1(x,y,z) (z ^ (x & (y ^ z))) - -#define P(a,b,c,d,e,f,g,h,x,K) \ -{ \ - temp1 = h + S3(e) + F1(e,f,g) + K + x; \ - temp2 = S2(a) + F0(a,b,c); \ - d += temp1; h = temp1 + temp2; \ -} - - for( i = 0; i < 16; i++ ) - { - GET_UINT64_BE( W[i], data, i << 3 ); - } - - for( ; i < 80; i++ ) - { - W[i] = S1(W[i - 2]) + W[i - 7] + - S0(W[i - 15]) + W[i - 16]; - } - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - F = ctx->state[5]; - G = ctx->state[6]; - H = ctx->state[7]; - i = 0; - - do - { - P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; - P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; - P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; - P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; - P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; - P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; - P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; - P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; - } - while( i < 80 ); - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; - ctx->state[5] += F; - ctx->state[6] += G; - ctx->state[7] += H; -} - -/* - * SHA-384 process buffer - */ -void sha384_update( sha384_ctx *ctx, const void *input, int ilen ) -{ - int fill; - uint64_t left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x7F; - fill = (int)( 128 - left ); - - ctx->total[0] += ilen; - - if( ctx->total[0] < (uint64_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (ctx->buffer + left), input, fill ); - sha384_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 128 ) - { - sha384_process( ctx, input ); - input += 128; - ilen -= 128; - } - - if( ilen > 0 ) - { - memcpy( (ctx->buffer + left), input, ilen ); - } -} - -static const uint8_t sha384_padding[128] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +static const uint64_t sha384_k[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-384 final digest - */ -void sha384_final( sha384_ctx *ctx, uint8_t *output ) +void +sha384_init(sha384_ctx *ctx) { - int last, padn; - uint64_t high, low; - uint8_t msglen[16]; - high = ( ctx->total[0] >> 61 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT64_BE( high, msglen, 0 ); - PUT_UINT64_BE( low, msglen, 8 ); - - last = (int)( ctx->total[0] & 0x7F ); - padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); - - sha384_update( ctx, (const uint8_t *) sha384_padding, padn ); - sha384_update( ctx, msglen, 16 ); - - PUT_UINT64_BE( ctx->state[0], output, 0 ); - PUT_UINT64_BE( ctx->state[1], output, 8 ); - PUT_UINT64_BE( ctx->state[2], output, 16 ); - PUT_UINT64_BE( ctx->state[3], output, 24 ); - PUT_UINT64_BE( ctx->state[4], output, 32 ); - PUT_UINT64_BE( ctx->state[5], output, 40 ); + memset(ctx, 0, sizeof *ctx); + memcpy(ctx->h, sha384_h, sizeof ctx->h); } -/* - * output = SHA-384( input buffer ) - */ -void sha384_complete( const void *input, int ilen, uint8_t *output ) +#define S0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) +#define S1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6)) + +#define S2(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39)) +#define S3(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41)) + +#define F0(x, y, z) ((x & y) | (z & (x | y))) +#define F1(x, y, z) (z ^ (x & (y ^ z))) + +#define P(i, a, b, c, d, e, f, g, h) do { \ + uint64_t t0, t1; \ + t0 = h + S3(e) + F1(e, f, g) + sha384_k[i] + w[i]; \ + t1 = S2(a) + F0(a, b, c); \ + d += t0; h = t0 + t1; \ + } while (0) + +static void +sha384_compute(sha384_ctx *ctx, const uint8_t *data) { - sha384_ctx ctx; + uint64_t w[80], A, B, C, D, E, F, G, H; + unsigned int i; - sha384_init( &ctx ); - sha384_update( &ctx, input, ilen ); - sha384_final( &ctx, output ); + be64decv(w, data, 16); + for (i = 16; i < 80; i++) + w[i] = S1(w[i - 2]) + w[i - 7] + S0(w[i - 15]) + w[i - 16]; + A = ctx->h[0]; + B = ctx->h[1]; + C = ctx->h[2]; + D = ctx->h[3]; + E = ctx->h[4]; + F = ctx->h[5]; + G = ctx->h[6]; + H = ctx->h[7]; - memset( &ctx, 0, sizeof( sha384_ctx ) ); + P( 0, A, B, C, D, E, F, G, H); + P( 1, H, A, B, C, D, E, F, G); + P( 2, G, H, A, B, C, D, E, F); + P( 3, F, G, H, A, B, C, D, E); + P( 4, E, F, G, H, A, B, C, D); + P( 5, D, E, F, G, H, A, B, C); + P( 6, C, D, E, F, G, H, A, B); + P( 7, B, C, D, E, F, G, H, A); + + P( 8, A, B, C, D, E, F, G, H); + P( 9, H, A, B, C, D, E, F, G); + P(10, G, H, A, B, C, D, E, F); + P(11, F, G, H, A, B, C, D, E); + P(12, E, F, G, H, A, B, C, D); + P(13, D, E, F, G, H, A, B, C); + P(14, C, D, E, F, G, H, A, B); + P(15, B, C, D, E, F, G, H, A); + + P(16, A, B, C, D, E, F, G, H); + P(17, H, A, B, C, D, E, F, G); + P(18, G, H, A, B, C, D, E, F); + P(19, F, G, H, A, B, C, D, E); + P(20, E, F, G, H, A, B, C, D); + P(21, D, E, F, G, H, A, B, C); + P(22, C, D, E, F, G, H, A, B); + P(23, B, C, D, E, F, G, H, A); + + P(24, A, B, C, D, E, F, G, H); + P(25, H, A, B, C, D, E, F, G); + P(26, G, H, A, B, C, D, E, F); + P(27, F, G, H, A, B, C, D, E); + P(28, E, F, G, H, A, B, C, D); + P(29, D, E, F, G, H, A, B, C); + P(30, C, D, E, F, G, H, A, B); + P(31, B, C, D, E, F, G, H, A); + + P(32, A, B, C, D, E, F, G, H); + P(33, H, A, B, C, D, E, F, G); + P(34, G, H, A, B, C, D, E, F); + P(35, F, G, H, A, B, C, D, E); + P(36, E, F, G, H, A, B, C, D); + P(37, D, E, F, G, H, A, B, C); + P(38, C, D, E, F, G, H, A, B); + P(39, B, C, D, E, F, G, H, A); + + P(40, A, B, C, D, E, F, G, H); + P(41, H, A, B, C, D, E, F, G); + P(42, G, H, A, B, C, D, E, F); + P(43, F, G, H, A, B, C, D, E); + P(44, E, F, G, H, A, B, C, D); + P(45, D, E, F, G, H, A, B, C); + P(46, C, D, E, F, G, H, A, B); + P(47, B, C, D, E, F, G, H, A); + + P(48, A, B, C, D, E, F, G, H); + P(49, H, A, B, C, D, E, F, G); + P(50, G, H, A, B, C, D, E, F); + P(51, F, G, H, A, B, C, D, E); + P(52, E, F, G, H, A, B, C, D); + P(53, D, E, F, G, H, A, B, C); + P(54, C, D, E, F, G, H, A, B); + P(55, B, C, D, E, F, G, H, A); + + P(56, A, B, C, D, E, F, G, H); + P(57, H, A, B, C, D, E, F, G); + P(58, G, H, A, B, C, D, E, F); + P(59, F, G, H, A, B, C, D, E); + P(60, E, F, G, H, A, B, C, D); + P(61, D, E, F, G, H, A, B, C); + P(62, C, D, E, F, G, H, A, B); + P(63, B, C, D, E, F, G, H, A); + + P(64, A, B, C, D, E, F, G, H); + P(65, H, A, B, C, D, E, F, G); + P(66, G, H, A, B, C, D, E, F); + P(67, F, G, H, A, B, C, D, E); + P(68, E, F, G, H, A, B, C, D); + P(69, D, E, F, G, H, A, B, C); + P(70, C, D, E, F, G, H, A, B); + P(71, B, C, D, E, F, G, H, A); + + P(72, A, B, C, D, E, F, G, H); + P(73, H, A, B, C, D, E, F, G); + P(74, G, H, A, B, C, D, E, F); + P(75, F, G, H, A, B, C, D, E); + P(76, E, F, G, H, A, B, C, D); + P(77, D, E, F, G, H, A, B, C); + P(78, C, D, E, F, G, H, A, B); + P(79, B, C, D, E, F, G, H, A); + + ctx->h[0] += A; + ctx->h[1] += B; + ctx->h[2] += C; + ctx->h[3] += D; + ctx->h[4] += E; + ctx->h[5] += F; + ctx->h[6] += G; + ctx->h[7] += H; +} + +void +sha384_update(sha384_ctx *ctx, const void *buf, size_t len) +{ + size_t copylen; + + while (len) { + if (ctx->blocklen > 0 || len < sizeof ctx->block) { + copylen = sizeof ctx->block - ctx->blocklen; + if (copylen > len) + copylen = len; + memcpy(ctx->block + ctx->blocklen, buf, copylen); + ctx->blocklen += copylen; + if (ctx->blocklen == sizeof ctx->block) { + sha384_compute(ctx, ctx->block); + ctx->blocklen = 0; + } + } else { + copylen = sizeof ctx->block; + sha384_compute(ctx, buf); + } + if ((ctx->bitlen[1] += copylen * 8) < copylen * 8) + ctx->bitlen[0]++; + buf += copylen; + len -= copylen; + } +} + +void +sha384_final(sha384_ctx *ctx, uint8_t *digest) +{ + + ctx->block[ctx->blocklen++] = 0x80; + memset(ctx->block + ctx->blocklen, 0, + sizeof ctx->block - ctx->blocklen); + if (ctx->blocklen > 112) { + sha384_compute(ctx, ctx->block); + ctx->blocklen = 0; + memset(ctx->block, 0, sizeof ctx->block); + } + be64encv(ctx->block + 112, ctx->bitlen, 2); + sha384_compute(ctx, ctx->block); + be64encv(digest, ctx->h, 6); + memset_s(ctx, 0, sizeof *ctx, sizeof *ctx); +} + +void +sha384_complete(const void *buf, size_t len, uint8_t *digest) +{ + sha384_ctx ctx; + + sha384_init(&ctx); + sha384_update(&ctx, buf, len); + sha384_final(&ctx, digest); } digest_algorithm sha384_digest = { diff --git a/lib/digest/cryb_sha512.c b/lib/digest/cryb_sha512.c index af6fcb7..a52c15b 100644 --- a/lib/digest/cryb_sha512.c +++ b/lib/digest/cryb_sha512.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2006-2007 Christophe Devine + * Copyright (c) 2017 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,285 +27,263 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * The SHA-512 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ #include "cryb/impl.h" #include #include +#include +#include +#include + #include -/* - * 64-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT64_BE -#define GET_UINT64_BE(n,b,i) \ -do { \ - (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ - | ( (uint64_t) (b)[(i) + 1] << 48 ) \ - | ( (uint64_t) (b)[(i) + 2] << 40 ) \ - | ( (uint64_t) (b)[(i) + 3] << 32 ) \ - | ( (uint64_t) (b)[(i) + 4] << 24 ) \ - | ( (uint64_t) (b)[(i) + 5] << 16 ) \ - | ( (uint64_t) (b)[(i) + 6] << 8 ) \ - | ( (uint64_t) (b)[(i) + 7] ); \ -} while (0) -#endif - -#ifndef PUT_UINT64_BE -#define PUT_UINT64_BE(n,b,i) \ -do { \ - (b)[(i) ] = (uint8_t) ( (n) >> 56 ); \ - (b)[(i) + 1] = (uint8_t) ( (n) >> 48 ); \ - (b)[(i) + 2] = (uint8_t) ( (n) >> 40 ); \ - (b)[(i) + 3] = (uint8_t) ( (n) >> 32 ); \ - (b)[(i) + 4] = (uint8_t) ( (n) >> 24 ); \ - (b)[(i) + 5] = (uint8_t) ( (n) >> 16 ); \ - (b)[(i) + 6] = (uint8_t) ( (n) >> 8 ); \ - (b)[(i) + 7] = (uint8_t) ( (n) ); \ -} while (0) -#endif - -/* XXX */ -#define UL64(x) x##ULL - -/* - * Round constants - */ -static const uint64_t K[80] = -{ - UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), - UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), - UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), - UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), - UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), - UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), - UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), - UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), - UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), - UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), - UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), - UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), - UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), - UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), - UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), - UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), - UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), - UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), - UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), - UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), - UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), - UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), - UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), - UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), - UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), - UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), - UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), - UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), - UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), - UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), - UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), - UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), - UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), - UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), - UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), - UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), - UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), - UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), - UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), - UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +static const uint64_t sha512_h[8] = { + 0x6A09E667F3BCC908ULL, 0xBB67AE8584CAA73BULL, + 0x3C6EF372FE94F82BULL, 0xA54FF53A5F1D36F1ULL, + 0x510E527FADE682D1ULL, 0x9B05688C2B3E6C1FULL, + 0x1F83D9ABFB41BD6BULL, 0x5BE0CD19137E2179ULL, }; -/* - * SHA-512 context setup - */ -void sha512_init( sha512_ctx *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = UL64(0x6A09E667F3BCC908); - ctx->state[1] = UL64(0xBB67AE8584CAA73B); - ctx->state[2] = UL64(0x3C6EF372FE94F82B); - ctx->state[3] = UL64(0xA54FF53A5F1D36F1); - ctx->state[4] = UL64(0x510E527FADE682D1); - ctx->state[5] = UL64(0x9B05688C2B3E6C1F); - ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); - ctx->state[7] = UL64(0x5BE0CD19137E2179); -} - -static void sha512_process( sha512_ctx *ctx, const uint8_t *data ) -{ - int i; - uint64_t temp1, temp2, W[80]; - uint64_t A, B, C, D, E, F, G, H; - -#define SHR(x,n) (x >> n) -#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) - -#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) -#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) - -#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) -#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) - -#define F0(x,y,z) ((x & y) | (z & (x | y))) -#define F1(x,y,z) (z ^ (x & (y ^ z))) - -#define P(a,b,c,d,e,f,g,h,x,K) \ -{ \ - temp1 = h + S3(e) + F1(e,f,g) + K + x; \ - temp2 = S2(a) + F0(a,b,c); \ - d += temp1; h = temp1 + temp2; \ -} - - for( i = 0; i < 16; i++ ) - { - GET_UINT64_BE( W[i], data, i << 3 ); - } - - for( ; i < 80; i++ ) - { - W[i] = S1(W[i - 2]) + W[i - 7] + - S0(W[i - 15]) + W[i - 16]; - } - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - F = ctx->state[5]; - G = ctx->state[6]; - H = ctx->state[7]; - i = 0; - - do - { - P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; - P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; - P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; - P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; - P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; - P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; - P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; - P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; - } - while( i < 80 ); - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; - ctx->state[5] += F; - ctx->state[6] += G; - ctx->state[7] += H; -} - -/* - * SHA-512 process buffer - */ -void sha512_update( sha512_ctx *ctx, const void *input, int ilen ) -{ - int fill; - uint64_t left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x7F; - fill = (int)( 128 - left ); - - ctx->total[0] += ilen; - - if( ctx->total[0] < (uint64_t) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (ctx->buffer + left), input, fill ); - sha512_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 128 ) - { - sha512_process( ctx, input ); - input += 128; - ilen -= 128; - } - - if( ilen > 0 ) - { - memcpy( (ctx->buffer + left), input, ilen ); - } -} - -static const uint8_t sha512_padding[128] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +static const uint64_t sha512_k[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-512 final digest - */ -void sha512_final( sha512_ctx *ctx, uint8_t *output ) +void +sha512_init(sha512_ctx *ctx) { - int last, padn; - uint64_t high, low; - uint8_t msglen[16]; - high = ( ctx->total[0] >> 61 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT64_BE( high, msglen, 0 ); - PUT_UINT64_BE( low, msglen, 8 ); - - last = (int)( ctx->total[0] & 0x7F ); - padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); - - sha512_update( ctx, (const uint8_t *) sha512_padding, padn ); - sha512_update( ctx, msglen, 16 ); - - PUT_UINT64_BE( ctx->state[0], output, 0 ); - PUT_UINT64_BE( ctx->state[1], output, 8 ); - PUT_UINT64_BE( ctx->state[2], output, 16 ); - PUT_UINT64_BE( ctx->state[3], output, 24 ); - PUT_UINT64_BE( ctx->state[4], output, 32 ); - PUT_UINT64_BE( ctx->state[5], output, 40 ); - - PUT_UINT64_BE( ctx->state[6], output, 48 ); - PUT_UINT64_BE( ctx->state[7], output, 56 ); + memset(ctx, 0, sizeof *ctx); + memcpy(ctx->h, sha512_h, sizeof ctx->h); } -/* - * output = SHA-512( input buffer ) - */ -void sha512_complete( const void *input, int ilen, uint8_t *output ) +#define S0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) +#define S1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6)) + +#define S2(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39)) +#define S3(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41)) + +#define F0(x, y, z) ((x & y) | (z & (x | y))) +#define F1(x, y, z) (z ^ (x & (y ^ z))) + +#define P(i, a, b, c, d, e, f, g, h) do { \ + uint64_t t0, t1; \ + t0 = h + S3(e) + F1(e, f, g) + sha512_k[i] + w[i]; \ + t1 = S2(a) + F0(a, b, c); \ + d += t0; h = t0 + t1; \ + } while (0) + +static void +sha512_compute(sha512_ctx *ctx, const uint8_t *data) { - sha512_ctx ctx; + uint64_t w[80], A, B, C, D, E, F, G, H; + unsigned int i; - sha512_init( &ctx ); - sha512_update( &ctx, input, ilen ); - sha512_final( &ctx, output ); + be64decv(w, data, 16); + for (i = 16; i < 80; i++) + w[i] = S1(w[i - 2]) + w[i - 7] + S0(w[i - 15]) + w[i - 16]; + A = ctx->h[0]; + B = ctx->h[1]; + C = ctx->h[2]; + D = ctx->h[3]; + E = ctx->h[4]; + F = ctx->h[5]; + G = ctx->h[6]; + H = ctx->h[7]; - memset( &ctx, 0, sizeof( sha512_ctx ) ); + P( 0, A, B, C, D, E, F, G, H); + P( 1, H, A, B, C, D, E, F, G); + P( 2, G, H, A, B, C, D, E, F); + P( 3, F, G, H, A, B, C, D, E); + P( 4, E, F, G, H, A, B, C, D); + P( 5, D, E, F, G, H, A, B, C); + P( 6, C, D, E, F, G, H, A, B); + P( 7, B, C, D, E, F, G, H, A); + + P( 8, A, B, C, D, E, F, G, H); + P( 9, H, A, B, C, D, E, F, G); + P(10, G, H, A, B, C, D, E, F); + P(11, F, G, H, A, B, C, D, E); + P(12, E, F, G, H, A, B, C, D); + P(13, D, E, F, G, H, A, B, C); + P(14, C, D, E, F, G, H, A, B); + P(15, B, C, D, E, F, G, H, A); + + P(16, A, B, C, D, E, F, G, H); + P(17, H, A, B, C, D, E, F, G); + P(18, G, H, A, B, C, D, E, F); + P(19, F, G, H, A, B, C, D, E); + P(20, E, F, G, H, A, B, C, D); + P(21, D, E, F, G, H, A, B, C); + P(22, C, D, E, F, G, H, A, B); + P(23, B, C, D, E, F, G, H, A); + + P(24, A, B, C, D, E, F, G, H); + P(25, H, A, B, C, D, E, F, G); + P(26, G, H, A, B, C, D, E, F); + P(27, F, G, H, A, B, C, D, E); + P(28, E, F, G, H, A, B, C, D); + P(29, D, E, F, G, H, A, B, C); + P(30, C, D, E, F, G, H, A, B); + P(31, B, C, D, E, F, G, H, A); + + P(32, A, B, C, D, E, F, G, H); + P(33, H, A, B, C, D, E, F, G); + P(34, G, H, A, B, C, D, E, F); + P(35, F, G, H, A, B, C, D, E); + P(36, E, F, G, H, A, B, C, D); + P(37, D, E, F, G, H, A, B, C); + P(38, C, D, E, F, G, H, A, B); + P(39, B, C, D, E, F, G, H, A); + + P(40, A, B, C, D, E, F, G, H); + P(41, H, A, B, C, D, E, F, G); + P(42, G, H, A, B, C, D, E, F); + P(43, F, G, H, A, B, C, D, E); + P(44, E, F, G, H, A, B, C, D); + P(45, D, E, F, G, H, A, B, C); + P(46, C, D, E, F, G, H, A, B); + P(47, B, C, D, E, F, G, H, A); + + P(48, A, B, C, D, E, F, G, H); + P(49, H, A, B, C, D, E, F, G); + P(50, G, H, A, B, C, D, E, F); + P(51, F, G, H, A, B, C, D, E); + P(52, E, F, G, H, A, B, C, D); + P(53, D, E, F, G, H, A, B, C); + P(54, C, D, E, F, G, H, A, B); + P(55, B, C, D, E, F, G, H, A); + + P(56, A, B, C, D, E, F, G, H); + P(57, H, A, B, C, D, E, F, G); + P(58, G, H, A, B, C, D, E, F); + P(59, F, G, H, A, B, C, D, E); + P(60, E, F, G, H, A, B, C, D); + P(61, D, E, F, G, H, A, B, C); + P(62, C, D, E, F, G, H, A, B); + P(63, B, C, D, E, F, G, H, A); + + P(64, A, B, C, D, E, F, G, H); + P(65, H, A, B, C, D, E, F, G); + P(66, G, H, A, B, C, D, E, F); + P(67, F, G, H, A, B, C, D, E); + P(68, E, F, G, H, A, B, C, D); + P(69, D, E, F, G, H, A, B, C); + P(70, C, D, E, F, G, H, A, B); + P(71, B, C, D, E, F, G, H, A); + + P(72, A, B, C, D, E, F, G, H); + P(73, H, A, B, C, D, E, F, G); + P(74, G, H, A, B, C, D, E, F); + P(75, F, G, H, A, B, C, D, E); + P(76, E, F, G, H, A, B, C, D); + P(77, D, E, F, G, H, A, B, C); + P(78, C, D, E, F, G, H, A, B); + P(79, B, C, D, E, F, G, H, A); + + ctx->h[0] += A; + ctx->h[1] += B; + ctx->h[2] += C; + ctx->h[3] += D; + ctx->h[4] += E; + ctx->h[5] += F; + ctx->h[6] += G; + ctx->h[7] += H; +} + +void +sha512_update(sha512_ctx *ctx, const void *buf, size_t len) +{ + size_t copylen; + + while (len) { + if (ctx->blocklen > 0 || len < sizeof ctx->block) { + copylen = sizeof ctx->block - ctx->blocklen; + if (copylen > len) + copylen = len; + memcpy(ctx->block + ctx->blocklen, buf, copylen); + ctx->blocklen += copylen; + if (ctx->blocklen == sizeof ctx->block) { + sha512_compute(ctx, ctx->block); + ctx->blocklen = 0; + } + } else { + copylen = sizeof ctx->block; + sha512_compute(ctx, buf); + } + if ((ctx->bitlen[1] += copylen * 8) < copylen * 8) + ctx->bitlen[0]++; + buf += copylen; + len -= copylen; + } +} + +void +sha512_final(sha512_ctx *ctx, uint8_t *digest) +{ + + ctx->block[ctx->blocklen++] = 0x80; + memset(ctx->block + ctx->blocklen, 0, + sizeof ctx->block - ctx->blocklen); + if (ctx->blocklen > 112) { + sha512_compute(ctx, ctx->block); + ctx->blocklen = 0; + memset(ctx->block, 0, sizeof ctx->block); + } + be64encv(ctx->block + 112, ctx->bitlen, 2); + sha512_compute(ctx, ctx->block); + be64encv(digest, ctx->h, 8); + memset_s(ctx, 0, sizeof *ctx, sizeof *ctx); +} + +void +sha512_complete(const void *buf, size_t len, uint8_t *digest) +{ + sha512_ctx ctx; + + sha512_init(&ctx); + sha512_update(&ctx, buf, len); + sha512_final(&ctx, digest); } digest_algorithm sha512_digest = { diff --git a/t/t_sha384.c b/t/t_sha384.c index 1093d3a..24277b9 100644 --- a/t/t_sha384.c +++ b/t/t_sha384.c @@ -229,22 +229,19 @@ t_sha384_carry(char **desc CRYB_UNUSED, void *arg CRYB_UNUSED) sha384_ctx ctx; uint8_t digest[SHA384_DIGEST_LEN]; static uint8_t expect[SHA384_DIGEST_LEN] = { - 0x04, 0xa8, 0xab, 0x2a, 0x7d, 0xe6, 0x68, 0x22, - 0xcd, 0x45, 0xfd, 0xc5, 0x41, 0x62, 0x32, 0xca, - 0x6c, 0x59, 0x92, 0x41, 0x77, 0x99, 0xca, 0xa7, - 0xe2, 0xf0, 0x28, 0x77, 0x2b, 0x33, 0xbe, 0xa0, - 0xbe, 0xee, 0x4d, 0xd1, 0x9e, 0x18, 0xc4, 0x5f, - 0x47, 0x91, 0xb3, 0xd1, 0x9c, 0x3a, 0x81, 0xfb, + 0x04, 0x69, 0xc2, 0x19, 0xcd, 0x88, 0x40, 0xf9, + 0xbb, 0xb6, 0xd8, 0x68, 0xab, 0x24, 0xf1, 0x5e, + 0x35, 0x79, 0xa9, 0xfc, 0xf3, 0x21, 0xc2, 0x27, + 0x79, 0x1f, 0x0a, 0x73, 0x4a, 0x50, 0x73, 0x24, + 0xfe, 0xcd, 0x3a, 0xca, 0x22, 0x5d, 0x22, 0xe7, + 0x7e, 0x1c, 0x75, 0xcb, 0x72, 0xee, 0x3a, 0xf8, }; sha384_init(&ctx); #if WITH_OPENSSL - /* openssl counts bits */ - ctx.Nl = 0xffffffffffffff80LLU << 3LLU; - ctx.Nh = 0xffffffffffffff80LLU >> 61LLU; + ctx.Nl = 0xfffffffffffffc00LLU; #else - /* cryb counts bytes and multiplies at the end */ - ctx.total[0] = 0xffffffffffffff80LLU; + ctx.bitlen[1] = 0xfffffffffffffc00LLU; #endif sha384_update(&ctx, t_seq8, 256); sha384_final(&ctx, digest); diff --git a/t/t_sha512.c b/t/t_sha512.c index de38856..7816381 100644 --- a/t/t_sha512.c +++ b/t/t_sha512.c @@ -239,24 +239,21 @@ t_sha512_carry(char **desc CRYB_UNUSED, void *arg CRYB_UNUSED) sha512_ctx ctx; uint8_t digest[SHA512_DIGEST_LEN]; static uint8_t expect[SHA512_DIGEST_LEN] = { - 0xbd, 0x25, 0x6d, 0xa8, 0xbf, 0xe0, 0x6c, 0xf0, - 0xc1, 0x8c, 0xe9, 0x58, 0xb8, 0xce, 0x43, 0xc7, - 0x9a, 0x3d, 0xec, 0x10, 0x58, 0x55, 0x00, 0x7f, - 0xe7, 0x75, 0x48, 0x66, 0xb2, 0x18, 0xc3, 0x98, - 0x91, 0x11, 0x75, 0x88, 0x53, 0x3e, 0xb3, 0x4b, - 0x83, 0x93, 0xca, 0x18, 0x8a, 0xbe, 0x32, 0x7d, - 0x4a, 0x54, 0x16, 0xbb, 0xdf, 0x9e, 0x9c, 0x3a, - 0xd7, 0x22, 0xc8, 0x0d, 0x71, 0x0f, 0x76, 0xc0, + 0x00, 0x79, 0xb9, 0x71, 0xd3, 0x86, 0x0b, 0x53, + 0x64, 0xc7, 0x37, 0x63, 0x97, 0x8f, 0x35, 0x14, + 0xed, 0x53, 0x20, 0x3d, 0xae, 0x03, 0xa0, 0x37, + 0x70, 0xbe, 0xce, 0x70, 0x87, 0x20, 0x21, 0x16, + 0x43, 0x8d, 0x3f, 0xe2, 0xbc, 0x02, 0xf0, 0x8c, + 0xc9, 0x98, 0x4c, 0x4d, 0xf3, 0x6f, 0x0b, 0xbb, + 0x55, 0x94, 0x70, 0x95, 0xf1, 0x9f, 0xaf, 0xaf, + 0xd6, 0xbb, 0x3a, 0xbb, 0x4d, 0x6a, 0xf0, 0xc0, }; sha512_init(&ctx); #if WITH_OPENSSL - /* openssl counts bits */ - ctx.Nl = 0xffffffffffffff80LLU << 3LLU; - ctx.Nh = 0xffffffffffffff80LLU >> 61LLU; + ctx.Nl = 0xfffffffffffffc00LLU; #else - /* cryb counts bytes and multiplies at the end */ - ctx.total[0] = 0xffffffffffffff80LLU; + ctx.bitlen[1] = 0xfffffffffffffc00LLU; #endif sha512_update(&ctx, t_seq8, 256); sha512_final(&ctx, digest);