Add hash_buffer and hash_buffers pointers to message digest spec
authorJussi Kivilinna <jussi.kivilinna@iki.fi>
Tue, 19 Jun 2018 15:34:33 +0000 (18:34 +0300)
committerJussi Kivilinna <jussi.kivilinna@iki.fi>
Tue, 19 Jun 2018 16:29:25 +0000 (19:29 +0300)
* src/cipher-proto.h (gcry_md_hash_buffer_t)
(gcry_md_hash_buffers_t): New.
(gcry_md_spec): Add hash_buffer and hash_buffers.
* cipher/md.c (_gcry_md_hash_buffer, _gcry_md_hash_buffers): Use
hash_buffer/hash_buffers from MD spec instead of hard-coding supported
algorithms.
* cipher/blake2.c: Add NULL to MD spec hash_buffer and hash_buffers
pointers.
* cipher/crc.c: Ditto.
* cipher/gostr3411-94.c: Ditto.
* cipher/keccak.c: Ditto.
* cipher/md2.c: Ditto.
* cipher/md4.c: Ditto.
* cipher/md5.c: Ditto.
* cipher/stribog.c: Ditto.
* cipher/tiger.c: Ditto.
* cipher/whirlpool.c: Ditto.
* cipher/rmd160.c (_gcry_rmd160_hash_buffers): New.
(_gcry_digest_spec_rmd160): Add hash_buffer and hash_buffers functions.
* cipher/sha1.c (_gcry_digest_spec_sha1): Add hash_buffer and
hash_buffers functions.
* cipher/sha256.c (_gcry_digest_spec_sha256): Add hash_buffer and
hash_buffers functions.
(_gcry_digest_spec_sha224): Add NULL pointers for hash_buffer and
hash_buffers.
* cipher/sha512.c (_gcry_digest_spec_sha1): Add hash_buffer and
hash_buffers functions.
(_gcry_digest_spec_sha384): Add NULL pointers for hash_buffer and
hash_buffers.
* cipher/sm3.c (_gcry_digest_spec_sha1): Add hash_buffer and
hash_buffers functions.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
18 files changed:
cipher/blake2.c
cipher/crc.c
cipher/gostr3411-94.c
cipher/keccak.c
cipher/md.c
cipher/md2.c
cipher/md4.c
cipher/md5.c
cipher/rmd160.c
cipher/sha1.c
cipher/sha256.c
cipher/sha512.c
cipher/sm3.c
cipher/stribog.c
cipher/tiger.c
cipher/whirlpool.c
src/cipher-proto.h
src/cipher.h

index 0f7494f..bfd24b9 100644 (file)
@@ -958,6 +958,7 @@ gcry_err_code_t _gcry_blake2_init_with_key(void *ctx, unsigned int flags,
       DIM (blake2##bs##_##dbits##_asn), oid_spec_blake2##bs##_##dbits, \
       dbits / 8, blake2##bs##_##dbits##_init, blake2##bs##_write, \
       blake2##bs##_final, blake2##bs##_read, NULL, \
+      NULL, NULL, \
       sizeof (BLAKE2##BS##_CONTEXT), selftests_blake2##bs \
     };
 
index a1ce50b..4457ff6 100644 (file)
@@ -841,6 +841,7 @@ gcry_md_spec_t _gcry_digest_spec_crc32 =
     GCRY_MD_CRC32, {0, 1},
     "CRC32", NULL, 0, NULL, 4,
     crc32_init, crc32_write, crc32_final, crc32_read, NULL,
+    NULL, NULL,
     sizeof (CRC_CONTEXT)
   };
 
@@ -849,6 +850,7 @@ gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
     GCRY_MD_CRC32_RFC1510, {0, 1},
     "CRC32RFC1510", NULL, 0, NULL, 4,
     crc32rfc1510_init, crc32_write, crc32rfc1510_final, crc32_read, NULL,
+    NULL, NULL,
     sizeof (CRC_CONTEXT)
   };
 
@@ -857,5 +859,6 @@ gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
     GCRY_MD_CRC24_RFC2440, {0, 1},
     "CRC24RFC2440", NULL, 0, NULL, 3,
     crc24rfc2440_init, crc24rfc2440_write, crc24rfc2440_final, crc32_read, NULL,
+    NULL, NULL,
     sizeof (CRC_CONTEXT)
   };
