hare

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

commit f0689316511925d4b735572cf2fc9b3e2ada173d
parent d16e7316eedf52cae45b7ffa6b5af9a4c1936553
Author: Armin Preiml <apreiml@strohwolke.at>
Date:   Thu, 23 Dec 2021 20:52:55 +0100

crypto::cipher: use finish for stream ciphers

Signed-off-by: Armin Preiml <apreiml@strohwolke.at>

Diffstat:
Mcrypto/aes/ctr+test.ha | 6++++++
Mcrypto/cipher/block.ha | 4----
Acrypto/cipher/cipher.ha | 10++++++++++
Mcrypto/cipher/ctr.ha | 15++++++++-------
Mcrypto/cipher/stream.ha | 1+
Mscripts/gen-stdlib | 1+
Mstdlib.mk | 2++
7 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/crypto/aes/ctr+test.ha b/crypto/aes/ctr+test.ha @@ -30,6 +30,7 @@ use bytes; defer cipher::finish(&b); let ctr = cipher::ctr(&b, iv[..], buf[..]); + defer cipher::finish(&ctr); cipher::stream_xor(&ctr, result, plain); assert(bytes::equal(cipher, result)); @@ -66,6 +67,7 @@ use bytes; defer cipher::finish(&b); let ctr = cipher::ctr(&b, iv[..], buf[..]); + defer cipher::finish(&ctr); cipher::stream_xor(&ctr, result, plain); assert(bytes::equal(cipher, result)); @@ -116,6 +118,7 @@ use bytes; defer cipher::finish(&b); let ctr = cipher::ctr(&b, iv[..], buf[..]); + defer cipher::finish(&ctr); cipher::stream_xor(&ctr, result, plain); assert(bytes::equal(cipher, result)); @@ -166,6 +169,7 @@ use bytes; defer cipher::finish(&b); let ctr = cipher::ctr(&b, iv[..], buf[..]); + defer cipher::finish(&ctr); cipher::stream_xor(&ctr, result[0..32], plain[0..32]); cipher::stream_xor(&ctr, result[32..], plain[32..]); assert(bytes::equal(cipher, result)); @@ -206,6 +210,7 @@ use bytes; let buf: [CTR_BUFSIZE]u8 = [0...]; let ctr = cipher::ctr(&b, iv[..], buf[..]); + defer cipher::finish(&ctr); cipher::stream_xor(&ctr, result, result); assert(bytes::equal(cipher, result)); @@ -240,6 +245,7 @@ use bytes; let buf: [64]u8 = [0...]; let ctr = cipher::ctr(&b, iv[..], buf[..]); + defer cipher::finish(&ctr); cipher::stream_xor(&ctr, result, result); assert(bytes::equal(cipher, result)); diff --git a/crypto/cipher/block.ha b/crypto/cipher/block.ha @@ -23,7 +23,3 @@ export fn encrypt(b: *block, dest: []u8, src: []u8) void = // Decrypt up to [[nparallel]] blocks from 'src' and writes to 'dest'. export fn decrypt(b: *block, dest: []u8, src: []u8) void = b.decrypt(b, dest, src); - -// Discards any state associated with a block cipher algorithm, securely erasing -// secret data from memory. -export fn finish(b: *block) void = b.finish(b); diff --git a/crypto/cipher/cipher.ha b/crypto/cipher/cipher.ha @@ -0,0 +1,10 @@ +// Discards any state associated with a block or a stream cipher algorithm, +// securely erasing secret data from memory. +export fn finish(a: (*block | *stream)) void = { + match (a) { + case let a: *block => + a.finish(a); + case let a: *stream => + a.finish(a); + }; +}; diff --git a/crypto/cipher/ctr.ha b/crypto/cipher/ctr.ha @@ -17,7 +17,7 @@ export type ctr_stream = struct { // underlying block cipher usually provides constants which define the lengths // of these buffers for static allocation. // -// The user must call [[ctr_finish]] when they are done using the stream to +// The user must call [[finish]] when they are done using the stream to // securely erase secret information stored in the stream state. export fn ctr(b: *block, iv: []u8, buf: []u8) ctr_stream = { assert(len(iv) == blocksz(b), "iv is of invalid block size"); @@ -47,6 +47,7 @@ export fn ctr(b: *block, iv: []u8, buf: []u8) ctr_stream = { return ctr_stream { xor = &ctr_stream_xor, + finish = &ctr_finish, b = b, counter = counter, xorbuf = xorbuf, @@ -55,12 +56,6 @@ export fn ctr(b: *block, iv: []u8, buf: []u8) ctr_stream = { }; }; -// Discards state associated with a CTR stream, securely erasing secret data -// from memory. -export fn ctr_finish(ctr: *ctr_stream) void = { - bytes::zero(ctr.xorbuf); -}; - fn ctr_stream_xor(s: *stream, dest: []u8, src: []u8) void = { let ctr = s: *ctr_stream; const bsz = blocksz(ctr.b); @@ -96,3 +91,9 @@ fn fill_xorbuf(ctr: *ctr_stream) void = { encrypt(ctr.b, ctr.xorbuf, ctr.xorbuf); ctr.xorused = 0; }; + +fn ctr_finish(s: *stream) void = { + let ctr = s: *ctr_stream; + bytes::zero(ctr.xorbuf); +}; + diff --git a/crypto/cipher/stream.ha b/crypto/cipher/stream.ha @@ -1,6 +1,7 @@ // An abstract interface for implementing cipher streams export type stream = struct { xor: *fn(s: *stream, dest: []u8, src: []u8) void, + finish: *fn(s: *stream) void, }; // Applies xor of the key produced by the stream to src and writes the result diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -235,6 +235,7 @@ crypto_blake2b() { crypto_cipher() { gen_srcs crypto::cipher \ + cipher.ha \ block.ha \ cbc.ha \ ctr.ha \ diff --git a/stdlib.mk b/stdlib.mk @@ -691,6 +691,7 @@ $(HARECACHE)/crypto/blake2b/crypto_blake2b-any.ssa: $(stdlib_crypto_blake2b_any_ # crypto::cipher (+any) stdlib_crypto_cipher_any_srcs= \ + $(STDLIB)/crypto/cipher/cipher.ha \ $(STDLIB)/crypto/cipher/block.ha \ $(STDLIB)/crypto/cipher/cbc.ha \ $(STDLIB)/crypto/cipher/ctr.ha \ @@ -2428,6 +2429,7 @@ $(TESTCACHE)/crypto/blake2b/crypto_blake2b-any.ssa: $(testlib_crypto_blake2b_any # crypto::cipher (+any) testlib_crypto_cipher_any_srcs= \ + $(STDLIB)/crypto/cipher/cipher.ha \ $(STDLIB)/crypto/cipher/block.ha \ $(STDLIB)/crypto/cipher/cbc.ha \ $(STDLIB)/crypto/cipher/ctr.ha \