Add GOST R 34.11-94 variant using id-GostR3411-94-CryptoProParamSet
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Fri, 6 Jun 2014 18:48:32 +0000 (22:48 +0400)
committerWerner Koch <wk@gnupg.org>
Sat, 28 Jun 2014 08:44:37 +0000 (10:44 +0200)
* 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>
NEWS
cipher/gost.h
cipher/gost28147.c
cipher/gostr3411-94.c
cipher/md.c
src/cipher.h
src/gcrypt.h.in

diff --git a/NEWS b/NEWS
index 5eacf30..214c676 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,7 @@ Noteworthy changes in version 1.7.0 (unreleased)
  GCRY_MD_FLAG_BUGEMU1            NEW.
  GCRYCTL_SET_SBOX                NEW.
  gcry_cipher_set_sbox            NEW macro.
+ GCRY_MD_GOSTR3411_CP            NEW.
 
 
 Noteworthy changes in version 1.6.0 (2013-12-16)
index 3fbd9df..caaf34b 100644 (file)
@@ -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
index ae9e705..5456053 100644 (file)
@@ -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 *);
 }
index 73d570f..9d065fb 100644 (file)
@@ -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)
+  };
index 5ab89cb..a1e5859 100644 (file)
@@ -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:
index ed57d3c..f4f6cc4 100644 (file)
@@ -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;
index 95d324b..a5f8350 100644 (file)
@@ -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.  */