index a782427..d974627 100644 (file)
@@ -344,6 +344,7 @@ gcry_md_spec_t _gcry_digest_spec_gost3411_94 =
     GCRY_MD_GOSTR3411_94, {0, 0},
     "GOSTR3411_94", NULL, 0, NULL, 32,
     gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read, NULL,
+    NULL, NULL,
     sizeof (GOSTR3411_CONTEXT)
   };
 gcry_md_spec_t _gcry_digest_spec_gost3411_cp =
@@ -351,5 +352,6 @@ 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, NULL,
+    NULL, NULL,
     sizeof (GOSTR3411_CONTEXT)
   };
index 0bb3155..db67d07 100644 (file)
@@ -1221,6 +1221,7 @@ gcry_md_spec_t _gcry_digest_spec_sha3_224 =
     GCRY_MD_SHA3_224, {0, 1},
     "SHA3-224", sha3_224_asn, DIM (sha3_224_asn), oid_spec_sha3_224, 28,
     sha3_224_init, keccak_write, keccak_final, keccak_read, NULL,
+    NULL, NULL,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
@@ -1229,6 +1230,7 @@ gcry_md_spec_t _gcry_digest_spec_sha3_256 =
     GCRY_MD_SHA3_256, {0, 1},
     "SHA3-256", sha3_256_asn, DIM (sha3_256_asn), oid_spec_sha3_256, 32,
     sha3_256_init, keccak_write, keccak_final, keccak_read, NULL,
+    NULL, NULL,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
@@ -1237,6 +1239,7 @@ gcry_md_spec_t _gcry_digest_spec_sha3_384 =
     GCRY_MD_SHA3_384, {0, 1},
     "SHA3-384", sha3_384_asn, DIM (sha3_384_asn), oid_spec_sha3_384, 48,
     sha3_384_init, keccak_write, keccak_final, keccak_read, NULL,
+    NULL, NULL,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
@@ -1245,6 +1248,7 @@ gcry_md_spec_t _gcry_digest_spec_sha3_512 =
     GCRY_MD_SHA3_512, {0, 1},
     "SHA3-512", sha3_512_asn, DIM (sha3_512_asn), oid_spec_sha3_512, 64,
     sha3_512_init, keccak_write, keccak_final, keccak_read, NULL,
+    NULL, NULL,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
@@ -1253,6 +1257,7 @@ gcry_md_spec_t _gcry_digest_spec_shake128 =
     GCRY_MD_SHAKE128, {0, 1},
     "SHAKE128", shake128_asn, DIM (shake128_asn), oid_spec_shake128, 0,
     shake128_init, keccak_write, keccak_final, NULL, keccak_extract,
+    NULL, NULL,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
@@ -1261,6 +1266,7 @@ gcry_md_spec_t _gcry_digest_spec_shake256 =
     GCRY_MD_SHAKE256, {0, 1},
     "SHAKE256", shake256_asn, DIM (shake256_asn), oid_spec_shake256, 0,
     shake256_init, keccak_write, keccak_final, NULL, keccak_extract,
