hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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:
Mcrypto/hmac/+test.ha | 19+++++++++++++++++++
Acrypto/hmac/sha256.ha | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Mscripts/gen-stdlib | 8+++++---
Mstdlib.mk | 8+++++---
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 \