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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -50,49 +50,17 @@ CRYB_BEGIN
extern digest_algorithm md2_digest; extern digest_algorithm md2_digest;
/** typedef struct {
* \brief MD2 context structure uint8_t state[48];
*/ uint8_t cksum[16];
typedef struct uint8_t block[16];
{ unsigned int blocklen;
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 */
} md2_ctx; } md2_ctx;
/** void md2_init(md2_ctx *);
* \brief MD2 context setup void md2_update(md2_ctx *, const void *, size_t);
* void md2_final(md2_ctx *, uint8_t *);
* \param ctx context to be initialized void md2_complete(const void *, size_t, uint8_t *);
*/
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 );
CRYB_END 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -50,57 +50,17 @@ CRYB_BEGIN
extern digest_algorithm md4_digest; extern digest_algorithm md4_digest;
/** typedef struct {
* \brief MD4 context structure uint8_t block[64];
*/ size_t blocklen;
typedef struct uint32_t state[4];
{ uint64_t bitlen;
uint64_t total; /*!< number of bytes processed */ } md4_ctx;
uint32_t state[4]; /*!< intermediate digest state */
uint8_t buffer[64]; /*!< data block being processed */
}
md4_ctx;
#ifdef __cplusplus void md4_init(md4_ctx *);
extern "C" { void md4_update(md4_ctx *, const void *, size_t);
#endif void md4_final(md4_ctx *, uint8_t *);
void md4_complete(const void *, size_t, uint8_t *);
/**
* \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
CRYB_END CRYB_END

View file

@ -54,8 +54,8 @@ extern digest_algorithm md5_digest;
typedef struct { typedef struct {
uint8_t block[64]; uint8_t block[64];
size_t blocklen; size_t blocklen;
uint32_t state[4];
uint64_t bitlen; uint64_t bitlen;
uint32_t h[4];
} md5_ctx; } md5_ctx;
void md5_init(md5_ctx *); void md5_init(md5_ctx *);

View file

@ -53,7 +53,7 @@ extern digest_algorithm sha1_digest;
typedef struct { typedef struct {
uint8_t block[64]; uint8_t block[64];
uint32_t blocklen; unsigned int blocklen;
uint32_t h[5]; uint32_t h[5];
uint64_t bitlen; uint64_t bitlen;
} sha1_ctx; } sha1_ctx;

View file

@ -1,5 +1,6 @@
/*- /*-
* Copyright (c) 2005-2013 Colin Percival * Copyright (c) 2005-2013 Colin Percival
* Copyright (c) 2014-2017 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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 * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@ -38,10 +42,6 @@ CRYB_BEGIN
#define SHA224_BLOCK_LEN 64 #define SHA224_BLOCK_LEN 64
#define SHA224_DIGEST_LEN 28 #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_digest cryb_sha224_digest
#define sha224_ctx cryb_sha224_ctx #define sha224_ctx cryb_sha224_ctx
#define sha224_init cryb_sha224_init #define sha224_init cryb_sha224_init
@ -51,46 +51,17 @@ CRYB_BEGIN
extern digest_algorithm sha224_digest; extern digest_algorithm sha224_digest;
/* Context structure for SHA224 operations. */
typedef struct { typedef struct {
uint32_t state[8]; uint32_t state[8];
uint64_t count; uint64_t count;
uint8_t buf[64]; uint8_t buf[64];
} sha224_ctx; } sha224_ctx;
/**
* sha224_init(ctx):
* Initialize the SHA224 context ${ctx}.
*/
void sha224_init(sha224_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); 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 *); 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 *); 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 CRYB_END
#endif #endif

View file