+    NULL, NULL,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
index 47c8cec..15e19a9 100644 (file)
@@ -1174,46 +1174,52 @@ void
 _gcry_md_hash_buffer (int algo, void *digest,
                       const void *buffer, size_t length)
 {
-  if (0)
-    ;
-#if USE_SHA256
-  else if (algo == GCRY_MD_SHA256)
-    _gcry_sha256_hash_buffer (digest, buffer, length);
-#endif
-#if USE_SHA512
-  else if (algo == GCRY_MD_SHA512)
-    _gcry_sha512_hash_buffer (digest, buffer, length);
-#endif
-#if USE_SHA1
-  else if (algo == GCRY_MD_SHA1)
-    _gcry_sha1_hash_buffer (digest, buffer, length);
-#endif
-#if USE_RMD160
-  else if (algo == GCRY_MD_RMD160 && !fips_mode () )
-    _gcry_rmd160_hash_buffer (digest, buffer, length);
-#endif
+  gcry_md_spec_t *spec;
+
+  spec = spec_from_algo (algo);
+  if (!spec)
+    {
+      log_debug ("md_hash_buffer: algorithm %d not available\n", algo);
+      return;
+    }
+
+  if (algo == GCRY_MD_MD5 && fips_mode ())
+    {
+      _gcry_inactivate_fips_mode ("MD5 used");
+      if (_gcry_enforced_fips_mode () )
+        {
+          /* We should never get to here because we do not register
+             MD5 in enforced fips mode.  */
+          _gcry_fips_noreturn ();
+        }
+    }
+
+  if (spec->hash_buffer != NULL)
+    {
+      spec->hash_buffer (digest, buffer, length);
+    }
+  else if (spec->hash_buffers != NULL)
+    {
+      gcry_buffer_t iov;
+
+      iov.size = 0;
+      iov.data = (void *)buffer;
+      iov.off = 0;
+      iov.len = length;
+
+      spec->hash_buffers (digest, &iov, 1);
+    }
   else
     {
       /* For the others we do not have a fast function, so we use the
-        normal functions. */
+         normal functions. */
       gcry_md_hd_t h;
       gpg_err_code_t err;
 
-      if (algo == GCRY_MD_MD5 && fips_mode ())
-        {
-          _gcry_inactivate_fips_mode ("MD5 used");
-          if (_gcry_enforced_fips_mode () )
-            {
-              /* We should never get to here because we do not register
-                 MD5 in enforced fips mode.  */
-              _gcry_fips_noreturn ();
-            }
-        }
-
       err = md_open (&h, algo, 0);
       if (err)
-       log_bug ("gcry_md_open failed for algo %d: %s",
-                 algo, gpg_strerror (gcry_error(err)));
+        log_bug ("gcry_md_open failed for algo %d: %s",
+                algo, gpg_strerror (gcry_error(err)));
       md_write (h, (byte *) buffer, length);
       md_final (h);
       memcpy (digest, md_read (h, algo), md_digest_length (algo));
@@ -1240,6 +1246,7 @@ gpg_err_code_t
 _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
                        const gcry_buffer_t *iov, int iovcnt)
 {
+  gcry_md_spec_t *spec;
   int hmac;
 
   if (!iov || iovcnt < 0)
@@ -1251,39 +1258,36 @@ _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
   if (hmac && iovcnt < 1)
     return GPG_ERR_INV_ARG;
 
-  if (0)
-    ;
-#if USE_SHA256
-  else if (algo == GCRY_MD_SHA256 && !hmac)
-    _gcry_sha256_hash_buffers (digest, iov, iovcnt);
-#endif
-#if USE_SHA512
-  else if (algo == GCRY_MD_SHA512 && !hmac)
-    _gcry_sha512_hash_buffers (digest, iov, iovcnt);
-#endif
-#if USE_SHA1
-  else if (algo == GCRY_MD_SHA1 && !hmac)
-    _gcry_sha1_hash_buffers (digest, iov, iovcnt);
-#endif
+  spec = spec_from_algo (algo);
+  if (!spec)
+    {
+      log_debug ("md_hash_buffers: algorithm %d not available\n", algo);
+      return GPG_ERR_DIGEST_ALGO;
+    }
+
+  if (algo == GCRY_MD_MD5 && fips_mode ())
+    {
+      _gcry_inactivate_fips_mode ("MD5 used");
+      if (_gcry_enforced_fips_mode () )
+        {
+          /* We should never get to here because we do not register
+             MD5 in enforced fips mode.  */
+          _gcry_fips_noreturn ();
+        }
+    }
+
+  if (!hmac && spec->hash_buffers)
+    {
+      spec->hash_buffers (digest, iov, iovcnt);
+    }
   else
     {
       /* For the others we do not have a fast function, so we use the
-        normal functions.  */
+         normal functions.  */
       gcry_md_hd_t h;
       gpg_err_code_t rc;
       int dlen;
 
-      if (algo == GCRY_MD_MD5 && fips_mode ())
-        {
-          _gcry_inactivate_fips_mode ("MD5 used");
-          if (_gcry_enforced_fips_mode () )
-            {
-              /* We should never get to here because we do not register
-                 MD5 in enforced fips mode.  */
-              _gcry_fips_noreturn ();
-            }
-        }
-
       /* Detect SHAKE128 like algorithms which we can't use because
        * our API does not allow for a variable length digest.  */
       dlen = md_digest_length (algo);
index e339b28..b6f7e94 100644 (file)
@@ -178,5 +178,6 @@ gcry_md_spec_t _gcry_digest_spec_md2 =
     GCRY_MD_MD2, {0, 0},
     "MD2", asn, DIM (asn), oid_spec_md2, 16,
     md2_init, _gcry_md_block_write, md2_final, md2_read, NULL,
+    NULL, NULL,
     sizeof (MD2_CONTEXT)
   };
index afa6382..0983808 100644 (file)
@@ -287,5 +287,6 @@ gcry_md_spec_t _gcry_digest_spec_md4 =
     GCRY_MD_MD4, {0, 0},
     "MD4", asn, DIM (asn), oid_spec_md4,16,
     md4_init, _gcry_md_block_write, md4_final, md4_read, NULL,
+    NULL, NULL,
     sizeof (MD4_CONTEXT)
   };
index ed942cf..e35a500 100644 (file)
@@ -313,5 +313,6 @@ gcry_md_spec_t _gcry_digest_spec_md5 =
     GCRY_MD_MD5, {0, 0},
     "MD5", asn, DIM (asn), oid_spec_md5, 16,
     md5_init, _gcry_md_block_write, md5_final, md5_read, NULL,
+    NULL, NULL,
     sizeof (MD5_CONTEXT)
   };
