From 7c7eb1b404dad2dfb2b5d9ed24212873f769995c Mon Sep 17 00:00:00 2001
From: "Alfred E. Heggestad" <alfred.heggestad@gmail.com>
Date: Sun, 26 Feb 2023 17:59:09 +0100
Subject: [PATCH] hmac: add stateless HMAC-SHA256 wrapper (#706)

---
 include/re_hmac.h    |  7 +++++++
 src/hmac/hmac_sha1.c | 30 ++++++++++++++++++++++++++++++
 test/hmac.c          | 10 ++++++++++
 3 files changed, 47 insertions(+)

diff --git a/include/re_hmac.h b/include/re_hmac.h
index 25e7e2e26..4d77cafac 100644
--- a/include/re_hmac.h
+++ b/include/re_hmac.h
@@ -12,6 +12,13 @@ void hmac_sha1(const uint8_t *k,   /* secret key */
 	       uint8_t*       out, /* output buffer, at least "t" bytes */
 	       size_t         t);
 
+void hmac_sha256(const uint8_t *key,
+		 size_t         key_len,
+		 const uint8_t *data,
+		 size_t         data_len,
+		 uint8_t       *out,
+		 size_t         out_len);
+
 
 enum hmac_hash {
 	HMAC_HASH_SHA1,
diff --git a/src/hmac/hmac_sha1.c b/src/hmac/hmac_sha1.c
index 9254120a9..46a87e419 100644
--- a/src/hmac/hmac_sha1.c
+++ b/src/hmac/hmac_sha1.c
@@ -52,5 +52,35 @@ void hmac_sha1(const uint8_t *k,  /* secret key */
 #error missing HMAC-SHA1 backend
 
 
+#endif
+}
+
+
+void hmac_sha256(const uint8_t *key, size_t key_len,
+		 const uint8_t *data, size_t data_len,
+		 uint8_t *out, size_t out_len)
+{
+#ifdef USE_OPENSSL
+
+	(void)out_len;
+
+	if (!HMAC(EVP_sha256(), key, (int)key_len, data, data_len, out, NULL))
+		ERR_clear_error();
+
+#elif defined (__APPLE__)
+	(void)out_len;
+
+	CCHmac(kCCHmacAlgSHA256, key, key_len, data, data_len, out);
+#else
+	(void)key;
+	(void)key_len;
+	(void)data;
+	(void)data_len;
+	(void)out;
+	(void)out_len;
+
+#error missing HMAC-SHA256 backend
+
+
 #endif
 }
diff --git a/test/hmac.c b/test/hmac.c
index 6e4576d19..3372826b7 100644
--- a/test/hmac.c
+++ b/test/hmac.c
@@ -255,6 +255,16 @@ int test_hmac_sha256(void)
 		TEST_MEMCMP(digest, sizeof(digest), md, sizeof(md));
 
 		hmac = mem_deref(hmac);
+
+		/* Test Stateless API */
+
+		uint8_t md2[SHA256_DIGEST_LENGTH];
+
+		hmac_sha256(key, key_len,
+			    data, data_len,
+			    md2, sizeof(md2));
+
+		TEST_MEMCMP(digest, sizeof(digest), md2, sizeof(md2));
 	}
 
  out: