summaryrefslogtreecommitdiff
path: root/gosthash94.c
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2019-07-11 21:43:12 +0300
committerNiels Möller <nisse@lysator.liu.se>2019-09-15 10:09:16 +0200
commit9826eed6b23296eac9e496232ba1b74c1d205694 (patch)
treea98cc76853465cf6abd9f49843985c076b8d6156 /gosthash94.c
parent1d7bce28f88b493854810ce21468a996b4d857f1 (diff)
downloadnettle-9826eed6b23296eac9e496232ba1b74c1d205694.tar.gz
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 <dbaryshkov@gmail.com>
Diffstat (limited to 'gosthash94.c')
-rw-r--r--gosthash94.c83
1 files changed, 68 insertions, 15 deletions
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 <rhash.admin@gmail.com>
+ * Copyright: 2019 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
*
* 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;
}
@@ -323,14 +327,47 @@ 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);
+}