hare

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

commit c1b553ed5326df5a109d76910c48428d2debaed3
parent 07587a1a987b14fbac0fe163d07e541ecb7e0a38
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 17 Apr 2022 10:07:43 +0200

crypto::hmac: add sha1

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Acrypto/hmac/sha1.ha | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrypto/sha1/sha1.ha | 16++++++++--------
Mscripts/gen-stdlib | 2++
Mstdlib.mk | 2++
4 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/crypto/hmac/sha1.ha b/crypto/hmac/sha1.ha @@ -0,0 +1,51 @@ +// License: MPL-2.0 +// (c) 2022 Drew DeVault <sir@cmpwn.com> +use bytes; +use crypto::mac; +use crypto::sha1; +use hash; +use io; + +export type sha1state = struct { + mac::mac, + h: sha1::state, + keypad: [sha1::BLOCKSIZE]u8, +}; + +// Creates a [[crypto::mac::mac]] that computes an HMAC with given 'key' using +// SHA1 as underlying hash function. +// +// The caller must take extra care to call [[crypto::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 sha1(key: []u8) sha1state = { + let s = sha1state { + h = sha1::sha1(), + sz = sha1::SIZE, + bsz = sha1::BLOCKSIZE, + writer = &sha1write, + sum = &sha1sum, + finish = &sha1finish, + ... + }; + + init(&s.h, key, s.keypad); + return s; +}; + +fn sha1write(st: *io::stream, buf: const []u8) (size | io::error) = { + let hm = st: *sha1state; + return hash::write(&hm.h, buf); +}; + +fn sha1sum(mac: *mac::mac, dest: []u8) void = { + let hm = mac: *sha1state; + sum(&hm.h, hm.keypad, dest); +}; + +fn sha1finish(mac: *mac::mac) void = { + let hm = mac: *sha1state; + bytes::zero(hm.keypad); + io::close(&hm.h); +}; diff --git a/crypto/sha1/sha1.ha b/crypto/sha1/sha1.ha @@ -21,7 +21,7 @@ def init2: u32 = 0x98BADCFE; def init3: u32 = 0x10325476; def init4: u32 = 0xC3D2E1F0; -export type digest = struct { +export type state = struct { hash::hash, h: [5]u32, x: [chunk]u8, @@ -35,8 +35,8 @@ export type digest = struct { // function is used to hash sensitive information, the caller should call // [[hash::close]] to erase sentitive data from memory after use; if not, the // use of [[hash::close]] is optional. -export fn sha1() digest = { - let sha = digest { +export fn sha1() state = { + let sha = state { writer = &write, closer = &close, sum = &sum, @@ -50,7 +50,7 @@ export fn sha1() digest = { }; fn write(st: *io::stream, buf: const []u8) (size | io::error) = { - let h = st: *digest; + let h = st: *state; let b: []u8 = buf; let nn = len(buf); @@ -82,7 +82,7 @@ fn write(st: *io::stream, buf: const []u8) (size | io::error) = { }; fn reset(h: *hash::hash) void = { - let h = h: *digest; + let h = h: *state; h.h[0] = init0; h.h[1] = init1; h.h[2] = init2; @@ -93,7 +93,7 @@ fn reset(h: *hash::hash) void = { }; fn sum(h: *hash::hash, buf: []u8) void = { - let h = h: *digest; + let h = h: *state; let copy = *h; let h = &copy; defer hash::close(h); @@ -126,7 +126,7 @@ let K2: u32 = 0x8F1BBCDC; let K3: u32 = 0xCA62C1D6; // A generic, pure Hare version of the SHA-1 block step -fn block(h: *digest, p: []u8) void = { +fn block(h: *state, p: []u8) void = { let w: [16]u32 = [0...]; let h0 = h.h[0]; @@ -220,7 +220,7 @@ fn block(h: *digest, p: []u8) void = { }; fn close(stream: *io::stream) void = { - let s = stream: *digest; + let s = stream: *state; bytes::zero((s.h[..]: *[*]u8)[..len(s.h) * size(u32)]); bytes::zero(s.x); }; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -322,11 +322,13 @@ crypto_hmac() { then gen_srcs crypto::hmac \ hmac.ha \ + sha1.ha \ sha256.ha gen_ssa crypto::hmac crypto::mac crypto::sha256 hash io bytes else gen_srcs crypto::hmac \ hmac.ha \ + sha1.ha \ sha256.ha \ +test.ha gen_ssa crypto::hmac bytes crypto::mac hash crypto::sha1 \ diff --git a/stdlib.mk b/stdlib.mk @@ -824,6 +824,7 @@ $(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/sha1.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_crypto_sha256_$(PLATFORM)) $(stdlib_hash_$(PLATFORM)) $(stdlib_io_$(PLATFORM)) $(stdlib_bytes_$(PLATFORM)) @@ -2805,6 +2806,7 @@ $(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/sha1.ha \ $(STDLIB)/crypto/hmac/sha256.ha \ $(STDLIB)/crypto/hmac/+test.ha