commit f173be36ad736bd342e47e9c7e4767afb394220a
parent 10cf8c9d36e4d6cdc448fe36765cab9f66f6c724
Author: Armin Preiml <apreiml@strohwolke.at>
Date: Sun, 14 Aug 2022 08:47:22 +0200
crypto::cipher::gcm: tag as slice
Signed-off-by: Armin Preiml <apreiml@strohwolke.at>
Diffstat:
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/crypto/aes/+test/gcm.ha b/crypto/aes/+test/gcm.ha
@@ -612,7 +612,8 @@ const gcmtestcases: []gcmtestcase = [
defer io::close(&gstream)!;
io::writeall(&gstream, t.plain)!;
- const tag = cipher::gcm_seal(&gstream);
+ let tag: [cipher::GCMTAGSIZE]u8 = [0...];
+ cipher::gcm_seal(&gstream, tag);
assert(bytes::equal(t.cipher, result));
assert(bytes::equal(t.tag, tag));
@@ -675,7 +676,8 @@ const gcmtestcases: []gcmtestcase = [
io::writeall(&gstream, result)!;
- const tag = cipher::gcm_seal(&gstream);
+ let tag: [cipher::GCMTAGSIZE]u8 = [0...];
+ cipher::gcm_seal(&gstream, tag);
assert(bytes::equal(t.cipher, result));
assert(bytes::equal(t.tag, tag));
diff --git a/crypto/cipher/gcm.ha b/crypto/cipher/gcm.ha
@@ -9,6 +9,8 @@ use types;
def GCMBLOCKSIZE: size = 16;
+export def GCMTAGSIZE: size = 16;
+
export type gcmstream = struct {
stream: io::stream,
block: *block,
@@ -190,30 +192,29 @@ fn gcm_reader(s: *io::stream, buf: []u8) (size | io::EOF | io::error) = {
// Finishes encryption and returns the authentication tag. After calling seal,
// the user must not write any more data to the stream.
-export fn gcm_seal(s: *gcmstream) [16]u8 = {
+export fn gcm_seal(s: *gcmstream, tag: []u8) void = {
+ assert(len(tag) == GCMTAGSIZE);
if (s.xorbufpos > 0 && s.xorbufpos < GCMBLOCKSIZE) {
// last block was is not full, therefore the content was not
// hashed yet.
ghash_ctmul64(s.tagbuf, s.h, s.cipherbuf[..s.xorbufpos]);
};
- let tmp: [16]u8 = [0...];
- beputu64(tmp, s.adlen << 3);
- beputu64(tmp[8..], s.clen << 3);
- ghash_ctmul64(s.tagbuf, s.h, tmp);
+ beputu64(tag, s.adlen << 3);
+ beputu64(tag[8..], s.clen << 3);
+ ghash_ctmul64(s.tagbuf, s.h, tag);
// use tmp to store the resulting tag
- encrypt(s.block, tmp, s.y0);
- xor(tmp, tmp, s.tagbuf);
-
- return tmp;
+ encrypt(s.block, tag, s.y0);
+ xor(tag, tag, s.tagbuf);
};
// Verifies the authentication tag against the decrypted data. Must be called
// after reading all data from the stream to ensure that the data was not
// modified. If the data was modified, [[errors::invalid]] will be returned and
// the data must not be trusted.
-export fn gcm_verify(s: *gcmstream, tag: [16]u8) (void | errors::invalid) = {
+export fn gcm_verify(s: *gcmstream, tag: []u8) (void | errors::invalid) = {
+ assert(len(tag) == GCMTAGSIZE);
if (s.xorbufpos > 0 && s.xorbufpos < GCMBLOCKSIZE) {
ghash_ctmul64(s.tagbuf, s.h, s.cipherbuf[..s.xorbufpos]);
};