index 0a019b9..2d2fae9 100644 (file)
@@ -486,6 +486,21 @@ _gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
   memcpy ( outbuf, hd.bctx.buf, 20 );
 }
 
+/* Variant of the above shortcut function using a multiple buffers.  */
+static void
+_gcry_rmd160_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+  RMD160_CONTEXT hd;
+
+  rmd160_init (&hd, 0);
+  for (;iovcnt > 0; iov++, iovcnt--)
+    _gcry_md_block_write (&hd,
+                          (const char*)iov[0].data + iov[0].off, iov[0].len);
+  rmd160_final ( &hd );
+  memcpy ( outbuf, hd.bctx.buf, 20 );
+}
+
+
 static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
   { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
     0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
@@ -504,5 +519,6 @@ gcry_md_spec_t _gcry_digest_spec_rmd160 =
     GCRY_MD_RMD160, {0, 0},
     "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
     rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read, NULL,
+    _gcry_rmd160_hash_buffer, _gcry_rmd160_hash_buffers,
     sizeof (RMD160_CONTEXT)
   };
index 09868aa..e50262f 100644 (file)
@@ -665,6 +665,7 @@ gcry_md_spec_t _gcry_digest_spec_sha1 =
     GCRY_MD_SHA1, {0, 1},
     "SHA1", asn, DIM (asn), oid_spec_sha1, 20,
     sha1_init, _gcry_md_block_write, sha1_final, sha1_read, NULL,
+    _gcry_sha1_hash_buffer, _gcry_sha1_hash_buffers,
     sizeof (SHA1_CONTEXT),
     run_selftests
   };
index cb6a860..5c1c13f 100644 (file)
@@ -743,6 +743,7 @@ gcry_md_spec_t _gcry_digest_spec_sha224 =
     GCRY_MD_SHA224, {0, 1},
     "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
     sha224_init, _gcry_md_block_write, sha256_final, sha256_read, NULL,
+    NULL, NULL,
     sizeof (SHA256_CONTEXT),
     run_selftests
   };
@@ -752,6 +753,7 @@ gcry_md_spec_t _gcry_digest_spec_sha256 =
     GCRY_MD_SHA256, {0, 1},
     "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
     sha256_init, _gcry_md_block_write, sha256_final, sha256_read, NULL,
+    _gcry_sha256_hash_buffer, _gcry_sha256_hash_buffers,
     sizeof (SHA256_CONTEXT),
     run_selftests
   };
index 06e8a2b..e83e84b 100644 (file)
@@ -925,6 +925,7 @@ gcry_md_spec_t _gcry_digest_spec_sha512 =
     GCRY_MD_SHA512, {0, 1},
     "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
     sha512_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
+    _gcry_sha512_hash_buffer, _gcry_sha512_hash_buffers,
     sizeof (SHA512_CONTEXT),
     run_selftests
   };
@@ -954,6 +955,7 @@ gcry_md_spec_t _gcry_digest_spec_sha384 =
     GCRY_MD_SHA384, {0, 1},
     "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
     sha384_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
+    NULL, NULL,
     sizeof (SHA512_CONTEXT),
     run_selftests
   };
