summaryrefslogtreecommitdiff
path: root/cipher
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2014-06-06 22:48:32 +0400
committerWerner Koch <wk@gnupg.org>2014-06-28 10:44:37 +0200
commit25d6af77e2336b5979ddbe8b90978fe5b61dfaf9 (patch)
treea7872fa22efbd8f41b27e0bd8fc52d0c26098fe1 /cipher
parent5ee35a04362c94e680ef3633fa83b72e0aee8626 (diff)
downloadlibgcrypt-25d6af77e2336b5979ddbe8b90978fe5b61dfaf9.tar.gz
Add GOST R 34.11-94 variant using id-GostR3411-94-CryptoProParamSet
* 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@gmail.com>
Diffstat (limited to 'cipher')
-rw-r--r--cipher/gost.h2
-rw-r--r--cipher/gost28147.c6
-rw-r--r--cipher/gostr3411-94.c29
-rw-r--r--cipher/md.c2
4 files changed, 31 insertions, 8 deletions
diff --git a/cipher/gost.h b/cipher/gost.h
index 3fbd9df2..caaf34ba 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 ae9e705a..5456053e 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 73d570f0..9d065fb9 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 5ab89cbd..a1e5859c 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: