Add hash_buffer and hash_buffers for SHA-224, SHA-385, SHA3 and BLAKE2
authorJussi Kivilinna <jussi.kivilinna@iki.fi>
Sun, 17 Jun 2018 17:03:28 +0000 (20:03 +0300)
committerJussi Kivilinna <jussi.kivilinna@iki.fi>
Tue, 19 Jun 2018 16:29:25 +0000 (19:29 +0300)
* cipher/blake2.c (DEFINE_BLAKE2_VARIANT): Add hash_buffer and
hash_buffers functions for BLAKE2 variants.
* cipher/keccak.c (_gcry_sha3_hash_buffer, _gcry_sha3_hash_buffers)
(_gcry_sha3_224_hash_buffer, _gcry_sha3_224_hash_buffers)
(_gcry_sha3_256_hash_buffer, _gcry_sha3_256_hash_buffers)
(_gcry_sha3_384_hash_buffer, _gcry_sha3_384_hash_buffers)
(_gcry_sha3_512_hash_buffer, _gcry_sha3_512_hash_buffers): New.
* cipher/sha256.c (_gcry_sha224_hash_buffer)
(_gcry_sha224_hash_buffers): New.
* cipher/sha512.c (_gcry_sha384_hash_buffer)
(_gcry_sha384_hash_buffers): New.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
cipher/blake2.c
cipher/keccak.c
cipher/sha256.c
cipher/sha512.c

index bfd24b9..f2bf49e 100644 (file)
@@ -945,6 +945,28 @@ gcry_err_code_t _gcry_blake2_init_with_key(void *ctx, unsigned int flags,
     int err = blake2##bs##_init_ctx (ctx, flags, NULL, 0, dbits); \
     gcry_assert (err == 0); \
   } \