index ee5daf2..c6f1a09 100644 (file)
@@ -462,6 +462,7 @@ gcry_md_spec_t _gcry_digest_spec_sm3 =
     GCRY_MD_SM3, {0, 1},
     "SM3", asn_sm3, DIM (asn_sm3), oid_spec_sm3, 32,
     sm3_init, _gcry_md_block_write, sm3_final, sm3_read, NULL,
+    _gcry_sm3_hash_buffer, _gcry_sm3_hash_buffers,
     sizeof (SM3_CONTEXT),
     run_selftests
   };
index 7b6e330..459e4db 100644 (file)
@@ -1344,7 +1344,7 @@ gcry_md_spec_t _gcry_digest_spec_stribog_256 =
     GCRY_MD_STRIBOG256, {0, 0},
     "STRIBOG256", NULL, 0, oid_spec_stribog256, 32,
     stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read_256,
-    NULL,
+    NULL, NULL, NULL,
     sizeof (STRIBOG_CONTEXT)
   };
 
@@ -1353,6 +1353,6 @@ gcry_md_spec_t _gcry_digest_spec_stribog_512 =
     GCRY_MD_STRIBOG512, {0, 0},
     "STRIBOG512", NULL, 0, oid_spec_stribog512, 64,
     stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read_512,
-    NULL,
+    NULL, NULL, NULL,
     sizeof (STRIBOG_CONTEXT)
   };
index b60ec16..d24d160 100644 (file)
@@ -814,6 +814,7 @@ gcry_md_spec_t _gcry_digest_spec_tiger =
     GCRY_MD_TIGER, {0, 0},
     "TIGER192", NULL, 0, NULL, 24,
     tiger_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
+    NULL, NULL,
     sizeof (TIGER_CONTEXT)
   };
 
@@ -837,6 +838,7 @@ gcry_md_spec_t _gcry_digest_spec_tiger1 =
     GCRY_MD_TIGER1, {0, 0},
     "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
     tiger1_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
+    NULL, NULL,
     sizeof (TIGER_CONTEXT)
   };
 
@@ -848,5 +850,6 @@ gcry_md_spec_t _gcry_digest_spec_tiger2 =
     GCRY_MD_TIGER2, {0, 0},
     "TIGER2", NULL, 0, NULL, 24,
     tiger2_init, _gcry_md_block_write, tiger_final, tiger_read, NULL,
+    NULL, NULL,
     sizeof (TIGER_CONTEXT)
   };
index 8a06939..d52375a 100644 (file)
@@ -1526,5 +1526,6 @@ gcry_md_spec_t _gcry_digest_spec_whirlpool =
     GCRY_MD_WHIRLPOOL, {0, 0},
     "WHIRLPOOL", NULL, 0, NULL, 64,
     whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read, NULL,
+    NULL, NULL,
     sizeof (whirlpool_context_t)
   };
index daa917c..97eb0d9 100644 (file)
@@ -219,6 +219,14 @@ typedef unsigned char *(*gcry_md_read_t) (void *c);
 /* Type for the md_extract function.  */
 typedef void (*gcry_md_extract_t) (void *c, void *outbuf, size_t nbytes);
 
+/* Type for the md_hash_buffer function. */
+typedef void (*gcry_md_hash_buffer_t) (void *outbuf, const void *buffer,
+                                      size_t length);
+
+/* Type for the md_hash_buffers function. */
+typedef void (*gcry_md_hash_buffers_t) (void *outbuf, const gcry_buffer_t *iov,
+                                       int iovcnt);
+
 typedef struct gcry_md_oid_spec
 {
   const char *oidstring;
@@ -242,6 +250,8 @@ typedef struct gcry_md_spec
   gcry_md_final_t final;
   gcry_md_read_t read;
   gcry_md_extract_t extract;
+  gcry_md_hash_buffer_t hash_buffer;
+  gcry_md_hash_buffers_t hash_buffers;
   size_t contextsize; /* allocate this amount of context */
   selftest_func_t selftest;
 } gcry_md_spec_t;
index 7c2e5d9..6e89be3 100644 (file)
@@ -115,6 +115,7 @@ gcry_err_code_t _gcry_cipher_cmac_set_subkeys
 /*-- rmd160.c --*/
 void _gcry_rmd160_hash_buffer (void *outbuf,
                                const void *buffer, size_t length);
+
 /*-- sha1.c --*/
 void _gcry_sha1_hash_buffer (void *outbuf,
                              const void *buffer, size_t length);