@ -1,5 +1,6 @@
/*- /*-
* Copyright (c) 2005-2013 Colin Percival * Copyright (c) 2005-2013 Colin Percival
* Copyright (c) 2014-2017 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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 * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@ -38,10 +42,6 @@ CRYB_BEGIN
#define SHA256_BLOCK_LEN 64 #define SHA256_BLOCK_LEN 64
#define SHA256_DIGEST_LEN 32 #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_digest cryb_sha256_digest
#define sha256_ctx cryb_sha256_ctx #define sha256_ctx cryb_sha256_ctx
#define sha256_init cryb_sha256_init #define sha256_init cryb_sha256_init
@ -51,46 +51,17 @@ CRYB_BEGIN
extern digest_algorithm sha256_digest; extern digest_algorithm sha256_digest;
/* Context structure for SHA256 operations. */
typedef struct { typedef struct {
uint32_t state[8]; uint32_t state[8];
uint64_t count; uint64_t count;
uint8_t buf[64]; uint8_t buf[64];
} sha256_ctx; } sha256_ctx;
/**
* sha256_init(ctx):
* Initialize the SHA256 context ${ctx}.
*/
void sha256_init(sha256_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); 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 *); 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 *); 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 CRYB_END
#endif #endif

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2006-2007 Christophe Devine * Copyright (c) 2006-2007 Christophe Devine
* Copyright (c) 2017 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -50,49 +51,17 @@ CRYB_BEGIN
extern digest_algorithm sha384_digest; extern digest_algorithm sha384_digest;
/** typedef struct {
* \brief SHA-384 context structure uint8_t block[128];
*/ unsigned int blocklen;
typedef struct uint64_t h[8];
{ uint64_t bitlen[2];
uint64_t total[2]; /*!< number of bytes processed */ } sha384_ctx;
uint64_t state[8]; /*!< intermediate digest state */
uint8_t buffer[128]; /*!< data block being processed */
}
sha384_ctx;
/** void sha384_init(sha384_ctx *);
* \brief SHA-384 context setup void sha384_update(sha384_ctx *, const void *, size_t);
* void sha384_final(sha384_ctx *, uint8_t *);
* \param ctx context to be initialized void sha384_complete(const void *, size_t, uint8_t *);
*/
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 );
CRYB_END CRYB_END

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2006-2007 Christophe Devine * Copyright (c) 2006-2007 Christophe Devine
* Copyright (c) 2017 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -50,49 +51,17 @@ CRYB_BEGIN
extern digest_algorithm sha512_digest; extern digest_algorithm sha512_digest;
/** typedef struct {
* \brief SHA-512 context structure uint8_t block[128];
*/ unsigned int blocklen;
typedef struct uint64_t h[8];
{ uint64_t bitlen[2];
uint64_t total[2]; /*!< number of bytes processed */ } sha512_ctx;
uint64_t state[8]; /*!< intermediate digest state */
uint8_t buffer[128]; /*!< data block being processed */
}
sha512_ctx;
/** void sha512_init(sha512_ctx *);
* \brief SHA-512 context setup void sha512_update(sha512_ctx *, const void *, size_t);
* void sha512_final(sha512_ctx *, uint8_t *);
* \param ctx context to be initialized void sha512_complete(const void *, size_t, uint8_t *);
*/
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 );
CRYB_END 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 "cryb/impl.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <cryb/memset_s.h>
#include <cryb/md2.h> #include <cryb/md2.h>
static const uint8_t PI_SUBST[256] = /*
{ * MD2 - RFC 1319
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, *
0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, * Note 1: the pseudocode for the checksum calculation in the RFC contains
0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, * a significant error - consult the errata.
0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, *
0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, * Note 2: the RFC describes the algorithm as having five steps: 1) append
0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, * padding, 2) compute checksum, 3) initialize state, 4) compute digest
0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, * and 5) output. This implementation merges the checksum and digest
0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, * computations, which are independent of eachother, which avoids
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, * processing the message twice. The padding is then appended and fed
0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, * through the checksum and digest computation, and finally the checksum
0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, * itself is fed through. Note that we update the checksum *after* the
0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, * digest, otherwise the final step (mixing the checksum into the digest)
0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, * would clobber the checksum before it was used.
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, static const uint8_t md2_s[256] = {
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0x29, 0x2e, 0x43, 0xc9, 0xa2, 0xd8, 0x7c, 0x01,
0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, 0x3d, 0x36, 0x54, 0xa1, 0xec, 0xf0, 0x06, 0x13,
0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x62, 0xa7, 0x05, 0xf3, 0xc0, 0xc7, 0x73, 0x8c,
0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x98, 0x93, 0x2b, 0xd9, 0xbc, 0x4c, 0x82, 0xca,
0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, 0x1e, 0x9b, 0x57, 0x3c, 0xfd, 0xd4, 0xe0, 0x16,
0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x67, 0x42, 0x6f, 0x18, 0x8a, 0x17, 0xe5, 0x12,
0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xbe, 0x4e, 0xc4, 0xd6, 0xda, 0x9e, 0xde, 0x49,
0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, 0xa0, 0xfb, 0xf5, 0x8e, 0xbb, 0x2f, 0xee, 0x7a,
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0xa9, 0x68, 0x79, 0x91, 0x15, 0xb2, 0x07, 0x3f,
0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 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,
}; };
/* void
* MD2 context setup 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; unsigned int j, k;
uint8_t t = 0; uint8_t l, t;
for( i = 0; i < 16; i++ ) for (j = 0; j < 16; j++) {
{ ctx->state[j + 16] = block[j];
ctx->state[i + 16] = ctx->buffer[i]; ctx->state[j + 32] = block[j] ^ ctx->state[j];
ctx->state[i + 32] =
(uint8_t)( ctx->buffer[i] ^ ctx->state[i]);
} }
t = 0;
for( i = 0; i < 18; i++ ) for (j = 0; j < 18; ++j) {
{ for (k = 0; k < 48; ++k) {
for( j = 0; j < 48; j++ ) ctx->state[k] = ctx->state[k] ^ md2_s[t];
{ t = ctx->state[k];
ctx->state[j] = (uint8_t)
( ctx->state[j] ^ PI_SUBST[t] );
t = ctx->state[j];
} }
t = t + j;
t = (uint8_t)( t + i );
} }
l = ctx->cksum[15];
t = ctx->cksum[15]; for (j = 0; j < 16; ++j) {
ctx->cksum[j] ^= md2_s[block[j] ^ l];
for( i = 0; i < 16; i++ ) l = ctx->cksum[j];
{
ctx->cksum[i] = (uint8_t)
( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
t = ctx->cksum[i];
} }
} }
/* void
* MD2 process buffer md2_update(md2_ctx *ctx, const void *buf, size_t len)
*/
void md2_update( md2_ctx *ctx, const void *input, int ilen )
{ {
int fill; size_t copylen;
while( ilen > 0 ) while (len) {
{ if (ctx->blocklen > 0 || len < sizeof ctx->block) {
if( ctx->left + ilen > 16 ) copylen = sizeof ctx->block - ctx->blocklen;
fill = 16 - ctx->left; if (copylen > len)
else copylen = len;
fill = ilen; memcpy(ctx->block + ctx->blocklen, buf, copylen);
ctx->blocklen += copylen;
memcpy( ctx->buffer + ctx->left, input, fill ); if (ctx->blocklen == sizeof ctx->block) {
md2_compute(ctx, ctx->block);
ctx->left += fill; ctx->blocklen = 0;
input += fill; }
ilen -= fill; } else {
copylen = sizeof ctx->block;
if( ctx->left == 16 ) md2_compute(ctx, buf);
{ }
ctx->left = 0; buf += copylen;
md2_process( ctx ); len -= copylen;
}
} }
} }
/* void
* MD2 final digest md2_final(md2_ctx *ctx, uint8_t *digest)
*/
void md2_final( md2_ctx *ctx, uint8_t *output )
{ {
int i; unsigned int i;
uint8_t x; uint8_t x;
x = (uint8_t)( 16 - ctx->left ); x = sizeof ctx->block - ctx->blocklen;
for (i = ctx->blocklen; i < sizeof ctx->block; i++)
for( i = ctx->left; i < 16; i++ ) ctx->block[i] = x;
ctx->buffer[i] = x; md2_compute(ctx, ctx->block);
md2_compute(ctx, ctx->cksum);
md2_process( ctx ); memcpy(digest, ctx->state, MD2_DIGEST_LEN);
memset_s(&ctx, 0, sizeof ctx, sizeof ctx);
memcpy( ctx->buffer, ctx->cksum, sizeof ctx->cksum );
md2_process( ctx );
memcpy( output, ctx->state, MD2_DIGEST_LEN );
} }
/* void md2_complete(const void *buf, size_t len, uint8_t *digest)
* output = MD2( input buffer )
*/
void md2_complete( const void *input, int ilen, uint8_t *output )
{ {
md2_ctx ctx; md2_ctx ctx;
md2_init(&ctx); md2_init(&ctx);
md2_update( &ctx, input, ilen ); md2_update(&ctx, buf, len);
md2_final( &ctx, output ); md2_final(&ctx, digest);
memset( &ctx, 0, sizeof( md2_ctx ) );
} }
digest_algorithm md2_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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -26,130 +26,110 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 "cryb/impl.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h> #include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/md4.h> #include <cryb/md4.h>
/* /*
* MD4 context setup * MD4 - RFC 1320
*/ */
void md4_init( md4_ctx *ctx )
{
ctx->total = 0;
ctx->state[0] = 0x67452301; /* initial state */
ctx->state[1] = 0xEFCDAB89; static const uint32_t md4_h[4] = {
ctx->state[2] = 0x98BADCFE; 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL,
ctx->state[3] = 0x10325476; };
void
md4_init(md4_ctx *ctx)
{
memset(ctx, 0, sizeof *ctx);
memcpy(ctx->state, md4_h, sizeof ctx->state);
} }
static void md4_process( md4_ctx *ctx, const uint8_t *data ) static void
md4_compute(md4_ctx *ctx, const uint8_t *data)
{ {
uint32_t X[16], A, B, C, D; uint32_t X[16];
uint32_t A, B, C, D;
X[ 0] = le32dec(data + 0); le32decv(X, data, 16);
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]; A = ctx->state[0];
B = ctx->state[1]; B = ctx->state[1];
C = ctx->state[2]; C = ctx->state[2];
D = ctx->state[3]; D = ctx->state[3];
#define F(x, y, z) ((x & y) | ((~x) & z)) #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); } #define md4_round1(a, b, c, d, k, s) \
a = rol32(a + F(b, c, d) + X[k], s)
P( A, B, C, D, X[ 0], 3 ); #define G(x, y, z) (x & y | x & z | y & z)
P( D, A, B, C, X[ 1], 7 ); #define md4_round2(a, b, c, d, k, s) \
P( C, D, A, B, X[ 2], 11 ); a = rol32(a + G(b, c, d) + X[k] + 0x5a827999, s)
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 #define H(x, y, z) (x ^ y ^ z)
#undef F #define md4_round3(a, b, c, d, k, s) \
a = rol32(a + H(b,c,d) + X[k] + 0x6ed9eba1, s)
#define F(x,y,z) ((x & y) | (x & z) | (y & z)) md4_round1(A, B, C, D, 0, 3);
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } 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);
P( A, B, C, D, X[ 0], 3 ); md4_round2(A, B, C, D, 0, 3);
P( D, A, B, C, X[ 4], 5 ); md4_round2(D, A, B, C, 4, 5);
P( C, D, A, B, X[ 8], 9 ); md4_round2(C, D, A, B, 8, 9);
P( B, C, D, A, X[12], 13 ); md4_round2(B, C, D, A, 12, 13);
P( A, B, C, D, X[ 1], 3 ); md4_round2(A, B, C, D, 1, 3);
P( D, A, B, C, X[ 5], 5 ); md4_round2(D, A, B, C, 5, 5);
P( C, D, A, B, X[ 9], 9 ); md4_round2(C, D, A, B, 9, 9);
P( B, C, D, A, X[13], 13 ); md4_round2(B, C, D, A, 13, 13);
P( A, B, C, D, X[ 2], 3 ); md4_round2(A, B, C, D, 2, 3);
P( D, A, B, C, X[ 6], 5 ); md4_round2(D, A, B, C, 6, 5);
P( C, D, A, B, X[10], 9 ); md4_round2(C, D, A, B, 10, 9);
P( B, C, D, A, X[14], 13 ); md4_round2(B, C, D, A, 14, 13);
P( A, B, C, D, X[ 3], 3 ); md4_round2(A, B, C, D, 3, 3);
P( D, A, B, C, X[ 7], 5 ); md4_round2(D, A, B, C, 7, 5);
P( C, D, A, B, X[11], 9 ); md4_round2(C, D, A, B, 11, 9);
P( B, C, D, A, X[15], 13 ); md4_round2(B, C, D, A, 15, 13);
#undef P md4_round3(A, B, C, D, 0, 3);
#undef F md4_round3(D, A, B, C, 8, 9);
md4_round3(C, D, A, B, 4, 11);
#define F(x,y,z) (x ^ y ^ z) md4_round3(B, C, D, A, 12, 15);
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } md4_round3(A, B, C, D, 2, 3);
md4_round3(D, A, B, C, 10, 9);
P( A, B, C, D, X[ 0], 3 ); md4_round3(C, D, A, B, 6, 11);
P( D, A, B, C, X[ 8], 9 ); md4_round3(B, C, D, A, 14, 15);
P( C, D, A, B, X[ 4], 11 ); md4_round3(A, B, C, D, 1, 3);
P( B, C, D, A, X[12], 15 ); md4_round3(D, A, B, C, 9, 9);
P( A, B, C, D, X[ 2], 3 ); md4_round3(C, D, A, B, 5, 11);
P( D, A, B, C, X[10], 9 ); md4_round3(B, C, D, A, 13, 15);
P( C, D, A, B, X[ 6], 11 ); md4_round3(A, B, C, D, 3, 3);
P( B, C, D, A, X[14], 15 ); md4_round3(D, A, B, C, 11, 9);
P( A, B, C, D, X[ 1], 3 ); md4_round3(C, D, A, B, 7, 11);
P( D, A, B, C, X[ 9], 9 ); md4_round3(B, C, D, A, 15, 15);
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[0] += A;
ctx->state[1] += B; ctx->state[1] += B;
@ -157,86 +137,58 @@ static void md4_process( md4_ctx *ctx, const uint8_t *data )
ctx->state[3] += D; ctx->state[3] += D;
} }
/* void
* MD4 process buffer md4_update(md4_ctx *ctx, const void *buf, size_t len)
*/
void md4_update( md4_ctx *ctx, const void *input, int ilen )
{ {
int fill; size_t copylen;
uint32_t left;
if( ilen <= 0 ) while (len) {
return; if (ctx->blocklen > 0 || len < sizeof ctx->block) {
copylen = sizeof ctx->block - ctx->blocklen;
left = ctx->total & 0x3F; if (copylen > len)
fill = 64 - left; copylen = len;
memcpy(ctx->block + ctx->blocklen, buf, copylen);
ctx->total += ilen; ctx->blocklen += copylen;
if (ctx->blocklen == sizeof ctx->block) {
if( left && ilen >= fill ) md4_compute(ctx, ctx->block);
{ ctx->blocklen = 0;
memcpy( (ctx->buffer + left), input, fill );
md4_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
} }
} else {
while( ilen >= 64 ) copylen = sizeof ctx->block;
{ md4_compute(ctx, buf);
md4_process( ctx, input );
input += 64;
ilen -= 64;
} }
ctx->bitlen += copylen * 8;
if( ilen > 0 ) buf += copylen;
{ len -= copylen;
memcpy( (ctx->buffer + left), input, ilen );
} }
} }
static const uint8_t md4_padding[64] = void
md4_final(md4_ctx *ctx, uint8_t *digest)
{ {
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
};
/* ctx->block[ctx->blocklen++] = 0x80;
* MD4 final digest memset(ctx->block + ctx->blocklen, 0,
*/ sizeof ctx->block - ctx->blocklen);
void md4_final( md4_ctx *ctx, uint8_t *output ) if (ctx->blocklen > 56) {
{ md4_compute(ctx, ctx->block);
uint32_t last, padn; ctx->blocklen = 0;
uint8_t msglen[8]; memset(ctx->block, 0, sizeof ctx->block);
}
le64enc(msglen, ctx->total << 3); le64enc(ctx->block + 56, ctx->bitlen);
md4_compute(ctx, ctx->block);
last = ctx->total & 0x3F; le32encv(digest, ctx->state, 4);
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); memset_s(ctx, 0, sizeof *ctx, sizeof *ctx);
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]);
} }
/* void
* output = MD4( input buffer ) md4_complete(const void *buf, size_t len, uint8_t *digest)
*/
void md4_complete( const void *input, int ilen, uint8_t *output )
{ {
md4_ctx ctx; md4_ctx ctx;
md4_init(&ctx); md4_init(&ctx);
md4_update( &ctx, input, ilen ); md4_update(&ctx, buf, len);
md4_final( &ctx, output ); md4_final(&ctx, digest);
memset( &ctx, 0, sizeof( md4_ctx ) );
} }
digest_algorithm md4_digest = { digest_algorithm md4_digest = {

View file

@ -35,30 +35,36 @@
#include <cryb/bitwise.h> #include <cryb/bitwise.h>
#include <cryb/endian.h> #include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/md5.h> #include <cryb/md5.h>
/*
* MD5 - RFC 1321
*/
/* initial state */ /* initial state */
static const uint32_t md5_h[4] = { static const uint32_t md5_h[4] = {
0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL,
}; };
static const uint32_t md5_k[64] = { static const uint32_t md5_k[64] = {
0xd76aa478U, 0xe8c7b756U, 0x242070dbU, 0xc1bdceeeU, 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL,
0xf57c0fafU, 0x4787c62aU, 0xa8304613U, 0xfd469501U, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
0x698098d8U, 0x8b44f7afU, 0xffff5bb1U, 0x895cd7beU, 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL,
0x6b901122U, 0xfd987193U, 0xa679438eU, 0x49b40821U, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
0xf61e2562U, 0xc040b340U, 0x265e5a51U, 0xe9b6c7aaU, 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL,
0xd62f105dU, 0x02441453U, 0xd8a1e681U, 0xe7d3fbc8U, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
0x21e1cde6U, 0xc33707d6U, 0xf4d50d87U, 0x455a14edU, 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL,
0xa9e3e905U, 0xfcefa3f8U, 0x676f02d9U, 0x8d2a4c8aU, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
0xfffa3942U, 0x8771f681U, 0x6d9d6122U, 0xfde5380cU, 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL,
0xa4beea44U, 0x4bdecfa9U, 0xf6bb4b60U, 0xbebfbc70U, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
0x289b7ec6U, 0xeaa127faU, 0xd4ef3085U, 0x04881d05U, 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL,
0xd9d4d039U, 0xe6db99e5U, 0x1fa27cf8U, 0xc4ac5665U, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
0xf4292244U, 0x432aff97U, 0xab9423a7U, 0xfc93a039U, 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL,
0x655b59c3U, 0x8f0ccc92U, 0xffeff47dU, 0x85845dd1U, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
0x6fa87e4fU, 0xfe2ce6e0U, 0xa3014314U, 0x4e0811a1U, 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL,
0xf7537e82U, 0xbd3af235U, 0x2ad7d2bbU, 0xeb86d391U, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL,
}; };
void void
@ -66,7 +72,7 @@ md5_init(md5_ctx *ctx)
{ {
memset(ctx, 0, sizeof *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 { \ #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; uint32_t w[16], a, b, c, d;
memcpy(w, block, 64); le32decv(w, block, 16);
for (int i = 0; i < 16; ++i) a = ctx->state[0];
w[i] = le32toh(w[i]); b = ctx->state[1];
a = ctx->h[0]; c = ctx->state[2];
b = ctx->h[1]; d = ctx->state[3];
c = ctx->h[2];
d = ctx->h[3];
md5_f( 0, a, b, c, d, w, 7); md5_f( 0, a, b, c, d, w, 7);
md5_f( 1, d, a, b, c, w, 12); 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(62, c, d, a, b, w, 15);
md5_i(63, b, c, d, a, w, 21); md5_i(63, b, c, d, a, w, 21);
ctx->h[0] += a; ctx->state[0] += a;
ctx->h[1] += b; ctx->state[1] += b;
ctx->h[2] += c; ctx->state[2] += c;
ctx->h[3] += d; ctx->state[3] += d;
} }
void void
@ -195,7 +199,6 @@ md5_update(md5_ctx *ctx, const void *buf, size_t len)
if (ctx->blocklen == sizeof ctx->block) { if (ctx->blocklen == sizeof ctx->block) {
md5_compute(ctx, ctx->block); md5_compute(ctx, ctx->block);
ctx->blocklen = 0; ctx->blocklen = 0;
memset(ctx->block, 0, sizeof ctx->block);
} }
} else { } else {
copylen = sizeof ctx->block; copylen = sizeof ctx->block;
@ -212,19 +215,17 @@ md5_final(md5_ctx *ctx, uint8_t *digest)
{ {
ctx->block[ctx->blocklen++] = 0x80; ctx->block[ctx->blocklen++] = 0x80;
memset(ctx->block + ctx->blocklen, 0,
sizeof ctx->block - ctx->blocklen);
if (ctx->blocklen > 56) { if (ctx->blocklen > 56) {
md5_compute(ctx, ctx->block); md5_compute(ctx, ctx->block);
ctx->blocklen = 0; ctx->blocklen = 0;
memset(ctx->block, 0, sizeof ctx->block); memset(ctx->block, 0, sizeof ctx->block);
} }
le32enc(ctx->block + 56, ctx->bitlen & 0xffffffffUL); le64enc(ctx->block + 56, ctx->bitlen);
le32enc(ctx->block + 60, ctx->bitlen >> 32);
md5_compute(ctx, ctx->block); md5_compute(ctx, ctx->block);
le32enc(digest, ctx->h[0]); le32encv(digest, ctx->state, 4);
le32enc(digest + 4, ctx->h[1]); memset_s(ctx, 0, sizeof *ctx, sizeof *ctx);
le32enc(digest + 8, ctx->h[2]);
le32enc(digest + 12, ctx->h[3]);
memset(ctx, 0, sizeof *ctx);
} }
void void

View file

@ -35,6 +35,8 @@
#include <cryb/bitwise.h> #include <cryb/bitwise.h>
#include <cryb/endian.h> #include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha1.h> #include <cryb/sha1.h>
static uint32_t sha1_h[5] = { static uint32_t sha1_h[5] = {
@ -70,11 +72,10 @@ static void
sha1_compute(sha1_ctx *ctx, const uint8_t *block) sha1_compute(sha1_ctx *ctx, const uint8_t *block)
{ {
uint32_t w[80], a, b, c, d, e; uint32_t w[80], a, b, c, d, e;
unsigned int i;
memcpy(w, block, 64); be32decv(w, block, 16);
for (int i = 0; i < 16; ++i) for (i = 16; i < 80; ++i) {
w[i] = be32toh(w[i]);
for (int i = 16; i < 80; ++i) {
w[i] = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]; w[i] = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
w[i] = rol32(w[i], 1); 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) { if (ctx->blocklen == sizeof ctx->block) {
sha1_compute(ctx, ctx->block); sha1_compute(ctx, ctx->block);
ctx->blocklen = 0; ctx->blocklen = 0;
memset(ctx->block, 0, sizeof ctx->block);
} }
} else { } else {
copylen = sizeof ctx->block; copylen = sizeof ctx->block;
@ -205,24 +205,19 @@ sha1_update(sha1_ctx *ctx, const void *buf, size_t len)
void void
sha1_final(sha1_ctx *ctx, uint8_t *digest) sha1_final(sha1_ctx *ctx, uint8_t *digest)
{ {
uint32_t hi, lo;
ctx->block[ctx->blocklen++] = 0x80; ctx->block[ctx->blocklen++] = 0x80;
memset(ctx->block + ctx->blocklen, 0,
sizeof ctx->block - ctx->blocklen);
if (ctx->blocklen > 56) { if (ctx->blocklen > 56) {
sha1_compute(ctx, ctx->block); sha1_compute(ctx, ctx->block);
ctx->blocklen = 0; ctx->blocklen = 0;
memset(ctx->block, 0, sizeof ctx->block); memset(ctx->block, 0, sizeof ctx->block);
} }
hi = htobe32(ctx->bitlen >> 32); be64enc(ctx->block + 56, ctx->bitlen);
lo = htobe32(ctx->bitlen & 0xffffffffUL);
memcpy(ctx->block + 56, &hi, 4);
memcpy(ctx->block + 60, &lo, 4);
ctx->blocklen = 64;
sha1_compute(ctx, ctx->block); sha1_compute(ctx, ctx->block);
for (int i = 0; i < 5; ++i) be32encv(digest, ctx->h, 5);
ctx->h[i] = htobe32(ctx->h[i]); memset_s(ctx, 0, sizeof *ctx, sizeof *ctx);
memcpy(digest, ctx->h, 20);
memset(ctx, 0, sizeof *ctx);
} }
void void

View file

@ -1,5 +1,6 @@
/*- /*-
* Copyright (c) 2005-2013 Colin Percival * Copyright (c) 2005-2013 Colin Percival
* Copyright (c) 2017 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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 * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@ -29,44 +33,20 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h> #include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha224.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 */ /* Elementary functions used by SHA224 */
#define Ch(x, y, z) ((x & (y ^ z)) ^ z) #define Ch(x, y, z) ((x & (y ^ z)) ^ z)
#define Maj(x, y, z) ((x & (y | z)) | (y & z)) #define Maj(x, y, z) ((x & (y | z)) | (y & z))
#define SHR(x, n) (x >> n) #define SHR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << (32 - n))) #define S0(x) (ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22))
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) #define S1(x) (ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25))
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) #define s0(x) (ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3))
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) #define s1(x) (ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10))
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
/* SHA224 round function */ /* SHA224 round function */
#define RND(a, b, c, d, e, f, g, h, k) \ #define RND(a, b, c, d, e, f, g, h, k) \
@ -96,7 +76,7 @@ sha224_Transform(uint32_t * state, const uint8_t block[64])
int i; int i;
/* 1. Prepare message schedule W. */ /* 1. Prepare message schedule W. */
be32dec_vect(W, block, 64); be32decv(W, block, 16);
for (i = 16; i < 64; i++) for (i = 16; i < 64; i++)
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
@ -172,18 +152,17 @@ sha224_Transform(uint32_t * state, const uint8_t block[64])
/* 4. Mix local working variables into global state. */ /* 4. Mix local working variables into global state. */
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
state[i] += S[i]; state[i] += S[i];
/* Clean the stack. */
memset(W, 0, 256);
memset(S, 0, 32);
t0 = t1 = 0;
} }
static uint8_t PAD[64] = { static uint8_t PAD[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 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. */ /* Add padding and terminating bit-count. */
@ -286,10 +265,10 @@ sha224_final(sha224_ctx * ctx, uint8_t *digest)
sha224_pad(ctx); sha224_pad(ctx);
/* Write the hash. */ /* Write the hash. */
be32enc_vect(digest, ctx->state, SHA224_DIGEST_LEN); be32encv(digest, ctx->state, SHA224_DIGEST_LEN / 4);
/* Clear the context state. */ /* Clear the context state. */
memset(ctx, 0, sizeof(*ctx)); memset_s(ctx, 0, sizeof *ctx, sizeof *ctx);
} }
/** /**
@ -306,65 +285,6 @@ sha224_complete(const void * in, size_t len, uint8_t *digest)
sha224_final(&ctx, 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 = { digest_algorithm sha224_digest = {
.name = "sha224", .name = "sha224",
.contextlen = sizeof(sha224_ctx), .contextlen = sizeof(sha224_ctx),

View file

@ -1,5 +1,6 @@
/*- /*-
* Copyright (c) 2005-2013 Colin Percival * Copyright (c) 2005-2013 Colin Percival
* Copyright (c) 2017 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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 * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@ -29,44 +33,19 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h> #include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha256.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 */ /* Elementary functions used by SHA256 */
#define Ch(x, y, z) ((x & (y ^ z)) ^ z) #define Ch(x, y, z) ((x & (y ^ z)) ^ z)
#define Maj(x, y, z) ((x & (y | z)) | (y & z)) #define Maj(x, y, z) ((x & (y | z)) | (y & z))
#define SHR(x, n) (x >> n) #define S0(x) (ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22))
#define ROTR(x, n) ((x >> n) | (x << (32 - n))) #define S1(x) (ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25))
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) #define s0(x) (ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3))
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) #define s1(x) (ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10))
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
/* SHA256 round function */ /* SHA256 round function */
#define RND(a, b, c, d, e, f, g, h, k) \ #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; int i;
/* 1. Prepare message schedule W. */ /* 1. Prepare message schedule W. */
be32dec_vect(W, block, 64); be32decv(W, block, 16);
for (i = 16; i < 64; i++) for (i = 16; i < 64; i++)
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
@ -172,18 +151,17 @@ sha256_Transform(uint32_t * state, const uint8_t block[64])
/* 4. Mix local working variables into global state. */ /* 4. Mix local working variables into global state. */
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
state[i] += S[i]; state[i] += S[i];
/* Clean the stack. */
memset(W, 0, 256);
memset(S, 0, 32);
t0 = t1 = 0;
} }
static uint8_t PAD[64] = { static uint8_t PAD[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 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. */ /* Add padding and terminating bit-count. */
@ -286,10 +264,10 @@ sha256_final(sha256_ctx * ctx, uint8_t *digest)
sha256_pad(ctx); sha256_pad(ctx);
/* Write the hash. */ /* Write the hash. */
be32enc_vect(digest, ctx->state, SHA256_DIGEST_LEN); be32encv(digest, ctx->state, SHA256_DIGEST_LEN / 4);
/* Clear the context state. */ /* Clear the context state. */
memset(ctx, 0, sizeof(*ctx)); memset_s(ctx, 0, sizeof *ctx, sizeof *ctx);
} }
/** /**
@ -306,65 +284,6 @@ sha256_complete(const void * in, size_t len, uint8_t *digest)
sha256_final(&ctx, 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 = { digest_algorithm sha256_digest = {
.name = "sha256", .name = "sha256",
.contextlen = sizeof(sha256_ctx), .contextlen = sizeof(sha256_ctx),

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2006-2007 Christophe Devine * Copyright (c) 2006-2007 Christophe Devine
* Copyright (c) 2017 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 "cryb/impl.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha384.h> #include <cryb/sha384.h>
/* static const uint64_t sha384_h[8] = {
* 64-bit integer manipulation macros (big endian) 0xCBBB9D5DC1059ED8ULL, 0x629A292A367CD507ULL,
*/ 0x9159015A3070DD17ULL, 0x152FECD8F70E5939ULL,
#ifndef GET_UINT64_BE 0x67332667FFC00B31ULL, 0x8EB44A8768581511ULL,
#define GET_UINT64_BE(n,b,i) \ 0xDB0C2E0D64F98FA7ULL, 0x47B5481DBEFA4FA4ULL,
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_k[80] = {
* SHA-384 context setup 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
*/ 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
void sha384_init( sha384_ctx *ctx ) 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
{ 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
ctx->total[0] = 0; 0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
ctx->total[1] = 0; 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,
};
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); void
ctx->state[1] = UL64(0x629A292A367CD507); sha384_init(sha384_ctx *ctx)
ctx->state[2] = UL64(0x9159015A3070DD17); {
ctx->state[3] = UL64(0x152FECD8F70E5939);
ctx->state[4] = UL64(0x67332667FFC00B31); memset(ctx, 0, sizeof *ctx);
ctx->state[5] = UL64(0x8EB44A8768581511); memcpy(ctx->h, sha384_h, sizeof ctx->h);
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
} }
static void sha384_process( sha384_ctx *ctx, const uint8_t *data ) #define S0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
{ #define S1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6))
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 S2(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39))
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) #define S3(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41))
#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 F0(x, y, z) ((x & y) | (z & (x | y)))
#define F1(x, y, z) (z ^ (x & (y ^ z))) #define F1(x, y, z) (z ^ (x & (y ^ z)))
#define P(a,b,c,d,e,f,g,h,x,K) \ #define P(i, a, b, c, d, e, f, g, h) do { \
{ \ uint64_t t0, t1; \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \ t0 = h + S3(e) + F1(e, f, g) + sha384_k[i] + w[i]; \
temp2 = S2(a) + F0(a,b,c); \ t1 = S2(a) + F0(a, b, c); \
d += temp1; h = temp1 + temp2; \ d += t0; h = t0 + t1; \
} } while (0)
for( i = 0; i < 16; i++ ) static void
sha384_compute(sha384_ctx *ctx, const uint8_t *data)
{ {
GET_UINT64_BE( W[i], data, i << 3 ); uint64_t w[80], A, B, C, D, E, F, G, H;
unsigned int i;
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];
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;
} }
for( ; i < 80; i++ ) void
sha384_update(sha384_ctx *ctx, const void *buf, size_t len)
{ {
W[i] = S1(W[i - 2]) + W[i - 7] + size_t copylen;
S0(W[i - 15]) + W[i - 16];
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;
}
} }
A = ctx->state[0]; void
B = ctx->state[1]; sha384_final(sha384_ctx *ctx, uint8_t *digest)
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->block[ctx->blocklen++] = 0x80;
ctx->state[1] += B; memset(ctx->block + ctx->blocklen, 0,
ctx->state[2] += C; sizeof ctx->block - ctx->blocklen);
ctx->state[3] += D; if (ctx->blocklen > 112) {
ctx->state[4] += E; sha384_compute(ctx, ctx->block);
ctx->state[5] += F; ctx->blocklen = 0;
ctx->state[6] += G; memset(ctx->block, 0, sizeof ctx->block);
ctx->state[7] += H; }
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
* SHA-384 process buffer sha384_complete(const void *buf, size_t len, uint8_t *digest)
*/
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
};
/*
* SHA-384 final digest
*/
void sha384_final( sha384_ctx *ctx, uint8_t *output )
{
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 );
}
/*
* output = SHA-384( input buffer )
*/
void sha384_complete( const void *input, int ilen, uint8_t *output )
{ {
sha384_ctx ctx; sha384_ctx ctx;
sha384_init(&ctx); sha384_init(&ctx);
sha384_update( &ctx, input, ilen ); sha384_update(&ctx, buf, len);
sha384_final( &ctx, output ); sha384_final(&ctx, digest);
memset( &ctx, 0, sizeof( sha384_ctx ) );
} }
digest_algorithm sha384_digest = { digest_algorithm sha384_digest = {

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2006-2007 Christophe Devine * Copyright (c) 2006-2007 Christophe Devine
* Copyright (c) 2017 Dag-Erling Smørgrav
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 "cryb/impl.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <cryb/bitwise.h>
#include <cryb/endian.h>
#include <cryb/memset_s.h>
#include <cryb/sha512.h> #include <cryb/sha512.h>
/* static const uint64_t sha512_h[8] = {
* 64-bit integer manipulation macros (big endian) 0x6A09E667F3BCC908ULL, 0xBB67AE8584CAA73BULL,
*/ 0x3C6EF372FE94F82BULL, 0xA54FF53A5F1D36F1ULL,
#ifndef GET_UINT64_BE 0x510E527FADE682D1ULL, 0x9B05688C2B3E6C1FULL,
#define GET_UINT64_BE(n,b,i) \ 0x1F83D9ABFB41BD6BULL, 0x5BE0CD19137E2179ULL,
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_k[80] = {
* SHA-512 context setup 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
*/ 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
void sha512_init( sha512_ctx *ctx ) 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
{ 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
ctx->total[0] = 0; 0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
ctx->total[1] = 0; 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,
};
ctx->state[0] = UL64(0x6A09E667F3BCC908); void
ctx->state[1] = UL64(0xBB67AE8584CAA73B); sha512_init(sha512_ctx *ctx)
ctx->state[2] = UL64(0x3C6EF372FE94F82B); {
ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
ctx->state[4] = UL64(0x510E527FADE682D1); memset(ctx, 0, sizeof *ctx);
ctx->state[5] = UL64(0x9B05688C2B3E6C1F); memcpy(ctx->h, sha512_h, sizeof ctx->h);
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
ctx->state[7] = UL64(0x5BE0CD19137E2179);
} }
static void sha512_process( sha512_ctx *ctx, const uint8_t *data ) #define S0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
{ #define S1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6))
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 S2(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39))
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) #define S3(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41))
#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 F0(x, y, z) ((x & y) | (z & (x | y)))
#define F1(x, y, z) (z ^ (x & (y ^ z))) #define F1(x, y, z) (z ^ (x & (y ^ z)))
#define P(a,b,c,d,e,f,g,h,x,K) \ #define P(i, a, b, c, d, e, f, g, h) do { \
{ \ uint64_t t0, t1; \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \ t0 = h + S3(e) + F1(e, f, g) + sha512_k[i] + w[i]; \
temp2 = S2(a) + F0(a,b,c); \ t1 = S2(a) + F0(a, b, c); \
d += temp1; h = temp1 + temp2; \ d += t0; h = t0 + t1; \
} } while (0)
for( i = 0; i < 16; i++ ) static void
sha512_compute(sha512_ctx *ctx, const uint8_t *data)
{ {
GET_UINT64_BE( W[i], data, i << 3 ); uint64_t w[80], A, B, C, D, E, F, G, H;
unsigned int i;
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];
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;
} }
for( ; i < 80; i++ ) void
sha512_update(sha512_ctx *ctx, const void *buf, size_t len)
{ {
W[i] = S1(W[i - 2]) + W[i - 7] + size_t copylen;
S0(W[i - 15]) + W[i - 16];
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;
}
} }
A = ctx->state[0]; void
B = ctx->state[1]; sha512_final(sha512_ctx *ctx, uint8_t *digest)
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->block[ctx->blocklen++] = 0x80;
ctx->state[1] += B; memset(ctx->block + ctx->blocklen, 0,
ctx->state[2] += C; sizeof ctx->block - ctx->blocklen);
ctx->state[3] += D; if (ctx->blocklen > 112) {
ctx->state[4] += E; sha512_compute(ctx, ctx->block);
ctx->state[5] += F; ctx->blocklen = 0;
ctx->state[6] += G; memset(ctx->block, 0, sizeof ctx->block);
ctx->state[7] += H; }
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
* SHA-512 process buffer sha512_complete(const void *buf, size_t len, uint8_t *digest)
*/
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
};
/*
* SHA-512 final digest
*/
void sha512_final( sha512_ctx *ctx, uint8_t *output )
{
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 );
}
/*
* output = SHA-512( input buffer )
*/
void sha512_complete( const void *input, int ilen, uint8_t *output )
{ {
sha512_ctx ctx; sha512_ctx ctx;
sha512_init(&ctx); sha512_init(&ctx);
sha512_update( &ctx, input, ilen ); sha512_update(&ctx, buf, len);
sha512_final( &ctx, output ); sha512_final(&ctx, digest);
memset( &ctx, 0, sizeof( sha512_ctx ) );
} }
digest_algorithm sha512_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; sha384_ctx ctx;
uint8_t digest[SHA384_DIGEST_LEN]; uint8_t digest[SHA384_DIGEST_LEN];
static uint8_t expect[SHA384_DIGEST_LEN] = { static uint8_t expect[SHA384_DIGEST_LEN] = {
0x04, 0xa8, 0xab, 0x2a, 0x7d, 0xe6, 0x68, 0x22, 0x04, 0x69, 0xc2, 0x19, 0xcd, 0x88, 0x40, 0xf9,
0xcd, 0x45, 0xfd, 0xc5, 0x41, 0x62, 0x32, 0xca, 0xbb, 0xb6, 0xd8, 0x68, 0xab, 0x24, 0xf1, 0x5e,
0x6c, 0x59, 0x92, 0x41, 0x77, 0x99, 0xca, 0xa7, 0x35, 0x79, 0xa9, 0xfc, 0xf3, 0x21, 0xc2, 0x27,
0xe2, 0xf0, 0x28, 0x77, 0x2b, 0x33, 0xbe, 0xa0, 0x79, 0x1f, 0x0a, 0x73, 0x4a, 0x50, 0x73, 0x24,
0xbe, 0xee, 0x4d, 0xd1, 0x9e, 0x18, 0xc4, 0x5f, 0xfe, 0xcd, 0x3a, 0xca, 0x22, 0x5d, 0x22, 0xe7,
0x47, 0x91, 0xb3, 0xd1, 0x9c, 0x3a, 0x81, 0xfb, 0x7e, 0x1c, 0x75, 0xcb, 0x72, 0xee, 0x3a, 0xf8,
}; };
sha384_init(&ctx); sha384_init(&ctx);
#if WITH_OPENSSL #if WITH_OPENSSL
/* openssl counts bits */ ctx.Nl = 0xfffffffffffffc00LLU;
ctx.Nl = 0xffffffffffffff80LLU << 3LLU;
ctx.Nh = 0xffffffffffffff80LLU >> 61LLU;
#else #else
/* cryb counts bytes and multiplies at the end */ ctx.bitlen[1] = 0xfffffffffffffc00LLU;
ctx.total[0] = 0xffffffffffffff80LLU;
#endif #endif
sha384_update(&ctx, t_seq8, 256); sha384_update(&ctx, t_seq8, 256);
sha384_final(&ctx, digest); sha384_final(&ctx, digest);

