hare

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

commit 1bfa1fde7fcac1c5bdcf29518d75b7eda784a675
parent 9ccc6c0b250a0ece928812660dd3a4e09d9d57a2
Author: Bor Grošelj Simić <bgs@turminal.net>
Date:   Tue, 17 May 2022 21:24:45 +0200

crypto::blake2b: don't store the key

This breaks hash::reset for this hash function, but we don't want to
facilitate key reuse here any way, so that's fine.

Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>

Diffstat:
Mcrypto/argon2/argon2.ha | 7++++---
Mcrypto/blake2b/+test.ha | 4++--
Mcrypto/blake2b/blake2b.ha | 19++-----------------
Mhash/siphash/siphash.ha | 3+++
4 files changed, 11 insertions(+), 22 deletions(-)

diff --git a/crypto/argon2/argon2.ha b/crypto/argon2/argon2.ha @@ -335,21 +335,22 @@ fn varhash(dest: []u8, block: []u8) void = { // avoid leaking the dest len. const r = divceil(len(dest): u32, 32) - 2; let v: [64]u8 = [0...]; - let h = blake2b::blake2b([], 64); - defer hash::close(&h); let destbuf = bufio::fixed(dest, io::mode::WRITE); + let h = blake2b::blake2b([], 64); hash_leputu32(&h, len(dest): u32); hash::write(&h, block); hash::sum(&h, v[..]); + hash::close(&h); io::writeall(&destbuf, v[..32])!; for (let i = 1z; i < r; i += 1) { - hash::reset(&h); + let h = blake2b::blake2b([], 64); hash::write(&h, v[..]); hash::sum(&h, v[..]); + hash::close(&h); io::writeall(&destbuf, v[..32])!; }; diff --git a/crypto/blake2b/+test.ha b/crypto/blake2b/+test.ha @@ -35,7 +35,6 @@ use strio; assert(strio::string(&out) == vectors[i].out); }; - let blake = blake2b([], 64); const vectors = [ ("", "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"), ("abc", "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"), @@ -49,7 +48,8 @@ use strio; for (let i = 0z; i < len(vectors); i += 1) { const vector = vectors[i]; - hash::reset(&blake); + let blake = blake2b([], 64); + defer hash::close(&blake); hash::write(&blake, strings::toutf8(vector.0)); static let sum: [64]u8 = [0...]; diff --git a/crypto/blake2b/blake2b.ha b/crypto/blake2b/blake2b.ha @@ -44,8 +44,6 @@ export type digest = struct { thigh: u64, block: [BSIZE]u8, blocklen: size, - key: [BSIZE]u8, - keylen: size, }; const blake2b_vtable: io::vtable = io::vtable { @@ -58,7 +56,8 @@ const blake2b_vtable: io::vtable = io::vtable { // given hash size. The size must be between 1 and 64, inclusive. If this // function is used to hash sensitive information, the caller should call // [[hash::close]] to erase sensitive data from memory after use; if not, the -// use of [[hash::close]] is optional. +// use of [[hash::close]] is optional. This function does not provide reset +// functionality and calling [[hash::reset]] on it will terminate execution. export fn blake2b(key: []u8, sz: size) digest = { assert(1 <= sz); assert(sz <= 64); @@ -70,15 +69,12 @@ export fn blake2b(key: []u8, sz: size) digest = { return digest { stream = &blake2b_vtable, sum = &sum, - reset = &reset, sz = sz, h = h, tlow = 0, thigh = 0, block = keyblock, blocklen = if (len(key) > 0) BSIZE else 0, - key = keyblock, - keylen = len(key), ... }; }; @@ -126,16 +122,6 @@ fn sum(h: *hash::hash, buf: []u8) void = { }; }; -fn reset(h: *hash::hash) void = { - let h = h: *digest; - h.h = iv; - h.h[0] ^= 0x01010000 ^ (h.keylen << 8) ^ h.sz; - h.tlow = 0; - h.thigh = 0; - h.block = h.key; - h.blocklen = if (h.keylen > 0) BSIZE else 0; -}; - // Compression function F fn compress(h: *[8]u64, b: *[BSIZE]u8, tlow: u64, thigh: u64, f: bool) void = { let v: [16]u64 = [0...]; @@ -182,5 +168,4 @@ fn close(stream: *io::stream) (void | io::error) = { let s = stream: *digest; bytes::zero((s.h[..]: *[*]u8)[..len(s.h) * size(u32)]); bytes::zero(s.block); - bytes::zero(s.key); }; diff --git a/hash/siphash/siphash.ha b/hash/siphash/siphash.ha @@ -24,6 +24,9 @@ const sip_vtable: io::vtable = io::vtable { // Creates a [hash::hash] that computes SipHash-c-d with the given 16 byte key, // where c denotes number of compression rounds and d denotes number of // finalization rounds. Recommended values for c and d are 2 and 4 respectively. +// Calling [[hash::close]] on this function will erase its state information. +// This function does not provide reset functionality and calling +// [[hash::reset]] on it will terminate execution. export fn siphash(c: u8, d: u8, key: *[16]u8) state = { let h = state { stream = &sip_vtable,