+  static void \
+  _gcry_blake2##bs##_##dbits##_hash_buffer(void *outbuf, \
+        const void *buffer, size_t length) \
+  { \
+    BLAKE2##BS##_CONTEXT hd; \
+    blake2##bs##_##dbits##_init (&hd, 0); \
+    blake2##bs##_write (&hd, buffer, length); \
+    blake2##bs##_final (&hd); \
+    memcpy (outbuf, blake2##bs##_read (&hd), dbits / 8); \
+  } \
+  static void \
+  _gcry_blake2##bs##_##dbits##_hash_buffers(void *outbuf, \
+        const gcry_buffer_t *iov, int iovcnt) \
+  { \
+    BLAKE2##BS##_CONTEXT hd; \
+    blake2##bs##_##dbits##_init (&hd, 0); \
+    for (;iovcnt > 0; iov++, iovcnt--) \
+      blake2##bs##_write (&hd, (const char*)iov[0].data + iov[0].off, \
+                          iov[0].len); \
+    blake2##bs##_final (&hd); \
+    memcpy (outbuf, blake2##bs##_read (&hd), dbits / 8); \
+  } \
   static byte blake2##bs##_##dbits##_asn[] = { 0x30 }; \
   static gcry_md_oid_spec_t oid_spec_blake2##bs##_##dbits[] = \
     { \
@@ -958,7 +980,8 @@ 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, \
+      _gcry_blake2##bs##_##dbits##_hash_buffer, \
+      _gcry_blake2##bs##_##dbits##_hash_buffers, \
       sizeof (BLAKE2##BS##_CONTEXT), selftests_blake2##bs \
     };
 
index db67d07..24963f1 100644 (file)
@@ -998,6 +998,88 @@ keccak_extract (void *context, void *out, size_t outlen)
 }
 
 
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 'spec->mdlen' bytes.  */
+static void
+_gcry_sha3_hash_buffer (void *outbuf, const void *buffer, size_t length,
+                        const gcry_md_spec_t *spec)
+{
+  KECCAK_CONTEXT hd;
+
+  spec->init (&hd, 0);
+  keccak_write (&hd, buffer, length);
+  keccak_final (&hd);
+  memcpy (outbuf, keccak_read (&hd), spec->mdlen);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers.  */
+static void
+_gcry_sha3_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt,
+                         const gcry_md_spec_t *spec)
+{
+  KECCAK_CONTEXT hd;
+
+  spec->init (&hd, 0);
+  for (;iovcnt > 0; iov++, iovcnt--)
+    keccak_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len);
+  keccak_final (&hd);
+  memcpy (outbuf, keccak_read (&hd), spec->mdlen);
+}
+
+
+static void
+_gcry_sha3_224_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+  _gcry_sha3_hash_buffer (outbuf, buffer, length, &_gcry_digest_spec_sha3_224);
+}
+
+static void
+_gcry_sha3_256_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+  _gcry_sha3_hash_buffer (outbuf, buffer, length, &_gcry_digest_spec_sha3_256);
+}
+
+static void
+_gcry_sha3_384_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+  _gcry_sha3_hash_buffer (outbuf, buffer, length, &_gcry_digest_spec_sha3_384);
+}
+
+static void
+_gcry_sha3_512_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+  _gcry_sha3_hash_buffer (outbuf, buffer, length, &_gcry_digest_spec_sha3_512);
+}
+
+static void
+_gcry_sha3_224_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+                             int iovcnt)
+{
+  _gcry_sha3_hash_buffers (outbuf, iov, iovcnt, &_gcry_digest_spec_sha3_224);
+}
+
+static void
+_gcry_sha3_256_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+                             int iovcnt)
+{
+  _gcry_sha3_hash_buffers (outbuf, iov, iovcnt, &_gcry_digest_spec_sha3_256);
+}
+
+static void
+_gcry_sha3_384_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+                             int iovcnt)
+{
+  _gcry_sha3_hash_buffers (outbuf, iov, iovcnt, &_gcry_digest_spec_sha3_384);
+}
+
+static void
+_gcry_sha3_512_hash_buffers (void *outbuf, const gcry_buffer_t *iov,
+                             int iovcnt)
+{
+  _gcry_sha3_hash_buffers (outbuf, iov, iovcnt, &_gcry_digest_spec_sha3_512);
+}
+
 \f
 /*
      Self-test section.
@@ -1221,7 +1303,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,
+    _gcry_sha3_224_hash_buffer, _gcry_sha3_224_hash_buffers,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
@@ -1230,7 +1312,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,
+    _gcry_sha3_256_hash_buffer, _gcry_sha3_256_hash_buffers,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
@@ -1239,7 +1321,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,
+    _gcry_sha3_384_hash_buffer, _gcry_sha3_384_hash_buffers,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
@@ -1248,7 +1330,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,
+    _gcry_sha3_512_hash_buffer, _gcry_sha3_512_hash_buffers,
     sizeof (KECCAK_CONTEXT),
     run_selftests
   };
index 5c1c13f..0695970 100644 (file)
@@ -588,6 +588,35 @@ _gcry_sha256_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
 }
 
 
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 28 bytes.  */
+static void
+_gcry_sha224_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+  SHA256_CONTEXT hd;
+
+  sha224_init (&hd, 0);
+  _gcry_md_block_write (&hd, buffer, length);
+  sha256_final (&hd);
+  memcpy (outbuf, hd.bctx.buf, 28);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers.  */
+static void
+_gcry_sha224_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+  SHA256_CONTEXT hd;
+
+  sha224_init (&hd, 0);
+  for (;iovcnt > 0; iov++, iovcnt--)
+    _gcry_md_block_write (&hd,
+                          (const char*)iov[0].data + iov[0].off, iov[0].len);
+  sha256_final (&hd);
+  memcpy (outbuf, hd.bctx.buf, 28);
+}
+
+
 \f
 /*
      Self-test section.
@@ -743,7 +772,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,
+    _gcry_sha224_hash_buffer, _gcry_sha224_hash_buffers,
     sizeof (SHA256_CONTEXT),
     run_selftests
   };
index e83e84b..9405de8 100644 (file)
@@ -768,6 +768,36 @@ _gcry_sha512_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
 }
 
 
+
+/* Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 48 bytes.  */
+static void
+_gcry_sha384_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+  SHA512_CONTEXT hd;
+
+  sha384_init (&hd, 0);
+  _gcry_md_block_write (&hd, buffer, length);
+  sha512_final (&hd);
+  memcpy (outbuf, hd.bctx.buf, 48);
+}
+
+
+/* Variant of the above shortcut function using multiple buffers.  */
+static void
+_gcry_sha384_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+  SHA512_CONTEXT hd;
+
+  sha384_init (&hd, 0);
+  for (;iovcnt > 0; iov++, iovcnt--)
+    _gcry_md_block_write (&hd,
+                          (const char*)iov[0].data + iov[0].off, iov[0].len);
+  sha512_final (&hd);
+  memcpy (outbuf, hd.bctx.buf, 48);
+}
+
+
 \f
 /*
      Self-test section.
@@ -955,7 +985,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,
+    _gcry_sha384_hash_buffer, _gcry_sha384_hash_buffers,
     sizeof (SHA512_CONTEXT),
     run_selftests
   };