commit 8da991279b174154c51394fe1edb80fb53c75124
parent 5f81cf1878feab2e2566c7865ef243838317c2ce
Author: Armin Preiml <apreiml@strohwolke.at>
Date: Wed, 19 Jan 2022 11:41:50 +0100
crypto::hmac: provide sha256 variant of hmac
Signed-off-by: Armin Preiml <apreiml@strohwolke.at>
Diffstat:
4 files changed, 78 insertions(+), 6 deletions(-)
diff --git a/crypto/hmac/+test.ha b/crypto/hmac/+test.ha
@@ -1,6 +1,7 @@
use bytes;
use crypto::mac;
use crypto::sha1;
+use crypto::sha256;
use encoding::hex;
use hash;
use io;
@@ -126,3 +127,21 @@ fn assert_hmac_sha1(keystr: str, vectors: [](str, [20]u8)) void = {
"jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
assert_hmac_sha1(key, vectors);
};
+
+@test fn sha256() void = {
+ const expected: [_]u8 = [
+ 0xb6, 0x13, 0x67, 0x9a, 0x08, 0x14, 0xd9, 0xec, 0x77, 0x2f,
+ 0x95, 0xd7, 0x78, 0xc3, 0x5f, 0xc5, 0xff, 0x16, 0x97, 0xc4,
+ 0x93, 0x71, 0x56, 0x53, 0xc6, 0xc7, 0x12, 0x14, 0x42, 0x92,
+ 0xc5, 0xad,
+ ];
+
+ let hmac = sha256([]);
+ defer mac::finish(&hmac);
+
+ let sum: [sha256::SIZE]u8 = [0...];
+ mac::sum(&hmac, sum);
+
+ assert(bytes::equal(expected, sum));
+};
+
diff --git a/crypto/hmac/sha256.ha b/crypto/hmac/sha256.ha
@@ -0,0 +1,49 @@
+use bytes;
+use crypto::mac;
+use crypto::sha256;
+use hash;
+use io;
+
+export type sha256state = struct {
+ mac::mac,
+ h: sha256::state,
+ keypad: [sha256::BLOCKSIZE]u8,
+};
+
+// Creates a [[crypto::mac::mac]] that computes an HMAC with given 'key' using
+// SHA256 as underlying hash function.
+//
+// The caller must take extra care to call [[mac::finish]] when they are
+// finished using the MAC function, which, in addition to freeing state
+// associated with the MAC, will securely erase state which contains secret
+// information.
+export fn sha256(key: []u8) sha256state = {
+ let s = sha256state {
+ h = sha256::sha256(),
+ sz = sha256::SIZE,
+ bsz = sha256::BLOCKSIZE,
+ writer = &sha256write,
+ sum = &sha256sum,
+ finish = &sha256finish,
+ ...
+ };
+
+ init(&s.h, key, s.keypad);
+ return s;
+};
+
+fn sha256write(st: *io::stream, buf: const []u8) (size | io::error) = {
+ let hm = st: *sha256state;
+ return hash::write(&hm.h, buf);
+};
+
+fn sha256sum(mac: *mac::mac, dest: []u8) void = {
+ let hm = mac: *sha256state;
+ sum(&hm.h, hm.keypad, dest);
+};
+
+fn sha256finish(mac: *mac::mac) void = {
+ let hm = mac: *sha256state;
+ bytes::zero(hm.keypad);
+ io::close(&hm.h);
+};
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -278,14 +278,16 @@ crypto_hmac() {
if [ $testing -eq 0 ]
then
gen_srcs crypto::hmac \
- hmac.ha
- gen_ssa crypto::hmac crypto::mac hash io bytes
+ hmac.ha \
+ sha256.ha
+ gen_ssa crypto::hmac crypto::mac crypto::sha256 hash io bytes
else
gen_srcs crypto::hmac \
hmac.ha \
+ sha256.ha \
+test.ha
gen_ssa crypto::hmac bytes crypto::mac hash crypto::sha1 \
- encoding::hex io strings
+ crypto::sha256 encoding::hex io strings
fi
}
diff --git a/stdlib.mk b/stdlib.mk
@@ -750,9 +750,10 @@ $(HARECACHE)/crypto/cipher/crypto_cipher-any.ssa: $(stdlib_crypto_cipher_any_src
# crypto::hmac (+any)
stdlib_crypto_hmac_any_srcs= \
- $(STDLIB)/crypto/hmac/hmac.ha
+ $(STDLIB)/crypto/hmac/hmac.ha \
+ $(STDLIB)/crypto/hmac/sha256.ha
-$(HARECACHE)/crypto/hmac/crypto_hmac-any.ssa: $(stdlib_crypto_hmac_any_srcs) $(stdlib_rt) $(stdlib_crypto_mac_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM))
+$(HARECACHE)/crypto/hmac/crypto_hmac-any.ssa: $(stdlib_crypto_hmac_any_srcs) $(stdlib_rt) $(stdlib_crypto_mac_$(PLATFORM)) $(stdlib_crypto_sha256_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM))
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/crypto/hmac
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ncrypto::hmac \
@@ -2559,9 +2560,10 @@ $(TESTCACHE)/crypto/cipher/crypto_cipher-any.ssa: $(testlib_crypto_cipher_any_sr
# crypto::hmac (+any)
testlib_crypto_hmac_any_srcs= \
$(STDLIB)/crypto/hmac/hmac.ha \
+ $(STDLIB)/crypto/hmac/sha256.ha \
$(STDLIB)/crypto/hmac/+test.ha
-$(TESTCACHE)/crypto/hmac/crypto_hmac-any.ssa: $(testlib_crypto_hmac_any_srcs) $(testlib_rt) $(testlib_bytes_$(PLATFORM)) $(testlib_crypto_mac_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_crypto_sha1_$(PLATFORM)) $(testlib_encoding_hex_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM))
+$(TESTCACHE)/crypto/hmac/crypto_hmac-any.ssa: $(testlib_crypto_hmac_any_srcs) $(testlib_rt) $(testlib_bytes_$(PLATFORM)) $(testlib_crypto_mac_$(PLATFORM)) $(testlib_hash_$(PLATFORM)) $(testlib_crypto_sha1_$(PLATFORM)) $(testlib_crypto_sha256_$(PLATFORM)) $(testlib_encoding_hex_$(PLATFORM)) $(testlib_io_$(PLATFORM)) $(testlib_strings_$(PLATFORM))
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/crypto/hmac
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ncrypto::hmac \