This is my current attempt to rework hash/HMAC internal API to use separate block buffer from main hash state and thus decrease HMAC context data size by removing byte buffer duplication. Unfortunately this breaks GnuTLS accelerated implementations. Patch for GnuTLS will be provided, if this approach is going to be accepted to Nettle.
The following changes since commit ee5d62898cf070f08beedc410a8d7c418588bd95:
Fixes for Nettle 3.5.1 (2019-06-26 21:51:36 +0200)
are available in the Git repository at:
https://gitlab.com/GostCrypt/nettle.git gitlab/hmac-3
for you to fetch changes up to dda00a07d26dbdb6647186c778febe870c30cafc:
hmac-sha512/hmac-sha384: use new hmac and hash split state/buffer interface (2019-07-02 16:21:48 +0300)
---------------------------------------------------------------- Dmitry Eremin-Solenikov (14): sha512-224,-256: use _NETTLE_HASH_US instead of hand-coding structure definitions hash: start separating state and block contexts macros: add interface for working with separate hash state and buffer md5: split context into hash state and byte buffer hmac: add interface for working with separate hash state and buffer hmac-md5: use new hmac and hash split state/buffer interface ripemd160: split context into hash state and byte buffer hmac-ripemd160: use new hmac and hash split state/buffer interface sha1: split context into hash state and byte buffer hmac-sha1: use new hmac and hash split state/buffer interface sha256/sha224: split context into hash state and byte buffer hmac-sha256/hmac-sha224: use new hmac and hash split state/buffer interface sha512/sha384: split context into hash state and byte buffer hmac-sha512/hmac-sha384: use new hmac and hash split state/buffer interface
hmac-md5.c | 6 +-- hmac-ripemd160.c | 6 +-- hmac-sha1.c | 6 +-- hmac-sha224.c | 4 +- hmac-sha256.c | 6 +-- hmac-sha384.c | 4 +- hmac-sha512.c | 6 +-- hmac.c | 62 ++++++++++++++++++++++++++ hmac.h | 37 +++++++++++++--- macros.h | 66 ++++++++++++++++++++++++++++ md5-meta.c | 3 ++ md5.c | 52 ++++++++++++++++------ md5.h | 29 ++++++++++-- nettle-meta.h | 56 ++++++++++++++++++++++++ nettle-types.h | 15 +++++++ ripemd160-meta.c | 3 ++ ripemd160.c | 50 ++++++++++++++++----- ripemd160.h | 29 ++++++++++-- sha1-meta.c | 3 ++ sha1.c | 56 +++++++++++++++++------- sha1.h | 29 ++++++++++-- sha2.h | 87 +++++++++++++++++++++++++++++++++--- sha224-meta.c | 3 ++ sha256-meta.c | 3 ++ sha256.c | 76 +++++++++++++++++++++++++------- sha384-meta.c | 3 ++ sha512-224-meta.c | 12 +---- sha512-256-meta.c | 12 +---- sha512-meta.c | 3 ++ sha512.c | 129 +++++++++++++++++++++++++++++++++++++++--------------- 30 files changed, 701 insertions(+), 155 deletions(-)
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- nettle-meta.h | 10 ++++++++++ sha512-224-meta.c | 12 ++---------- sha512-256-meta.c | 12 ++---------- 3 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/nettle-meta.h b/nettle-meta.h index 74e50e59cd2e..e3db0e9d63aa 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -117,6 +117,16 @@ struct nettle_hash (nettle_hash_digest_func *) name##_digest \ }
+#define _NETTLE_HASH_US(name, name_us, NAME) { \ + #name, \ + sizeof(struct name_us##_ctx), \ + NAME##_DIGEST_SIZE, \ + NAME##_BLOCK_SIZE, \ + (nettle_hash_init_func *) name_us##_init, \ + (nettle_hash_update_func *) name_us##_update, \ + (nettle_hash_digest_func *) name_us##_digest \ +} + /* null-terminated list of digests implemented by this version of nettle */ const struct nettle_hash * const * _NETTLE_ATTRIBUTE_PURE nettle_get_hashes (void); diff --git a/sha512-224-meta.c b/sha512-224-meta.c index 24c42bfc23d9..ce07362f3ad0 100644 --- a/sha512-224-meta.c +++ b/sha512-224-meta.c @@ -37,13 +37,5 @@
#include "sha2.h"
-const struct nettle_hash nettle_sha512_224 = - { - "sha512-224", sizeof(struct sha512_ctx), - SHA512_224_DIGEST_SIZE, - SHA512_224_BLOCK_SIZE, - (nettle_hash_init_func *) sha512_224_init, - (nettle_hash_update_func *) sha512_224_update, - (nettle_hash_digest_func *) sha512_224_digest - }; - +const struct nettle_hash nettle_sha512_224 += _NETTLE_HASH_US(sha512-224, sha512_224, SHA512_224); diff --git a/sha512-256-meta.c b/sha512-256-meta.c index 37d17c351878..fbaece84b998 100644 --- a/sha512-256-meta.c +++ b/sha512-256-meta.c @@ -37,13 +37,5 @@
#include "sha2.h"
-const struct nettle_hash nettle_sha512_256 = - { - "sha512-256", sizeof(struct sha512_ctx), - SHA512_256_DIGEST_SIZE, - SHA512_256_BLOCK_SIZE, - (nettle_hash_init_func *) sha512_256_init, - (nettle_hash_update_func *) sha512_256_update, - (nettle_hash_digest_func *) sha512_256_digest - }; - +const struct nettle_hash nettle_sha512_256 += _NETTLE_HASH_US(sha512-256, sha512_256, SHA512_256);
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- nettle-meta.h | 28 ++++++++++++++++++++++++++++ nettle-types.h | 15 +++++++++++++++ 2 files changed, 43 insertions(+)
diff --git a/nettle-meta.h b/nettle-meta.h index e3db0e9d63aa..f21dcd9b344d 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -107,6 +107,24 @@ struct nettle_hash nettle_hash_digest_func *digest; };
+struct nettle_bctx_hash +{ + const char *name; + + /* Size of the context state struct */ + unsigned state_size; + + /* Size of digests */ + unsigned digest_size; + + /* Internal block size */ + unsigned block_size; + + nettle_hash_block_init_func *block_init; + nettle_hash_block_update_func *block_update; + nettle_hash_block_digest_func *block_digest; +}; + #define _NETTLE_HASH(name, NAME) { \ #name, \ sizeof(struct name##_ctx), \ @@ -127,6 +145,16 @@ struct nettle_hash (nettle_hash_digest_func *) name_us##_digest \ }
+#define _NETTLE_BLOCK_HASH(name, NAME) { \ + #name, \ + sizeof(struct name##_state), \ + NAME##_DIGEST_SIZE, \ + NAME##_BLOCK_SIZE, \ + (nettle_hash_block_init_func *) name##_block_init, \ + (nettle_hash_block_update_func *) name##_block_update, \ + (nettle_hash_block_digest_func *) name##_block_digest \ +} + /* null-terminated list of digests implemented by this version of nettle */ const struct nettle_hash * const * _NETTLE_ATTRIBUTE_PURE nettle_get_hashes (void); diff --git a/nettle-types.h b/nettle-types.h index 87292ac69730..ecb56cbba39c 100644 --- a/nettle-types.h +++ b/nettle-types.h @@ -65,6 +65,14 @@ union nettle_block16 uint64_t u64[2]; };
+#define BLOCK_CTX(size) struct { unsigned index; uint8_t buffer[size]; } block + +/* Simple block context without actual buffer length */ +struct block_ctx { + unsigned index; + uint8_t buffer[0]; +}; + /* Randomness. Used by key generation and dsa signature creation. */ typedef void nettle_random_func(void *ctx, size_t length, uint8_t *dst); @@ -97,6 +105,13 @@ typedef void nettle_hash_update_func(void *ctx, const uint8_t *src); typedef void nettle_hash_digest_func(void *ctx, size_t length, uint8_t *dst); +typedef void nettle_hash_block_init_func(void *ctx, struct block_ctx *bctx); +typedef void nettle_hash_block_update_func(void *ctx, + struct block_ctx *bctx, + size_t length, + const uint8_t *src); +typedef void nettle_hash_block_digest_func(void *ctx, struct block_ctx *bctx, + size_t length, uint8_t *dst);
/* ASCII armor codecs. NOTE: Experimental and subject to change. */
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- macros.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/macros.h b/macros.h index 990d32ee3b36..615f06c4c7de 100644 --- a/macros.h +++ b/macros.h @@ -215,6 +215,45 @@ do { \ ; \ } while (0)
+/* Takes the compression function f as argument. NOTE: also clobbers + length and data. */ +#define MD_BLOCK_UPDATE(state, bctx, bsize, length, data, f, incr) \ + do { \ + if ((bctx)->index) \ + { \ + /* Try to fill partial block */ \ + unsigned __md_left = bsize - (bctx)->index; \ + if ((length) < __md_left) \ + { \ + memcpy((bctx)->buffer + (bctx)->index, (data), (length)); \ + (bctx)->index += (length); \ + goto __md_done; /* Finished */ \ + } \ + else \ + { \ + memcpy((bctx)->buffer + (bctx)->index, (data), __md_left); \ + \ + f((state), (bctx)->buffer); \ + (incr); \ + \ + (data) += __md_left; \ + (length) -= __md_left; \ + } \ + } \ + while ((length) >= bsize) \ + { \ + f((state), (data)); \ + (incr); \ + \ + (data) += bsize; \ + (length) -= bsize; \ + } \ + memcpy ((bctx)->buffer, (data), (length)); \ + (bctx)->index = (length); \ + __md_done: \ + ; \ + } while (0) + /* Pads the block to a block boundary with the bit pattern 1 0*, leaving size octets for the length field at the end. If needed, compresses the block and starts a new one. */ @@ -242,4 +281,31 @@ do { \ \ } while (0)
+/* Pads the block to a block boundary with the bit pattern 1 0*, + leaving size octets for the length field at the end. If needed, + compresses the block and starts a new one. */ +#define MD_BLOCK_PAD(sctx, bctx, bsize, size, f) \ + do { \ + unsigned __md_i; \ + __md_i = (bctx)->index; \ + \ + /* Set the first char of padding to 0x80. This is safe since there \ + is always at least one byte free */ \ + \ + assert(__md_i < bsize); \ + (bctx)->buffer[__md_i++] = 0x80; \ + \ + if (__md_i > (bsize - (size))) \ + { /* No room for length in this block. Process it and \ + pad with another one */ \ + memset((bctx)->buffer + __md_i, 0, bsize - __md_i); \ + \ + f((sctx), (bctx)->buffer); \ + __md_i = 0; \ + } \ + memset((bctx)->buffer + __md_i, 0, \ + bsize - (size) - __md_i); \ + \ + } while (0) + #endif /* NETTLE_MACROS_H_INCLUDED */
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- md5-meta.c | 3 +++ md5.c | 52 +++++++++++++++++++++++++++++++++++++-------------- md5.h | 29 +++++++++++++++++++++++++--- nettle-meta.h | 2 ++ 4 files changed, 69 insertions(+), 17 deletions(-)
diff --git a/md5-meta.c b/md5-meta.c index e4013edfd233..63b4a7438774 100644 --- a/md5-meta.c +++ b/md5-meta.c @@ -39,3 +39,6 @@
const struct nettle_hash nettle_md5 = _NETTLE_HASH(md5, MD5); + +const struct nettle_bctx_hash nettle_bctx_md5 += _NETTLE_BLOCK_HASH(md5, MD5); diff --git a/md5.c b/md5.c index cc009b4a8dc8..2876a3105108 100644 --- a/md5.c +++ b/md5.c @@ -47,7 +47,7 @@ #include "nettle-write.h"
void -md5_init(struct md5_ctx *ctx) +md5_block_init(struct md5_state *state, struct block_ctx *bctx) { const uint32_t iv[_MD5_DIGEST_LENGTH] = { @@ -56,9 +56,15 @@ md5_init(struct md5_ctx *ctx) 0x98badcfe, 0x10325476, }; - memcpy(ctx->state, iv, sizeof(ctx->state)); - ctx->count = 0; - ctx->index = 0; + memcpy(state->state, iv, sizeof(state->state)); + state->count = 0; + bctx->index = 0; +} + +void +md5_init(struct md5_ctx *ctx) +{ + return md5_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
#define COMPRESS(ctx, data) (nettle_md5_compress((ctx)->state, (data))) @@ -68,26 +74,44 @@ md5_update(struct md5_ctx *ctx, size_t length, const uint8_t *data) { - MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++); + MD_BLOCK_UPDATE(&ctx->state, &ctx->block, MD5_BLOCK_SIZE, length, data, COMPRESS, ctx->state.count++); }
void -md5_digest(struct md5_ctx *ctx, - size_t length, - uint8_t *digest) +md5_block_update(struct md5_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data) +{ + MD_BLOCK_UPDATE(state, bctx, MD5_BLOCK_SIZE, length, data, COMPRESS, state->count++); +} + +void +md5_block_digest(struct md5_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest) { uint64_t bit_count;
assert(length <= MD5_DIGEST_SIZE);
- MD_PAD(ctx, 8, COMPRESS); + MD_BLOCK_PAD(state, bctx, MD5_BLOCK_SIZE, 8, COMPRESS);
/* There are 512 = 2^9 bits in one block */ - bit_count = (ctx->count << 9) | (ctx->index << 3); + bit_count = (state->count << 9) | (bctx->index << 3);
- LE_WRITE_UINT64(ctx->block + (MD5_BLOCK_SIZE - 8), bit_count); - nettle_md5_compress(ctx->state, ctx->block); + LE_WRITE_UINT64(bctx->buffer + (MD5_BLOCK_SIZE - 8), bit_count); + nettle_md5_compress(state->state, bctx->buffer); + + _nettle_write_le32(length, digest, state->state); + md5_block_init(state, bctx); +}
- _nettle_write_le32(length, digest, ctx->state); - md5_init(ctx); +void +md5_digest(struct md5_ctx *ctx, + size_t length, + uint8_t *digest) +{ + return md5_block_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); } diff --git a/md5.h b/md5.h index e5ae228e8217..23738a8532c5 100644 --- a/md5.h +++ b/md5.h @@ -44,6 +44,9 @@ extern "C" { #define md5_init nettle_md5_init #define md5_update nettle_md5_update #define md5_digest nettle_md5_digest +#define md5_block_init nettle_md5_block_init +#define md5_block_update nettle_md5_block_update +#define md5_block_digest nettle_md5_block_digest
#define MD5_DIGEST_SIZE 16 #define MD5_BLOCK_SIZE 64 @@ -53,12 +56,16 @@ extern "C" { /* Digest is kept internally as 4 32-bit words. */ #define _MD5_DIGEST_LENGTH 4
-struct md5_ctx +struct md5_state { uint32_t state[_MD5_DIGEST_LENGTH]; uint64_t count; /* Block count */ - unsigned index; /* Into buffer */ - uint8_t block[MD5_BLOCK_SIZE]; /* Block buffer */ +}; + +struct md5_ctx +{ + struct md5_state state; + BLOCK_CTX(MD5_BLOCK_SIZE); };
void @@ -74,6 +81,22 @@ md5_digest(struct md5_ctx *ctx, size_t length, uint8_t *digest);
+void +md5_block_init(struct md5_state *state, + struct block_ctx *bctx); + +void +md5_block_update(struct md5_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data); + +void +md5_block_digest(struct md5_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest); + /* Internal compression function. STATE points to 4 uint32_t words, and DATA points to 64 bytes of input data, possibly unaligned. */ void diff --git a/nettle-meta.h b/nettle-meta.h index f21dcd9b344d..770b1953ca5d 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -181,6 +181,8 @@ extern const struct nettle_hash nettle_sha3_256; extern const struct nettle_hash nettle_sha3_384; extern const struct nettle_hash nettle_sha3_512;
+extern const struct nettle_bctx_hash nettle_bctx_md5; + struct nettle_aead { const char *name;
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- hmac.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hmac.h | 27 +++++++++++++++++++++++++ 2 files changed, 89 insertions(+)
diff --git a/hmac.c b/hmac.c index 6ac5e11a0686..6b925ce6e147 100644 --- a/hmac.c +++ b/hmac.c @@ -115,3 +115,65 @@ hmac_digest(const void *outer, const void *inner, void *state,
memcpy(state, inner, hash->context_size); } + +void +hmac_block_set_key(void *outer, void *inner, void *state, + struct block_ctx *bctx, + const struct nettle_bctx_hash *hash, + size_t key_length, const uint8_t *key) +{ + TMP_DECL(pad, uint8_t, NETTLE_MAX_HASH_BLOCK_SIZE); + TMP_ALLOC(pad, hash->block_size); + + hash->block_init(outer, bctx); + hash->block_init(inner, bctx); + + if (key_length > hash->block_size) + { + /* Reduce key to the algorithm's hash size. Use the area pointed + * to by state for the temporary state. */ + + TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + TMP_ALLOC(digest, hash->digest_size); + + hash->block_init(state, bctx); + hash->block_update(state, bctx, key_length, key); + hash->block_digest(state, bctx, hash->digest_size, digest); + + key = digest; + key_length = hash->digest_size; + } + + assert(key_length <= hash->block_size); + + memset(pad, OPAD, hash->block_size); + memxor(pad, key, key_length); + + hash->block_update(outer, bctx, hash->block_size, pad); + + memset(pad, IPAD, hash->block_size); + memxor(pad, key, key_length); + + hash->block_update(inner, bctx, hash->block_size, pad); + + memcpy(state, inner, hash->state_size); +} + +void +hmac_block_digest(const void *outer, const void *inner, void *state, + struct block_ctx *bctx, + const struct nettle_bctx_hash *hash, + size_t length, uint8_t *dst) +{ + TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + TMP_ALLOC(digest, hash->digest_size); + + hash->block_digest(state, bctx, hash->digest_size, digest); + + memcpy(state, outer, hash->state_size); + + hash->block_update(state, bctx, hash->digest_size, digest); + hash->block_digest(state, bctx, length, dst); + + memcpy(state, inner, hash->state_size); +} diff --git a/hmac.h b/hmac.h index 40a8e77aab6d..84ff4a56d93b 100644 --- a/hmac.h +++ b/hmac.h @@ -49,6 +49,8 @@ extern "C" { #define hmac_set_key nettle_hmac_set_key #define hmac_update nettle_hmac_update #define hmac_digest nettle_hmac_digest +#define hmac_block_set_key nettle_hmac_block_set_key +#define hmac_block_digest nettle_hmac_block_digest #define hmac_md5_set_key nettle_hmac_md5_set_key #define hmac_md5_update nettle_hmac_md5_update #define hmac_md5_digest nettle_hmac_md5_digest @@ -86,6 +88,18 @@ hmac_digest(const void *outer, const void *inner, void *state, const struct nettle_hash *hash, size_t length, uint8_t *digest);
+void +hmac_block_set_key(void *outer, void *inner, void *state, + struct block_ctx *bctx, + const struct nettle_bctx_hash *hash, + size_t key_length, const uint8_t *key); + +void +hmac_block_digest(const void *outer, const void *inner, void *state, + struct block_ctx *bctx, + const struct nettle_bctx_hash *hash, + size_t length, uint8_t *digest); +
#define HMAC_CTX(type) \ { type outer; type inner; type state; } @@ -98,6 +112,19 @@ hmac_digest(const void *outer, const void *inner, void *state, hmac_digest( &(ctx)->outer, &(ctx)->inner, &(ctx)->state, \ (hash), (length), (digest) )
+#define HMAC_BLOCK_CTX(type, block_size) \ +{ type outer; type inner; type state; BLOCK_CTX(block_size); } + +#define HMAC_BLOCK_SET_KEY(ctx, hash, length, key) \ + hmac_block_set_key( &(ctx)->outer, &(ctx)->inner, &(ctx)->state, \ + (struct block_ctx *)&(ctx)->block, \ + (hash), (length), (key) ) + +#define HMAC_BLOCK_DIGEST(ctx, hash, length, digest) \ + hmac_block_digest( &(ctx)->outer, &(ctx)->inner, &(ctx)->state, \ + (struct block_ctx *)&(ctx)->block, \ + (hash), (length), (digest) ) + /* HMAC using specific hash functions */
/* hmac-md5 */
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- hmac-md5.c | 6 +++--- hmac.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/hmac-md5.c b/hmac-md5.c index a27e64f6f61b..910d8a508a11 100644 --- a/hmac-md5.c +++ b/hmac-md5.c @@ -41,19 +41,19 @@ void hmac_md5_set_key(struct hmac_md5_ctx *ctx, size_t key_length, const uint8_t *key) { - HMAC_SET_KEY(ctx, &nettle_md5, key_length, key); + HMAC_BLOCK_SET_KEY(ctx, &nettle_bctx_md5, key_length, key); }
void hmac_md5_update(struct hmac_md5_ctx *ctx, size_t length, const uint8_t *data) { - md5_update(&ctx->state, length, data); + md5_block_update(&ctx->state, (struct block_ctx *)&ctx->block, length, data); }
void hmac_md5_digest(struct hmac_md5_ctx *ctx, size_t length, uint8_t *digest) { - HMAC_DIGEST(ctx, &nettle_md5, length, digest); + HMAC_BLOCK_DIGEST(ctx, &nettle_bctx_md5, length, digest); } diff --git a/hmac.h b/hmac.h index 84ff4a56d93b..20b9d8483b80 100644 --- a/hmac.h +++ b/hmac.h @@ -128,7 +128,7 @@ hmac_block_digest(const void *outer, const void *inner, void *state, /* HMAC using specific hash functions */
/* hmac-md5 */ -struct hmac_md5_ctx HMAC_CTX(struct md5_ctx); +struct hmac_md5_ctx HMAC_BLOCK_CTX(struct md5_state, MD5_BLOCK_SIZE);
void hmac_md5_set_key(struct hmac_md5_ctx *ctx,
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- nettle-meta.h | 1 + ripemd160-meta.c | 3 +++ ripemd160.c | 50 ++++++++++++++++++++++++++++++++++++------------ ripemd160.h | 29 +++++++++++++++++++++++++--- 4 files changed, 68 insertions(+), 15 deletions(-)
diff --git a/nettle-meta.h b/nettle-meta.h index 770b1953ca5d..79a9900cbdfa 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -182,6 +182,7 @@ extern const struct nettle_hash nettle_sha3_384; extern const struct nettle_hash nettle_sha3_512;
extern const struct nettle_bctx_hash nettle_bctx_md5; +extern const struct nettle_bctx_hash nettle_bctx_ripemd160;
struct nettle_aead { diff --git a/ripemd160-meta.c b/ripemd160-meta.c index c1860b728599..bfa0b080767e 100644 --- a/ripemd160-meta.c +++ b/ripemd160-meta.c @@ -39,3 +39,6 @@
const struct nettle_hash nettle_ripemd160 = _NETTLE_HASH(ripemd160, RIPEMD160); + +const struct nettle_bctx_hash nettle_bctx_ripemd160 += _NETTLE_BLOCK_HASH(ripemd160, RIPEMD160); diff --git a/ripemd160.c b/ripemd160.c index 56ffee33cd6d..ee59684bd834 100644 --- a/ripemd160.c +++ b/ripemd160.c @@ -156,7 +156,7 @@ */
void -ripemd160_init(struct ripemd160_ctx *ctx) +ripemd160_block_init(struct ripemd160_state *state, struct block_ctx *bctx) { static const uint32_t iv[_RIPEMD160_DIGEST_LENGTH] = { @@ -166,9 +166,15 @@ ripemd160_init(struct ripemd160_ctx *ctx) 0x10325476, 0xC3D2E1F0, }; - memcpy(ctx->state, iv, sizeof(ctx->state)); - ctx->count = 0; - ctx->index = 0; + memcpy(state->state, iv, sizeof(state->state)); + state->count = 0; + bctx->index = 0; +} + +void +ripemd160_init(struct ripemd160_ctx *ctx) +{ + return ripemd160_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
#define COMPRESS(ctx, data) (_nettle_ripemd160_compress((ctx)->state, (data))) @@ -179,25 +185,45 @@ ripemd160_init(struct ripemd160_ctx *ctx) void ripemd160_update(struct ripemd160_ctx *ctx, size_t length, const uint8_t *data) { - MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++); + MD_BLOCK_UPDATE(&ctx->state, &ctx->block, RIPEMD160_BLOCK_SIZE, length, data, COMPRESS, ctx->state.count++); +} + +void +ripemd160_block_update(struct ripemd160_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data) +{ + MD_BLOCK_UPDATE(state, bctx, RIPEMD160_BLOCK_SIZE, length, data, COMPRESS, state->count++); }
void -ripemd160_digest(struct ripemd160_ctx *ctx, size_t length, uint8_t *digest) +ripemd160_block_digest(struct ripemd160_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest) { uint64_t bit_count;
assert(length <= RIPEMD160_DIGEST_SIZE);
- MD_PAD(ctx, 8, COMPRESS); + MD_BLOCK_PAD(state, bctx, RIPEMD160_BLOCK_SIZE, 8, COMPRESS);
/* There are 2^9 bits in one block */ - bit_count = (ctx->count << 9) | (ctx->index << 3); + bit_count = (state->count << 9) | (bctx->index << 3); \ /* append the 64 bit count */ - LE_WRITE_UINT64(ctx->block + 56, bit_count); - _nettle_ripemd160_compress(ctx->state, ctx->block); + LE_WRITE_UINT64(bctx->buffer + 56, bit_count); + _nettle_ripemd160_compress(state->state, bctx->buffer);
- _nettle_write_le32(length, digest, ctx->state); - ripemd160_init(ctx); + _nettle_write_le32(length, digest, state->state); + ripemd160_block_init(state, bctx); +} + +void +ripemd160_digest(struct ripemd160_ctx *ctx, + size_t length, + uint8_t *digest) +{ + return ripemd160_block_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); } diff --git a/ripemd160.h b/ripemd160.h index 238c5ee7a44c..40671a29a5a6 100644 --- a/ripemd160.h +++ b/ripemd160.h @@ -44,6 +44,9 @@ extern "C" { #define ripemd160_init nettle_ripemd160_init #define ripemd160_update nettle_ripemd160_update #define ripemd160_digest nettle_ripemd160_digest +#define ripemd160_block_init nettle_ripemd160_block_init +#define ripemd160_block_update nettle_ripemd160_block_update +#define ripemd160_block_digest nettle_ripemd160_block_digest
/* RIPEMD160 */
@@ -55,12 +58,16 @@ extern "C" { /* Digest is kept internally as 5 32-bit words. */ #define _RIPEMD160_DIGEST_LENGTH 5
-struct ripemd160_ctx +struct ripemd160_state { uint32_t state[_RIPEMD160_DIGEST_LENGTH]; uint64_t count; /* 64-bit block count */ - unsigned int index; - uint8_t block[RIPEMD160_BLOCK_SIZE]; +}; + +struct ripemd160_ctx +{ + struct ripemd160_state state; + BLOCK_CTX(RIPEMD160_BLOCK_SIZE); };
void @@ -76,6 +83,22 @@ ripemd160_digest(struct ripemd160_ctx *ctx, size_t length, uint8_t *digest);
+void +ripemd160_block_init(struct ripemd160_state *state, + struct block_ctx *bctx); + +void +ripemd160_block_update(struct ripemd160_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data); + +void +ripemd160_block_digest(struct ripemd160_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest); + #ifdef __cplusplus } #endif
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- hmac-ripemd160.c | 6 +++--- hmac.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/hmac-ripemd160.c b/hmac-ripemd160.c index 24e2cbe7a578..fa4e6a09075c 100644 --- a/hmac-ripemd160.c +++ b/hmac-ripemd160.c @@ -41,19 +41,19 @@ void hmac_ripemd160_set_key(struct hmac_ripemd160_ctx *ctx, size_t key_length, const uint8_t *key) { - HMAC_SET_KEY(ctx, &nettle_ripemd160, key_length, key); + HMAC_BLOCK_SET_KEY(ctx, &nettle_bctx_ripemd160, key_length, key); }
void hmac_ripemd160_update(struct hmac_ripemd160_ctx *ctx, size_t length, const uint8_t *data) { - ripemd160_update(&ctx->state, length, data); + ripemd160_block_update(&ctx->state, (struct block_ctx *)&ctx->block, length, data); }
void hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx, size_t length, uint8_t *digest) { - HMAC_DIGEST(ctx, &nettle_ripemd160, length, digest); + HMAC_BLOCK_DIGEST(ctx, &nettle_bctx_ripemd160, length, digest); } diff --git a/hmac.h b/hmac.h index 20b9d8483b80..cf083cfb0c3c 100644 --- a/hmac.h +++ b/hmac.h @@ -144,7 +144,7 @@ hmac_md5_digest(struct hmac_md5_ctx *ctx,
/* hmac-ripemd160 */ -struct hmac_ripemd160_ctx HMAC_CTX(struct ripemd160_ctx); +struct hmac_ripemd160_ctx HMAC_BLOCK_CTX(struct ripemd160_state, RIPEMD160_BLOCK_SIZE);
void hmac_ripemd160_set_key(struct hmac_ripemd160_ctx *ctx,
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- nettle-meta.h | 1 + sha1-meta.c | 3 +++ sha1.c | 56 ++++++++++++++++++++++++++++++++++++--------------- sha1.h | 29 +++++++++++++++++++++++--- 4 files changed, 70 insertions(+), 19 deletions(-)
diff --git a/nettle-meta.h b/nettle-meta.h index 79a9900cbdfa..95aaaf0fcc8c 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -183,6 +183,7 @@ extern const struct nettle_hash nettle_sha3_512;
extern const struct nettle_bctx_hash nettle_bctx_md5; extern const struct nettle_bctx_hash nettle_bctx_ripemd160; +extern const struct nettle_bctx_hash nettle_bctx_sha1;
struct nettle_aead { diff --git a/sha1-meta.c b/sha1-meta.c index dde990360a8f..def2704c40ee 100644 --- a/sha1-meta.c +++ b/sha1-meta.c @@ -39,3 +39,6 @@
const struct nettle_hash nettle_sha1 = _NETTLE_HASH(sha1, SHA1); + +const struct nettle_bctx_hash nettle_bctx_sha1 += _NETTLE_BLOCK_HASH(sha1, SHA1); diff --git a/sha1.c b/sha1.c index af73096c9016..7dca34b71ef7 100644 --- a/sha1.c +++ b/sha1.c @@ -47,7 +47,7 @@
/* Initialize the SHA values */ void -sha1_init(struct sha1_ctx *ctx) +sha1_block_init(struct sha1_state *state, struct block_ctx *bctx) { /* FIXME: Put the buffer last in the struct, and arrange so that we can initialize with a single memcpy. */ @@ -61,11 +61,17 @@ sha1_init(struct sha1_ctx *ctx) 0xC3D2E1F0L, };
- memcpy(ctx->state, iv, sizeof(ctx->state)); - ctx->count = 0; - + memcpy(state->state, iv, sizeof(state->state)); + state->count = 0; + /* Initialize buffer */ - ctx->index = 0; + bctx->index = 0; +} + +void +sha1_init(struct sha1_ctx *ctx) +{ + return sha1_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
#define COMPRESS(ctx, data) (nettle_sha1_compress((ctx)->state, data)) @@ -74,27 +80,45 @@ void sha1_update(struct sha1_ctx *ctx, size_t length, const uint8_t *data) { - MD_UPDATE (ctx, length, data, COMPRESS, ctx->count++); + MD_BLOCK_UPDATE(&ctx->state, &ctx->block, SHA1_BLOCK_SIZE, length, data, COMPRESS, ctx->state.count++); } - + void -sha1_digest(struct sha1_ctx *ctx, - size_t length, - uint8_t *digest) +sha1_block_update(struct sha1_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data) +{ + MD_BLOCK_UPDATE(state, bctx, SHA1_BLOCK_SIZE, length, data, COMPRESS, state->count++); +} + +void +sha1_block_digest(struct sha1_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest) { uint64_t bit_count;
assert(length <= SHA1_DIGEST_SIZE);
- MD_PAD(ctx, 8, COMPRESS); + MD_BLOCK_PAD(state, bctx, SHA1_BLOCK_SIZE, 8, COMPRESS);
/* There are 512 = 2^9 bits in one block */ - bit_count = (ctx->count << 9) | (ctx->index << 3); + bit_count = (state->count << 9) | (bctx->index << 3);
/* append the 64 bit count */ - WRITE_UINT64(ctx->block + (SHA1_BLOCK_SIZE - 8), bit_count); - nettle_sha1_compress(ctx->state, ctx->block); + WRITE_UINT64(bctx->buffer + (SHA1_BLOCK_SIZE - 8), bit_count); + nettle_sha1_compress(state->state, bctx->buffer); + + _nettle_write_be32(length, digest, state->state); + sha1_block_init(state, bctx); +}
- _nettle_write_be32(length, digest, ctx->state); - sha1_init(ctx); +void +sha1_digest(struct sha1_ctx *ctx, + size_t length, + uint8_t *digest) +{ + return sha1_block_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); } diff --git a/sha1.h b/sha1.h index 0f4964f8f61c..d5f336eaab04 100644 --- a/sha1.h +++ b/sha1.h @@ -44,6 +44,9 @@ extern "C" { #define sha1_init nettle_sha1_init #define sha1_update nettle_sha1_update #define sha1_digest nettle_sha1_digest +#define sha1_block_init nettle_sha1_block_init +#define sha1_block_update nettle_sha1_block_update +#define sha1_block_digest nettle_sha1_block_digest
/* SHA1 */
@@ -55,12 +58,16 @@ extern "C" { /* Digest is kept internally as 5 32-bit words. */ #define _SHA1_DIGEST_LENGTH 5
-struct sha1_ctx +struct sha1_state { uint32_t state[_SHA1_DIGEST_LENGTH]; /* State variables */ uint64_t count; /* 64-bit block count */ - unsigned int index; /* index into buffer */ - uint8_t block[SHA1_BLOCK_SIZE]; /* SHA1 data buffer */ +}; + +struct sha1_ctx +{ + struct sha1_state state; + BLOCK_CTX(SHA1_BLOCK_SIZE); };
void @@ -76,6 +83,22 @@ sha1_digest(struct sha1_ctx *ctx, size_t length, uint8_t *digest);
+void +sha1_block_init(struct sha1_state *state, + struct block_ctx *bctx); + +void +sha1_block_update(struct sha1_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data); + +void +sha1_block_digest(struct sha1_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest); + /* Internal compression function. STATE points to 5 uint32_t words, and DATA points to 64 bytes of input data, possibly unaligned. */ void
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- hmac-sha1.c | 6 +++--- hmac.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/hmac-sha1.c b/hmac-sha1.c index 5e7188f92cf2..e968a51cd431 100644 --- a/hmac-sha1.c +++ b/hmac-sha1.c @@ -41,19 +41,19 @@ void hmac_sha1_set_key(struct hmac_sha1_ctx *ctx, size_t key_length, const uint8_t *key) { - HMAC_SET_KEY(ctx, &nettle_sha1, key_length, key); + HMAC_BLOCK_SET_KEY(ctx, &nettle_bctx_sha1, key_length, key); }
void hmac_sha1_update(struct hmac_sha1_ctx *ctx, size_t length, const uint8_t *data) { - sha1_update(&ctx->state, length, data); + sha1_block_update(&ctx->state, (struct block_ctx *)&ctx->block, length, data); }
void hmac_sha1_digest(struct hmac_sha1_ctx *ctx, size_t length, uint8_t *digest) { - HMAC_DIGEST(ctx, &nettle_sha1, length, digest); + HMAC_BLOCK_DIGEST(ctx, &nettle_bctx_sha1, length, digest); } diff --git a/hmac.h b/hmac.h index cf083cfb0c3c..117de3262857 100644 --- a/hmac.h +++ b/hmac.h @@ -160,7 +160,7 @@ hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx,
/* hmac-sha1 */ -struct hmac_sha1_ctx HMAC_CTX(struct sha1_ctx); +struct hmac_sha1_ctx HMAC_BLOCK_CTX(struct sha1_state, SHA1_BLOCK_SIZE);
void hmac_sha1_set_key(struct hmac_sha1_ctx *ctx,
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- nettle-meta.h | 2 ++ sha2.h | 42 ++++++++++++++++++++++++++-- sha224-meta.c | 3 ++ sha256-meta.c | 3 ++ sha256.c | 76 +++++++++++++++++++++++++++++++++++++++------------ 5 files changed, 106 insertions(+), 20 deletions(-)
diff --git a/nettle-meta.h b/nettle-meta.h index 95aaaf0fcc8c..a28cecf5fe62 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -184,6 +184,8 @@ extern const struct nettle_hash nettle_sha3_512; extern const struct nettle_bctx_hash nettle_bctx_md5; extern const struct nettle_bctx_hash nettle_bctx_ripemd160; extern const struct nettle_bctx_hash nettle_bctx_sha1; +extern const struct nettle_bctx_hash nettle_bctx_sha224; +extern const struct nettle_bctx_hash nettle_bctx_sha256;
struct nettle_aead { diff --git a/sha2.h b/sha2.h index ca8222a7ece5..95640b5f4b7f 100644 --- a/sha2.h +++ b/sha2.h @@ -43,9 +43,14 @@ extern "C" { /* Name mangling */ #define sha224_init nettle_sha224_init #define sha224_digest nettle_sha224_digest +#define sha224_block_init nettle_sha224_block_init +#define sha224_block_digest nettle_sha224_block_digest #define sha256_init nettle_sha256_init #define sha256_update nettle_sha256_update #define sha256_digest nettle_sha256_digest +#define sha256_block_init nettle_sha256_block_init +#define sha256_block_update nettle_sha256_block_update +#define sha256_block_digest nettle_sha256_block_digest #define sha384_init nettle_sha384_init #define sha384_digest nettle_sha384_digest #define sha512_init nettle_sha512_init @@ -70,12 +75,16 @@ extern "C" { /* Digest is kept internally as 8 32-bit words. */ #define _SHA256_DIGEST_LENGTH 8
-struct sha256_ctx +struct sha256_state { uint32_t state[_SHA256_DIGEST_LENGTH]; /* State variables */ uint64_t count; /* 64-bit block count */ - unsigned int index; /* index into buffer */ - uint8_t block[SHA256_BLOCK_SIZE]; /* SHA256 data buffer */ +}; + +struct sha256_ctx +{ + struct sha256_state state; + BLOCK_CTX(SHA256_BLOCK_SIZE); };
void @@ -91,12 +100,28 @@ sha256_digest(struct sha256_ctx *ctx, size_t length, uint8_t *digest);
+void +sha256_block_init(struct sha256_state *state, + struct block_ctx *bctx); + +void +sha256_block_update(struct sha256_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data); + +void +sha256_block_digest(struct sha256_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest);
/* SHA224, a truncated SHA256 with different initial state. */
#define SHA224_DIGEST_SIZE 28 #define SHA224_BLOCK_SIZE SHA256_BLOCK_SIZE #define sha224_ctx sha256_ctx +#define sha224_state sha256_state
void sha224_init(struct sha256_ctx *ctx); @@ -108,6 +133,17 @@ sha224_digest(struct sha256_ctx *ctx, size_t length, uint8_t *digest);
+void +sha224_block_init(struct sha256_state *state, + struct block_ctx *bctx); + +#define sha224_block_update sha256_block_update + +void +sha224_block_digest(struct sha256_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest);
/* SHA512 */
diff --git a/sha224-meta.c b/sha224-meta.c index 4b3bcef36eba..639a8edd75bc 100644 --- a/sha224-meta.c +++ b/sha224-meta.c @@ -39,3 +39,6 @@
const struct nettle_hash nettle_sha224 = _NETTLE_HASH(sha224, SHA224); + +const struct nettle_bctx_hash nettle_bctx_sha224 += _NETTLE_BLOCK_HASH(sha224, SHA224); diff --git a/sha256-meta.c b/sha256-meta.c index fcdf79322600..1f0a4ee338c2 100644 --- a/sha256-meta.c +++ b/sha256-meta.c @@ -39,3 +39,6 @@
const struct nettle_hash nettle_sha256 = _NETTLE_HASH(sha256, SHA256); + +const struct nettle_bctx_hash nettle_bctx_sha256 += _NETTLE_BLOCK_HASH(sha256, SHA256); diff --git a/sha256.c b/sha256.c index 253c13191356..e14a1caf59b0 100644 --- a/sha256.c +++ b/sha256.c @@ -75,7 +75,7 @@ K[64] = /* Initialize the SHA values */
void -sha256_init(struct sha256_ctx *ctx) +sha256_block_init(struct sha256_state *state, struct block_ctx *bctx) { /* Initial values, also generated by the shadata program. */ static const uint32_t H0[_SHA256_DIGEST_LENGTH] = @@ -84,24 +84,40 @@ sha256_init(struct sha256_ctx *ctx) 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL, };
- memcpy(ctx->state, H0, sizeof(H0)); + memcpy(state->state, H0, sizeof(H0));
/* Initialize bit count */ - ctx->count = 0; + state->count = 0;
/* Initialize buffer */ - ctx->index = 0; + bctx->index = 0; +} + +void +sha256_init(struct sha256_ctx *ctx) +{ + return sha256_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
void sha256_update(struct sha256_ctx *ctx, size_t length, const uint8_t *data) { - MD_UPDATE (ctx, length, data, COMPRESS, ctx->count++); + MD_BLOCK_UPDATE(&ctx->state, &ctx->block, SHA256_BLOCK_SIZE, length, data, COMPRESS, ctx->state.count++); +} + +void +sha256_block_update(struct sha256_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data) +{ + MD_BLOCK_UPDATE(state, bctx, SHA256_BLOCK_SIZE, length, data, COMPRESS, state->count++); }
static void -sha256_write_digest(struct sha256_ctx *ctx, +sha256_write_digest(struct sha256_state *state, + struct block_ctx *bctx, size_t length, uint8_t *digest) { @@ -109,18 +125,18 @@ sha256_write_digest(struct sha256_ctx *ctx,
assert(length <= SHA256_DIGEST_SIZE);
- MD_PAD(ctx, 8, COMPRESS); + MD_BLOCK_PAD(state, bctx, SHA256_BLOCK_SIZE, 8, COMPRESS);
/* There are 512 = 2^9 bits in one block */ - bit_count = (ctx->count << 9) | (ctx->index << 3); + bit_count = (state->count << 9) | (bctx->index << 3);
/* This is slightly inefficient, as the numbers are converted to big-endian format, and will be converted back by the compression function. It's probably not worth the effort to fix this. */ - WRITE_UINT64(ctx->block + (SHA256_BLOCK_SIZE - 8), bit_count); - COMPRESS(ctx, ctx->block); + WRITE_UINT64(bctx->buffer + (SHA256_BLOCK_SIZE - 8), bit_count); + COMPRESS(state, bctx->buffer);
- _nettle_write_be32(length, digest, ctx->state); + _nettle_write_be32(length, digest, state->state); }
void @@ -128,14 +144,24 @@ sha256_digest(struct sha256_ctx *ctx, size_t length, uint8_t *digest) { - sha256_write_digest(ctx, length, digest); + sha256_write_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); sha256_init(ctx); }
+void +sha256_block_digest(struct sha256_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest) +{ + sha256_write_digest(state, bctx, length, digest); + sha256_block_init(state, bctx); +} + /* sha224 variant. */
void -sha224_init(struct sha256_ctx *ctx) +sha224_block_init(struct sha256_state *state, struct block_ctx *bctx) { /* Initial values. Low 32 bits of the initial values for sha384. */ static const uint32_t H0[_SHA256_DIGEST_LENGTH] = @@ -144,13 +170,19 @@ sha224_init(struct sha256_ctx *ctx) 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4, };
- memcpy(ctx->state, H0, sizeof(H0)); + memcpy(state->state, H0, sizeof(H0));
/* Initialize bit count */ - ctx->count = 0; + state->count = 0;
/* Initialize buffer */ - ctx->index = 0; + bctx->index = 0; +} + +void +sha224_init(struct sha256_ctx *ctx) +{ + return sha224_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
void @@ -158,6 +190,16 @@ sha224_digest(struct sha256_ctx *ctx, size_t length, uint8_t *digest) { - sha256_write_digest(ctx, length, digest); + sha256_write_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); sha224_init(ctx); } + +void +sha224_block_digest(struct sha256_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest) +{ + sha256_write_digest(state, bctx, length, digest); + sha224_block_init(state, bctx); +}
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- hmac-sha224.c | 4 ++-- hmac-sha256.c | 6 +++--- hmac.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/hmac-sha224.c b/hmac-sha224.c index c5bc8750a054..303337fe257f 100644 --- a/hmac-sha224.c +++ b/hmac-sha224.c @@ -41,12 +41,12 @@ void hmac_sha224_set_key(struct hmac_sha224_ctx *ctx, size_t key_length, const uint8_t *key) { - HMAC_SET_KEY(ctx, &nettle_sha224, key_length, key); + HMAC_BLOCK_SET_KEY(ctx, &nettle_bctx_sha224, key_length, key); }
void hmac_sha224_digest(struct hmac_sha224_ctx *ctx, size_t length, uint8_t *digest) { - HMAC_DIGEST(ctx, &nettle_sha224, length, digest); + HMAC_BLOCK_DIGEST(ctx, &nettle_bctx_sha224, length, digest); } diff --git a/hmac-sha256.c b/hmac-sha256.c index af5cc0f1cbef..25263bdcd36b 100644 --- a/hmac-sha256.c +++ b/hmac-sha256.c @@ -41,19 +41,19 @@ void hmac_sha256_set_key(struct hmac_sha256_ctx *ctx, size_t key_length, const uint8_t *key) { - HMAC_SET_KEY(ctx, &nettle_sha256, key_length, key); + HMAC_BLOCK_SET_KEY(ctx, &nettle_bctx_sha256, key_length, key); }
void hmac_sha256_update(struct hmac_sha256_ctx *ctx, size_t length, const uint8_t *data) { - sha256_update(&ctx->state, length, data); + sha256_block_update(&ctx->state, (struct block_ctx *)&ctx->block, length, data); }
void hmac_sha256_digest(struct hmac_sha256_ctx *ctx, size_t length, uint8_t *digest) { - HMAC_DIGEST(ctx, &nettle_sha256, length, digest); + HMAC_BLOCK_DIGEST(ctx, &nettle_bctx_sha256, length, digest); } diff --git a/hmac.h b/hmac.h index 117de3262857..445d7c95e03f 100644 --- a/hmac.h +++ b/hmac.h @@ -175,7 +175,7 @@ hmac_sha1_digest(struct hmac_sha1_ctx *ctx, size_t length, uint8_t *digest);
/* hmac-sha256 */ -struct hmac_sha256_ctx HMAC_CTX(struct sha256_ctx); +struct hmac_sha256_ctx HMAC_BLOCK_CTX(struct sha256_state, SHA256_BLOCK_SIZE);
void hmac_sha256_set_key(struct hmac_sha256_ctx *ctx,
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- nettle-meta.h | 12 +++++ sha2.h | 45 ++++++++++++++++-- sha384-meta.c | 3 ++ sha512-meta.c | 3 ++ sha512.c | 129 ++++++++++++++++++++++++++++++++++++-------------- 5 files changed, 152 insertions(+), 40 deletions(-)
diff --git a/nettle-meta.h b/nettle-meta.h index a28cecf5fe62..da9591287e79 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -155,6 +155,16 @@ struct nettle_bctx_hash (nettle_hash_block_digest_func *) name##_block_digest \ }
+#define _NETTLE_BLOCK_HASH_US(name, name_us, NAME) { \ + #name, \ + sizeof(struct name_us##_state), \ + NAME##_DIGEST_SIZE, \ + NAME##_BLOCK_SIZE, \ + (nettle_hash_block_init_func *) name_us##_block_init, \ + (nettle_hash_block_update_func *) name_us##_block_update, \ + (nettle_hash_block_digest_func *) name_us##_block_digest \ +} + /* null-terminated list of digests implemented by this version of nettle */ const struct nettle_hash * const * _NETTLE_ATTRIBUTE_PURE nettle_get_hashes (void); @@ -186,6 +196,8 @@ extern const struct nettle_bctx_hash nettle_bctx_ripemd160; extern const struct nettle_bctx_hash nettle_bctx_sha1; extern const struct nettle_bctx_hash nettle_bctx_sha224; extern const struct nettle_bctx_hash nettle_bctx_sha256; +extern const struct nettle_bctx_hash nettle_bctx_sha384; +extern const struct nettle_bctx_hash nettle_bctx_sha512;
struct nettle_aead { diff --git a/sha2.h b/sha2.h index 95640b5f4b7f..4f8f5c300822 100644 --- a/sha2.h +++ b/sha2.h @@ -53,9 +53,14 @@ extern "C" { #define sha256_block_digest nettle_sha256_block_digest #define sha384_init nettle_sha384_init #define sha384_digest nettle_sha384_digest +#define sha384_block_init nettle_sha384_block_init +#define sha384_block_digest nettle_sha384_block_digest #define sha512_init nettle_sha512_init #define sha512_update nettle_sha512_update #define sha512_digest nettle_sha512_digest +#define sha512_block_init nettle_sha512_block_init +#define sha512_block_update nettle_sha512_block_update +#define sha512_block_digest nettle_sha512_block_digest #define sha512_224_init nettle_sha512_224_init #define sha512_224_digest nettle_sha512_224_digest #define sha512_256_init nettle_sha512_256_init @@ -153,12 +158,16 @@ sha224_block_digest(struct sha256_state *state, /* Digest is kept internally as 8 64-bit words. */ #define _SHA512_DIGEST_LENGTH 8
-struct sha512_ctx +struct sha512_state { uint64_t state[_SHA512_DIGEST_LENGTH]; /* State variables */ uint64_t count_low, count_high; /* 128-bit block count */ - unsigned int index; /* index into buffer */ - uint8_t block[SHA512_BLOCK_SIZE]; /* SHA512 data buffer */ +}; + +struct sha512_ctx +{ + struct sha512_state state; + BLOCK_CTX(SHA512_BLOCK_SIZE); };
void @@ -174,12 +183,28 @@ sha512_digest(struct sha512_ctx *ctx, size_t length, uint8_t *digest);
+void +sha512_block_init(struct sha512_state *state, + struct block_ctx *bctx); + +void +sha512_block_update(struct sha512_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data); + +void +sha512_block_digest(struct sha512_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest);
/* SHA384, a truncated SHA512 with different initial state. */
#define SHA384_DIGEST_SIZE 48 #define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE #define sha384_ctx sha512_ctx +#define sha384_state sha512_state
void sha384_init(struct sha512_ctx *ctx); @@ -191,6 +216,18 @@ sha384_digest(struct sha512_ctx *ctx, size_t length, uint8_t *digest);
+void +sha384_block_init(struct sha512_state *state, + struct block_ctx *bctx); + +#define sha384_block_update sha512_block_update + +void +sha384_block_digest(struct sha512_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest); +
/* SHA512_224 and SHA512_256, two truncated versions of SHA512 with different initial states. */ @@ -222,7 +259,7 @@ void sha512_256_digest(struct sha512_256_ctx *ctx, size_t length, uint8_t *digest); - + #ifdef __cplusplus } #endif diff --git a/sha384-meta.c b/sha384-meta.c index 0eb561054a73..7c842f1b1b44 100644 --- a/sha384-meta.c +++ b/sha384-meta.c @@ -39,3 +39,6 @@
const struct nettle_hash nettle_sha384 = _NETTLE_HASH(sha384, SHA384); + +const struct nettle_bctx_hash nettle_bctx_sha384 += _NETTLE_BLOCK_HASH(sha384, SHA384); diff --git a/sha512-meta.c b/sha512-meta.c index d592c4bec6c7..c61812d5a8e1 100644 --- a/sha512-meta.c +++ b/sha512-meta.c @@ -39,3 +39,6 @@
const struct nettle_hash nettle_sha512 = _NETTLE_HASH(sha512, SHA512); + +const struct nettle_bctx_hash nettle_bctx_sha512 += _NETTLE_BLOCK_HASH(sha512, SHA512); diff --git a/sha512.c b/sha512.c index 6936cb501142..16d79a989955 100644 --- a/sha512.c +++ b/sha512.c @@ -116,7 +116,7 @@ K[80] = #define COMPRESS(ctx, data) (_nettle_sha512_compress((ctx)->state, (data), K))
void -sha512_init(struct sha512_ctx *ctx) +sha512_block_init(struct sha512_state *state, struct block_ctx *bctx) { /* Initial values, generated by the gp script { @@ -135,24 +135,40 @@ sha512_init(struct sha512_ctx *ctx) 0x1F83D9ABFB41BD6BULL,0x5BE0CD19137E2179ULL, };
- memcpy(ctx->state, H0, sizeof(H0)); + memcpy(state->state, H0, sizeof(H0));
/* Initialize bit count */ - ctx->count_low = ctx->count_high = 0; + state->count_low = state->count_high = 0;
/* Initialize buffer */ - ctx->index = 0; + bctx->index = 0; +} + +void +sha512_init(struct sha512_ctx *ctx) +{ + return sha512_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
void sha512_update(struct sha512_ctx *ctx, size_t length, const uint8_t *data) { - MD_UPDATE (ctx, length, data, COMPRESS, MD_INCR(ctx)); + MD_BLOCK_UPDATE (&ctx->state, &ctx->block, SHA512_BLOCK_SIZE, length, data, COMPRESS, MD_INCR(&ctx->state)); +} + +void +sha512_block_update(struct sha512_state *state, + struct block_ctx *bctx, + size_t length, + const uint8_t *data) +{ + MD_BLOCK_UPDATE(state, bctx, SHA512_BLOCK_SIZE, length, data, COMPRESS, MD_INCR(state)); }
static void -sha512_write_digest(struct sha512_ctx *ctx, +sha512_write_digest(struct sha512_state *state, + struct block_ctx *bctx, size_t length, uint8_t *digest) { @@ -164,29 +180,29 @@ sha512_write_digest(struct sha512_ctx *ctx,
assert(length <= SHA512_DIGEST_SIZE);
- MD_PAD(ctx, 16, COMPRESS); + MD_BLOCK_PAD(state, bctx, SHA512_BLOCK_SIZE, 16, COMPRESS);
/* There are 1024 = 2^10 bits in one block */ - high = (ctx->count_high << 10) | (ctx->count_low >> 54); - low = (ctx->count_low << 10) | (ctx->index << 3); + high = (state->count_high << 10) | (state->count_low >> 54); + low = (state->count_low << 10) | (bctx->index << 3);
/* This is slightly inefficient, as the numbers are converted to big-endian format, and will be converted back by the compression function. It's probably not worth the effort to fix this. */ - WRITE_UINT64(ctx->block + (SHA512_BLOCK_SIZE - 16), high); - WRITE_UINT64(ctx->block + (SHA512_BLOCK_SIZE - 8), low); - COMPRESS(ctx, ctx->block); + WRITE_UINT64(bctx->buffer + (SHA512_BLOCK_SIZE - 16), high); + WRITE_UINT64(bctx->buffer + (SHA512_BLOCK_SIZE - 8), low); + COMPRESS(state, bctx->buffer);
words = length / 8; leftover = length % 8;
for (i = 0; i < words; i++, digest += 8) - WRITE_UINT64(digest, ctx->state[i]); + WRITE_UINT64(digest, state->state[i]);
if (leftover) { /* Truncate to the right size */ - uint64_t word = ctx->state[i] >> (8*(8 - leftover)); + uint64_t word = state->state[i] >> (8*(8 - leftover));
do { digest[--leftover] = word & 0xff; @@ -202,13 +218,23 @@ sha512_digest(struct sha512_ctx *ctx, { assert(length <= SHA512_DIGEST_SIZE);
- sha512_write_digest(ctx, length, digest); + sha512_write_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); sha512_init(ctx); }
+void +sha512_block_digest(struct sha512_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest) +{ + sha512_write_digest(state, bctx, length, digest); + sha512_block_init(state, bctx); +} + /* sha384 variant. */ void -sha384_init(struct sha512_ctx *ctx) +sha384_block_init(struct sha512_state *state, struct block_ctx *bctx) { /* Initial values, generated by the gp script { @@ -227,13 +253,19 @@ sha384_init(struct sha512_ctx *ctx) 0xDB0C2E0D64F98FA7ULL, 0x47B5481DBEFA4FA4ULL, };
- memcpy(ctx->state, H0, sizeof(H0)); + memcpy(state->state, H0, sizeof(H0));
/* Initialize bit count */ - ctx->count_low = ctx->count_high = 0; + state->count_low = state->count_high = 0;
/* Initialize buffer */ - ctx->index = 0; + bctx->index = 0; +} + +void +sha384_init(struct sha512_ctx *ctx) +{ + return sha384_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
void @@ -243,14 +275,26 @@ sha384_digest(struct sha512_ctx *ctx, { assert(length <= SHA384_DIGEST_SIZE);
- sha512_write_digest(ctx, length, digest); + sha512_write_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); sha384_init(ctx); }
-/* sha-512/224 variant. */ void -sha512_224_init(struct sha512_224_ctx *ctx) +sha384_block_digest(struct sha512_state *state, + struct block_ctx *bctx, + size_t length, + uint8_t *digest) +{ + assert(length <= SHA384_DIGEST_SIZE); + + sha512_write_digest(state, bctx, length, digest); + sha384_block_init(state, bctx); +} + +/* sha-512/224 variant. */ +static void +sha512_224_block_init(struct sha512_state *state, struct block_ctx *bctx) { static const uint64_t H0[_SHA512_DIGEST_LENGTH] = { @@ -260,30 +304,37 @@ sha512_224_init(struct sha512_224_ctx *ctx) 0x3f9d85a86a1d36c8ULL, 0x1112e6ad91d692a1ULL, };
- memcpy(ctx->state, H0, sizeof(H0)); + memcpy(state->state, H0, sizeof(H0));
/* Initialize bit count */ - ctx->count_low = ctx->count_high = 0; + state->count_low = state->count_high = 0;
/* Initialize buffer */ - ctx->index = 0; + bctx->index = 0; +} + +void +sha512_224_init(struct sha512_ctx *ctx) +{ + return sha512_224_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
void sha512_224_digest(struct sha512_224_ctx *ctx, - size_t length, - uint8_t *digest) + size_t length, + uint8_t *digest) { assert(length <= SHA224_DIGEST_SIZE);
- sha512_write_digest(ctx, length, digest); + sha512_write_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); sha512_224_init(ctx); }
/* sha-512/256 variant. */ -void -sha512_256_init(struct sha512_256_ctx *ctx) +static void +sha512_256_block_init(struct sha512_state *state, + struct block_ctx *bctx) { static const uint64_t H0[_SHA512_DIGEST_LENGTH] = { @@ -293,22 +344,28 @@ sha512_256_init(struct sha512_256_ctx *ctx) 0x2b0199fc2c85b8aaULL, 0x0eb72ddc81c52ca2ULL, };
- memcpy(ctx->state, H0, sizeof(H0)); + memcpy(state->state, H0, sizeof(H0));
/* Initialize bit count */ - ctx->count_low = ctx->count_high = 0; + state->count_low = state->count_high = 0;
/* Initialize buffer */ - ctx->index = 0; + bctx->index = 0; +} + +void +sha512_256_init(struct sha512_256_ctx *ctx) +{ + sha512_256_block_init(&ctx->state, (struct block_ctx *)&ctx->block); }
void sha512_256_digest(struct sha512_256_ctx *ctx, - size_t length, - uint8_t *digest) + size_t length, + uint8_t *digest) { assert(length <= SHA256_DIGEST_SIZE);
- sha512_write_digest(ctx, length, digest); + sha512_write_digest(&ctx->state, (struct block_ctx *)&ctx->block, length, digest); sha512_256_init(ctx); }
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- hmac-sha384.c | 4 ++-- hmac-sha512.c | 6 +++--- hmac.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/hmac-sha384.c b/hmac-sha384.c index 30008b5f85c1..d162c4a0fab8 100644 --- a/hmac-sha384.c +++ b/hmac-sha384.c @@ -41,12 +41,12 @@ void hmac_sha384_set_key(struct hmac_sha512_ctx *ctx, size_t key_length, const uint8_t *key) { - HMAC_SET_KEY(ctx, &nettle_sha384, key_length, key); + HMAC_BLOCK_SET_KEY(ctx, &nettle_bctx_sha384, key_length, key); }
void hmac_sha384_digest(struct hmac_sha512_ctx *ctx, size_t length, uint8_t *digest) { - HMAC_DIGEST(ctx, &nettle_sha384, length, digest); + HMAC_BLOCK_DIGEST(ctx, &nettle_bctx_sha384, length, digest); } diff --git a/hmac-sha512.c b/hmac-sha512.c index de64637a8216..8028fb3f5518 100644 --- a/hmac-sha512.c +++ b/hmac-sha512.c @@ -41,19 +41,19 @@ void hmac_sha512_set_key(struct hmac_sha512_ctx *ctx, size_t key_length, const uint8_t *key) { - HMAC_SET_KEY(ctx, &nettle_sha512, key_length, key); + HMAC_BLOCK_SET_KEY(ctx, &nettle_bctx_sha512, key_length, key); }
void hmac_sha512_update(struct hmac_sha512_ctx *ctx, size_t length, const uint8_t *data) { - sha512_update(&ctx->state, length, data); + sha512_block_update(&ctx->state, (struct block_ctx *)&ctx->block, length, data); }
void hmac_sha512_digest(struct hmac_sha512_ctx *ctx, size_t length, uint8_t *digest) { - HMAC_DIGEST(ctx, &nettle_sha512, length, digest); + HMAC_BLOCK_DIGEST(ctx, &nettle_bctx_sha512, length, digest); } diff --git a/hmac.h b/hmac.h index 445d7c95e03f..ed0210857ade 100644 --- a/hmac.h +++ b/hmac.h @@ -203,7 +203,7 @@ hmac_sha224_digest(struct hmac_sha224_ctx *ctx, size_t length, uint8_t *digest);
/* hmac-sha512 */ -struct hmac_sha512_ctx HMAC_CTX(struct sha512_ctx); +struct hmac_sha512_ctx HMAC_BLOCK_CTX(struct sha512_state, SHA512_BLOCK_SIZE);
void hmac_sha512_set_key(struct hmac_sha512_ctx *ctx,
nettle-bugs@lists.lysator.liu.se