View file

@ -239,24 +239,21 @@ t_sha512_carry(char **desc CRYB_UNUSED, void *arg CRYB_UNUSED)
sha512_ctx ctx; sha512_ctx ctx;
uint8_t digest[SHA512_DIGEST_LEN]; uint8_t digest[SHA512_DIGEST_LEN];
static uint8_t expect[SHA512_DIGEST_LEN] = { static uint8_t expect[SHA512_DIGEST_LEN] = {
0xbd, 0x25, 0x6d, 0xa8, 0xbf, 0xe0, 0x6c, 0xf0, 0x00, 0x79, 0xb9, 0x71, 0xd3, 0x86, 0x0b, 0x53,
0xc1, 0x8c, 0xe9, 0x58, 0xb8, 0xce, 0x43, 0xc7, 0x64, 0xc7, 0x37, 0x63, 0x97, 0x8f, 0x35, 0x14,
0x9a, 0x3d, 0xec, 0x10, 0x58, 0x55, 0x00, 0x7f, 0xed, 0x53, 0x20, 0x3d, 0xae, 0x03, 0xa0, 0x37,
0xe7, 0x75, 0x48, 0x66, 0xb2, 0x18, 0xc3, 0x98, 0x70, 0xbe, 0xce, 0x70, 0x87, 0x20, 0x21, 0x16,
0x91, 0x11, 0x75, 0x88, 0x53, 0x3e, 0xb3, 0x4b, 0x43, 0x8d, 0x3f, 0xe2, 0xbc, 0x02, 0xf0, 0x8c,
0x83, 0x93, 0xca, 0x18, 0x8a, 0xbe, 0x32, 0x7d, 0xc9, 0x98, 0x4c, 0x4d, 0xf3, 0x6f, 0x0b, 0xbb,
0x4a, 0x54, 0x16, 0xbb, 0xdf, 0x9e, 0x9c, 0x3a, 0x55, 0x94, 0x70, 0x95, 0xf1, 0x9f, 0xaf, 0xaf,
0xd7, 0x22, 0xc8, 0x0d, 0x71, 0x0f, 0x76, 0xc0, 0xd6, 0xbb, 0x3a, 0xbb, 0x4d, 0x6a, 0xf0, 0xc0,
}; };
sha512_init(&ctx); sha512_init(&ctx);
#if WITH_OPENSSL #if WITH_OPENSSL
/* openssl counts bits */ ctx.Nl = 0xfffffffffffffc00LLU;
ctx.Nl = 0xffffffffffffff80LLU << 3LLU;
ctx.Nh = 0xffffffffffffff80LLU >> 61LLU;
#else #else
/* cryb counts bytes and multiplies at the end */ ctx.bitlen[1] = 0xfffffffffffffc00LLU;
ctx.total[0] = 0xffffffffffffff80LLU;
#endif #endif
sha512_update(&ctx, t_seq8, 256); sha512_update(&ctx, t_seq8, 256);
sha512_final(&ctx, digest); sha512_final(&ctx, digest);