[PATCH 06/10] Add GOST R 34.11-94 variant using id-GostR3411-94-CryptoProParamSet
Dmitry Eremin-Solenikov
dbaryshkov at gmail.com
Fri Jun 6 20:48:32 CEST 2014
* src/gcrypt.h.in (GCRY_MD_GOSTR3411_CP): New.
* src/cipher.h (_gcry_digest_spec_gost3411_cp): New.
* cipher/gost28147.c (_gcry_gost_enc_one): Differentiate between
CryptoPro and Test S-Boxes.
* cipher/gostr3411-94.c (_gcry_digest_spec_gost3411_cp,
gost3411_cp_init): New.
* cipher/md.c (md_open): GCRY_MD_GOSTR3411_CP also uses B=32.
--
RFC4357 defines only two S-Boxes that should be used together with
GOST R 34.11-94 - a testing one (from standard itself, for testing only)
and CryptoPro one. Instead of adding a separate gcry_md_ctrl() function
just to switch s-boxes, add a separate MD algorithm using CryptoPro
S-box.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
---
cipher/gost.h | 2 +-
cipher/gost28147.c | 6 +++++-
cipher/gostr3411-94.c | 29 +++++++++++++++++++++++------
cipher/md.c | 2 ++
src/cipher.h | 1 +
src/gcrypt.h.in | 3 ++-
6 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/cipher/gost.h b/cipher/gost.h
index 3fbd9df..caaf34b 100644
--- a/cipher/gost.h
+++ b/cipher/gost.h
@@ -27,6 +27,6 @@ typedef struct {
/* This is a simple interface that will be used by GOST R 34.11-94 */
extern unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key,
- byte *out, byte *in);
+ byte *out, byte *in, int cryptopro);
#endif
diff --git a/cipher/gost28147.c b/cipher/gost28147.c
index 52d0946..453a024 100644
--- a/cipher/gost28147.c
+++ b/cipher/gost28147.c
@@ -120,8 +120,12 @@ gost_encrypt_block (void *c, byte *outbuf, const byte *inbuf)
}
unsigned int _gcry_gost_enc_one (GOST28147_context *c, const byte *key,
- byte *out, byte *in)
+ byte *out, byte *in, int cryptopro)
{
+ if (cryptopro)
+ c->sbox = sbox_CryptoPro_3411;
+ else
+ c->sbox = sbox_test_3411;
gost_setkey (c, key, 32);
return gost_encrypt_block (c, out, in) + 5 * sizeof(void *);
}
diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c
index 73d570f..9d065fb 100644
--- a/cipher/gostr3411-94.c
+++ b/cipher/gostr3411-94.c
@@ -38,6 +38,7 @@ typedef struct {
byte h[32];
byte sigma[32];
u32 len;
+ int cryptopro;
} GOSTR3411_CONTEXT;
static unsigned int
@@ -58,6 +59,15 @@ gost3411_init (void *context, unsigned int flags)
hd->bctx.count = 0;
hd->bctx.blocksize = 32;
hd->bctx.bwrite = transform;
+ hd->cryptopro = 0;
+}
+
+static void
+gost3411_cp_init (void *context, unsigned int flags)
+{
+ GOSTR3411_CONTEXT *hd = context;
+ gost3411_init (context, flags);
+ hd->cryptopro = 1;
}
static void
@@ -153,7 +163,7 @@ do_add (unsigned char *s, unsigned char *a)
}
static unsigned int
-do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m)
+do_hash_step (GOSTR3411_CONTEXT *hd, unsigned char *h, unsigned char *m)
{
unsigned char u[32], v[32], s[32];
unsigned char k[32];
@@ -166,7 +176,7 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m)
for (i = 0; i < 4; i++) {
do_p (k, u, v);
- burn = _gcry_gost_enc_one (hd, k, s + i*8, h + i*8);
+ burn = _gcry_gost_enc_one (&hd->hd, k, s + i*8, h + i*8, hd->cryptopro);
do_a (u);
if (i == 1)
@@ -220,7 +230,7 @@ transform_blk (void *ctx, const unsigned char *data)
unsigned int burn;
memcpy (m, data, 32);
- burn = do_hash_step (&hd->hd, hd->h, m);
+ burn = do_hash_step (hd, hd->h, m);
do_add (hd->sigma, m);
return /* burn_stack */ burn + 3 * sizeof(void*) + 32 + 2 * sizeof(void*);
@@ -283,8 +293,8 @@ gost3411_final (void *context)
nblocks /= 256;
}
- do_hash_step (&hd->hd, hd->h, l);
- do_hash_step (&hd->hd, hd->h, hd->sigma);
+ do_hash_step (hd, hd->h, l);
+ do_hash_step (hd, hd->h, hd->sigma);
}
static byte *
@@ -310,7 +320,14 @@ static gcry_md_oid_spec_t oid_spec_gostr3411[] =
gcry_md_spec_t _gcry_digest_spec_gost3411_94 =
{
GCRY_MD_GOSTR3411_94, {0, 0},
- "GOSTR3411_94", asn, DIM (asn), oid_spec_gostr3411, 32,
+ "GOSTR3411_94", NULL, 0, NULL, 32,
gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read,
sizeof (GOSTR3411_CONTEXT)
};
+gcry_md_spec_t _gcry_digest_spec_gost3411_cp =
+ {
+ GCRY_MD_GOSTR3411_CP, {0, 0},
+ "GOSTR3411_CP", asn, DIM (asn), oid_spec_gostr3411, 32,
+ gost3411_cp_init, _gcry_md_block_write, gost3411_final, gost3411_read,
+ sizeof (GOSTR3411_CONTEXT)
+ };
diff --git a/cipher/md.c b/cipher/md.c
index 5ab89cb..a1e5859 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -53,6 +53,7 @@ static gcry_md_spec_t *digest_list[] =
#endif
#ifdef USE_GOST_R_3411_94
&_gcry_digest_spec_gost3411_94,
+ &_gcry_digest_spec_gost3411_cp,
#endif
#ifdef USE_GOST_R_3411_12
&_gcry_digest_spec_stribog_256,
@@ -335,6 +336,7 @@ md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
ctx->macpads_Bsize = 128;
break;
case GCRY_MD_GOSTR3411_94:
+ case GCRY_MD_GOSTR3411_CP:
ctx->macpads_Bsize = 32;
break;
default:
diff --git a/src/cipher.h b/src/cipher.h
index ed57d3c..f4f6cc4 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -258,6 +258,7 @@ extern gcry_md_spec_t _gcry_digest_spec_crc32;
extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510;
extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440;
extern gcry_md_spec_t _gcry_digest_spec_gost3411_94;
+extern gcry_md_spec_t _gcry_digest_spec_gost3411_cp;
extern gcry_md_spec_t _gcry_digest_spec_stribog_256;
extern gcry_md_spec_t _gcry_digest_spec_stribog_512;
extern gcry_md_spec_t _gcry_digest_spec_md2;
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 95d324b..a5f8350 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -1152,7 +1152,8 @@ enum gcry_md_algos
GCRY_MD_TIGER2 = 307, /* TIGER2 variant. */
GCRY_MD_GOSTR3411_94 = 308, /* GOST R 34.11-94. */
GCRY_MD_STRIBOG256 = 309, /* GOST R 34.11-2012, 256 bit. */
- GCRY_MD_STRIBOG512 = 310 /* GOST R 34.11-2012, 512 bit. */
+ GCRY_MD_STRIBOG512 = 310, /* GOST R 34.11-2012, 512 bit. */
+ GCRY_MD_GOSTR3411_CP = 311 /* GOST R 34.11-94 with CryptoPro-A S-Box. */
};
/* Flags used with the open function. */
--
2.0.0.rc2
More information about the Gcrypt-devel
mailing list