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:
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 \