Major cleanup of the MD and SHA digests.

- Use the new vector byte-order conversion functions where appropriate.
- Use memset_s() instead of memset() where appropriate.
- Use consistent names and types for function arguments.
- Reindent, rename and reorganize to conform to Cryb style and idiom.

SHA224 and SHA256 were left mostly unchanged.  MD2 and MD4 were completely rewritten as the previous versions (taken from XySSL) seem to have been copied from RSAREF.

This breaks the ABI as some context structures have grown or shrunk and some function arguments have been changed from int to size_t.
This commit is contained in:
Dag-Erling Smørgrav 2017-03-20 00:13:47 +01:00
parent d96415b2c3
commit c6536641c5
18 changed files with 936 additions and 1392 deletions

View file

@ -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

View file

@ -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

View file

@ -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 *);

View file

@ -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 *);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 <stdint.h>
#include <string.h>
#include <cryb/memset_s.h>
#include <cryb/md2.h>
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 = {

View file

@ -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 <stdint.h>
#include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/md4.h>
/*
* 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 = {

View file

@ -35,30 +35,36 @@
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/md5.h>
/*
* 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

View file

@ -35,6 +35,8 @@
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha1.h>
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

View file

@ -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 <stdint.h>
#include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha224.h>
/*
* 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),

View file

@ -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 <stdint.h>
#include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha256.h>
/*
* 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),

View file

@ -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 <stdint.h>
#include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha384.h>
/*
* 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 = {

View file

@ -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 <stdint.h>
#include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha512.h>
/*
* 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 = {

View file

@ -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);

View file

@ -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);