From 9826eed6b23296eac9e496232ba1b74c1d205694 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 11 Jul 2019 21:43:12 +0300 Subject: Add support for GOSTHASH94CP: GOST R 34.11-94 hash with CryptoPro S-box Hash gosthash94 implements GOST R 34.11-94 standard using S-Box defined in the standard 'for testing purposes only'. RFC 4357 defines S-Box (CryptoPro one) for GOST R 34.11-94 hash function that is widely used in applications. Add separate hash function algorithm (gosthash94cp) implementing GOST R 34.11-94 hashing using that S-Box. Signed-off-by: Dmitry Eremin-Solenikov --- gosthash94.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 15 deletions(-) (limited to 'gosthash94.c') diff --git a/gosthash94.c b/gosthash94.c index 53716ca7..954130f7 100644 --- a/gosthash94.c +++ b/gosthash94.c @@ -5,6 +5,7 @@ * See also RFC 4357. * * Copyright: 2009-2012 Aleksey Kravchenko + * Copyright: 2019 Dmitry Eremin-Solenikov * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -62,7 +63,8 @@ gosthash94_init (struct gosthash94_ctx *ctx) * @param block the message block to process */ static void -gost_block_compress (struct gosthash94_ctx *ctx, const uint32_t *block) +gost_block_compress (struct gosthash94_ctx *ctx, const uint32_t *block, + const uint32_t sbox[4][256]) { unsigned i; uint32_t key[8], u[8], v[8], w[8], s[8]; @@ -107,7 +109,7 @@ gost_block_compress (struct gosthash94_ctx *ctx, const uint32_t *block) ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000); /* encryption: s_i := E_{key_i} (h_i) */ - _gost28147_encrypt_block (key, gost28147_param_test_3411.sbox, &ctx->hash[i], &s[i]); + _gost28147_encrypt_block (key, sbox, &ctx->hash[i], &s[i]); if (i == 0) { @@ -262,7 +264,8 @@ gost_block_compress (struct gosthash94_ctx *ctx, const uint32_t *block) * @param block the 256-bit message block to process */ static void -gost_compute_sum_and_hash (struct gosthash94_ctx *ctx, const uint8_t *block) +gost_compute_sum_and_hash (struct gosthash94_ctx *ctx, const uint8_t *block, + const uint32_t sbox[4][256]) { uint32_t block_le[8]; unsigned i, carry; @@ -278,7 +281,7 @@ gost_compute_sum_and_hash (struct gosthash94_ctx *ctx, const uint8_t *block) } /* update message hash */ - gost_block_compress (ctx, block_le); + gost_block_compress (ctx, block_le, sbox); } /** @@ -289,9 +292,10 @@ gost_compute_sum_and_hash (struct gosthash94_ctx *ctx, const uint8_t *block) * @param msg message chunk * @param size length of the message chunk */ -void -gosthash94_update (struct gosthash94_ctx *ctx, - size_t length, const uint8_t *msg) +static void +gosthash94_update_int (struct gosthash94_ctx *ctx, + size_t length, const uint8_t *msg, + const uint32_t sbox[4][256]) { unsigned index = (unsigned) ctx->length & 31; ctx->length += length; @@ -305,13 +309,13 @@ gosthash94_update (struct gosthash94_ctx *ctx, return; /* process partial block */ - gost_compute_sum_and_hash (ctx, ctx->message); + gost_compute_sum_and_hash (ctx, ctx->message, sbox); msg += left; length -= left; } while (length >= GOSTHASH94_BLOCK_SIZE) { - gost_compute_sum_and_hash (ctx, msg); + gost_compute_sum_and_hash (ctx, msg, sbox); msg += GOSTHASH94_BLOCK_SIZE; length -= GOSTHASH94_BLOCK_SIZE; } @@ -322,15 +326,48 @@ gosthash94_update (struct gosthash94_ctx *ctx, } } +/** + * Calculate message hash. + * Can be called repeatedly with chunks of the message to be hashed. + * + * @param ctx the algorithm context containing current hashing state + * @param msg message chunk + * @param size length of the message chunk + */ +void +gosthash94_update (struct gosthash94_ctx *ctx, + size_t length, const uint8_t *msg) +{ + gosthash94_update_int (ctx, length, msg, + gost28147_param_test_3411.sbox); +} + +/** + * Calculate message hash. + * Can be called repeatedly with chunks of the message to be hashed. + * + * @param ctx the algorithm context containing current hashing state + * @param msg message chunk + * @param size length of the message chunk + */ +void +gosthash94cp_update (struct gosthash94_ctx *ctx, + size_t length, const uint8_t *msg) +{ + gosthash94_update_int (ctx, length, msg, + gost28147_param_CryptoPro_3411.sbox); +} + /** * Finish hashing and store message digest into given array. * * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void -gosthash94_digest (struct gosthash94_ctx *ctx, - size_t length, uint8_t *result) +static void +gosthash94_write_digest (struct gosthash94_ctx *ctx, + size_t length, uint8_t *result, + const uint32_t sbox[4][256]) { unsigned index = ctx->length & 31; uint32_t msg32[8]; @@ -341,7 +378,7 @@ gosthash94_digest (struct gosthash94_ctx *ctx, if (index > 0) { memset (ctx->message + index, 0, 32 - index); - gost_compute_sum_and_hash (ctx, ctx->message); + gost_compute_sum_and_hash (ctx, ctx->message, sbox); } /* hash the message length and the sum */ @@ -349,10 +386,26 @@ gosthash94_digest (struct gosthash94_ctx *ctx, msg32[1] = ctx->length >> 29; memset (msg32 + 2, 0, sizeof (uint32_t) * 6); - gost_block_compress (ctx, msg32); - gost_block_compress (ctx, ctx->sum); + gost_block_compress (ctx, msg32, sbox); + gost_block_compress (ctx, ctx->sum, sbox); /* convert hash state to result bytes */ _nettle_write_le32(length, result, ctx->hash); gosthash94_init (ctx); } + +void +gosthash94_digest (struct gosthash94_ctx *ctx, + size_t length, uint8_t *result) +{ + gosthash94_write_digest (ctx, length, result, + gost28147_param_test_3411.sbox); +} + +void +gosthash94cp_digest (struct gosthash94_ctx *ctx, + size_t length, uint8_t *result) +{ + gosthash94_write_digest (ctx, length, result, + gost28147_param_CryptoPro_3411.sbox); +} -- cgit v1.2.1