commit 800542bd3b04a89e2d9b84c10bd8d6078d46f798
parent 7b323f92e632e7c9bc8c5cd6e3b14a2b570ebc37
Author: Armin Preiml <apreiml@strohwolke.at>
Date: Tue, 10 May 2022 16:49:02 +0200
crypto::cipher::ctr: finish underlying block on close
Signed-off-by: Armin Preiml <apreiml@strohwolke.at>
Diffstat:
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/crypto/aes/ctr+test.ha b/crypto/aes/ctr+test.ha
@@ -34,7 +34,6 @@ use io;
let b = ct64();
ct64_init(&b, key);
- defer cipher::finish(&b);
let ctr = cipher::ctr(&resultbuf, &b, iv[..], buf[..]);
@@ -47,6 +46,9 @@ use io;
const bsz = cipher::blocksz(&b);
assert(bytes::equal(ctr.xorbuf, zero[bsz..]));
+ let b = ct64();
+ ct64_init(&b, key);
+
result = [0...];
buf = [0...];
let cipherbuf = bufio::fixed(cipher, io::mode::READ);
@@ -85,7 +87,6 @@ use io;
let b = ct64();
ct64_init(&b, key);
- defer cipher::finish(&b);
let ctr = cipher::ctr(&resultbuf, &b, iv[..], buf[..]);
defer io::close(&ctr)!;
@@ -137,7 +138,6 @@ use io;
let b = ct64();
ct64_init(&b, key);
- defer cipher::finish(&b);
let ctr = cipher::ctr(&resultbuf, &b, iv[..], buf[..]);
const n = io::writeall(&ctr, plain)!;
@@ -145,11 +145,15 @@ use io;
assert(bytes::equal(cipher, result));
io::close(&ctr)!;
+ let b = ct64();
+ ct64_init(&b, key);
+
let cipherbuf = bufio::fixed(cipher, io::mode::READ);
let ctr = cipher::ctr(&cipherbuf, &b, iv[..], buf[..]);
const n = io::readall(&ctr, result)!;
assert(n as size == len(plain));
assert(bytes::equal(plain, result));
+ io::close(&ctr)!;
};
@test fn ctr_test_multiple_calls() void = {
@@ -195,7 +199,6 @@ use io;
let b = ct64();
ct64_init(&b, key);
- defer cipher::finish(&b);
let ctr = cipher::ctr(&resultbuf, &b, iv[..], buf[..]);
defer io::close(&ctr)!;
diff --git a/crypto/cipher/ctr.ha b/crypto/cipher/ctr.ha
@@ -26,7 +26,8 @@ export type ctr_stream = struct {
// of these buffers for static allocation.
//
// The user must call [[io::close]] when they are done using the stream to
-// securely erase secret information stored in the stream state.
+// securely erase secret information stored in the stream state. This will also
+// finish the underlying [[block]] cipher.
export fn ctr(h: io::handle, b: *block, iv: []u8, buf: []u8) ctr_stream = {
assert(len(iv) == blocksz(b), "iv is of invalid block size");
assert(len(buf) >= blocksz(b) * 2, "buf must be at least 2 * blocksize");
@@ -109,4 +110,5 @@ fn ctr_advance(s: *xorstream, n: size) void = {
fn ctr_finish(s: *xorstream) void = {
let ctr = s: *ctr_stream;
bytes::zero(ctr.xorbuf);
+ finish(ctr.b);
};