gc: support HMAC-SHA256 and HMAC-SHA512.
[gnulib.git] / lib / gc-libgcrypt.c
index 050b89f..3be4272 100644 (file)
@@ -656,7 +656,7 @@ gc_hmac_md5 (const void *key, size_t keylen,
   unsigned char *hash;
   gpg_error_t err;
 
-  assert (hlen == 16);
+  assert (hlen == GC_MD5_DIGEST_SIZE);
 
   err = gcry_md_open (&mdh, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
   if (err != GPG_ERR_NO_ERROR)
@@ -725,3 +725,83 @@ gc_hmac_sha1 (const void *key, size_t keylen,
   return GC_OK;
 }
 #endif
+
+#ifdef GNULIB_GC_HMAC_SHA256
+Gc_rc
+gc_hmac_sha256 (const void *key, size_t keylen,
+             const void *in, size_t inlen, char *resbuf)
+{
+  size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
+  gcry_md_hd_t mdh;
+  unsigned char *hash;
+  gpg_error_t err;
+
+  assert (hlen == GC_SHA256_DIGEST_SIZE);
+
+  err = gcry_md_open (&mdh, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
+  if (err != GPG_ERR_NO_ERROR)
+    return GC_INVALID_HASH;
+
+  err = gcry_md_setkey (mdh, key, keylen);
+  if (err != GPG_ERR_NO_ERROR)
+    {
+      gcry_md_close (mdh);
+      return GC_INVALID_HASH;
+    }
+
+  gcry_md_write (mdh, in, inlen);
+
+  hash = gcry_md_read (mdh, GCRY_MD_SHA256);
+  if (hash == NULL)
+    {
+      gcry_md_close (mdh);
+      return GC_INVALID_HASH;
+    }
+
+  memcpy (resbuf, hash, hlen);
+
+  gcry_md_close (mdh);
+
+  return GC_OK;
+}
+#endif
+
+#ifdef GNULIB_GC_HMAC_SHA512
+Gc_rc
+gc_hmac_sha512 (const void *key, size_t keylen,
+              const void *in, size_t inlen, char *resbuf)
+{
+  size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA512);
+  gcry_md_hd_t mdh;
+  unsigned char *hash;
+  gpg_error_t err;
+
+  assert (hlen == GC_SHA512_DIGEST_SIZE);
+
+  err = gcry_md_open (&mdh, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
+  if (err != GPG_ERR_NO_ERROR)
+    return GC_INVALID_HASH;
+
+  err = gcry_md_setkey (mdh, key, keylen);
+  if (err != GPG_ERR_NO_ERROR)
+    {
+      gcry_md_close (mdh);
+      return GC_INVALID_HASH;
+    }
+
+  gcry_md_write (mdh, in, inlen);
+
+  hash = gcry_md_read (mdh, GCRY_MD_SHA512);
+  if (hash == NULL)
+    {
+      gcry_md_close (mdh);
+      return GC_INVALID_HASH;
+    }
+
+  memcpy (resbuf, hash, hlen);
+
+  gcry_md_close (mdh);
+
+  return GC_OK;
+}
+#endif