commit 57a723a2d911043b76171ff3712528be806aaa07
parent 15a5e9ab579bb06feca51e5784eaf2fad8c66b5c
Author: Armin Preiml <apreiml@strohwolke.at>
Date: Thu, 13 Jan 2022 07:57:35 +0100
crypto: fix padding for poly1305 in encrypt/decrypt
Signed-off-by: Armin Preiml <apreiml@strohwolke.at>
Diffstat:
2 files changed, 64 insertions(+), 12 deletions(-)
diff --git a/crypto/+test/authenc.ha b/crypto/+test/authenc.ha
@@ -152,6 +152,40 @@ const nothing: sample = sample {
...
};
+const polyaligned: sample = sample {
+ key = [
+ 0x8a, 0x67, 0xe3, 0x6c, 0x24, 0xbd, 0x05, 0x7f, 0x53, 0x7d,
+ 0x3b, 0x2d, 0x25, 0x98, 0x7c, 0x21, 0xb1, 0x51, 0x90, 0xdd,
+ 0x7a, 0x4a, 0x52, 0x49, 0x12, 0x22, 0x3e, 0x7e, 0x2e, 0x0d,
+ 0x8a, 0x15,
+ ],
+ msg = [
+ 0xa1, 0x9c, 0x40, 0xbe, 0x6e, 0xf7, 0x43, 0x66, 0xcf, 0xe1,
+ 0x15, 0xce, 0x0c, 0x90, 0x7c, 0x1f, 0x35, 0xfb, 0x03, 0x7f,
+ 0x96, 0x62, 0x53, 0xa6, 0xfa, 0xf1, 0x31, 0x39, 0xae, 0x69,
+ 0x0e, 0xf7,
+ ],
+ nonce = [
+ 0xc2, 0x16, 0x80, 0x49, 0xd1, 0x82, 0x04, 0xc5, 0x89, 0xee,
+ 0xbc, 0x24, 0xa0, 0x37, 0x6f, 0xbb, 0x44, 0x09, 0x49, 0x8e,
+ 0xe2, 0x73, 0x33, 0x4d,
+ ],
+ additional = [
+ 0xc1, 0xf7, 0xa5, 0xcf, 0x2f, 0xc0, 0x21, 0x55, 0x74, 0xfb,
+ 0x75, 0xcd, 0x8b, 0x9e, 0xe2, 0x2a,
+ ],
+ cipher = [
+ 0xfe, 0xe1, 0xb9, 0xff, 0xc5, 0x03, 0x38, 0x73, 0xbb, 0x1c,
+ 0x90, 0x7b, 0x53, 0x39, 0x65, 0xd7, 0x64, 0x12, 0xe4, 0x88,
+ 0xa0, 0xaa, 0x8e, 0x11, 0x23, 0xd0, 0x20, 0x8a, 0x54, 0x76,
+ 0x12, 0x75,
+ ],
+ mac = [
+ 0x7e, 0x80, 0x2c, 0x34, 0x45, 0x04, 0x5b, 0xff, 0x04, 0x58,
+ 0x36, 0xef, 0xe2, 0x55, 0xc8, 0x45,
+ ],
+};
+
@test fn rfc() void = {
let result: []u8 = alloc(rfcsample.msg...);
defer free(result);
@@ -234,6 +268,24 @@ const nothing: sample = sample {
assert(bytes::equal([], plain as []u8));
};
+@test fn polyaligned() void = {
+ let result: []u8 = alloc(polyaligned.msg...);
+ defer free(result);
+
+ let b = encrypt(&polyaligned.key, &polyaligned.nonce, result[..],
+ polyaligned.additional[..]);
+
+ assert(bytes::equal(polyaligned.cipher, b.2));
+ assert(bytes::equal(polyaligned.nonce, b.1));
+ assert(bytes::equal(polyaligned.mac, b.0));
+
+ const plain = decrypt(&polyaligned.key, &b, polyaligned.additional);
+
+ assert(plain is []u8);
+ assert(bytes::equal(polyaligned.msg, plain as []u8));
+};
+
+
@test fn invalidkey() void = {
const zero: [114]u8 = [0...];
diff --git a/crypto/authenc.ha b/crypto/authenc.ha
@@ -103,25 +103,15 @@ fn writemac(
poly1305::init(&poly, otk);
defer mac::finish(&poly);
- const pad: [16]u8 = [0...];
-
let adlen: size = 0;
for (let i = 0z; i < len(additional); i += 1) {
adlen += len(additional[i]);
mac::write(&poly, additional[i]);
};
- let padlen: size = 0;
- if (adlen > 0) {
- padlen = poly1305::BLOCKSIZE - (adlen % poly1305::BLOCKSIZE);
- mac::write(&poly, pad[..padlen]);
- };
+ polypad(&poly, adlen);
mac::write(&poly, ciphertext);
- if (len(ciphertext) > 0) {
- padlen = poly1305::BLOCKSIZE
- - (len(ciphertext) % poly1305::BLOCKSIZE);
- mac::write(&poly, pad[..padlen]);
- };
+ polypad(&poly, len(ciphertext));
let nbuf: [8]u8 = [0...];
endian::leputu64(nbuf, adlen: u32);
@@ -133,6 +123,16 @@ fn writemac(
mac::sum(&poly, m[..]);
};
+fn polypad(p: *poly1305::state, n: size) void = {
+ if (n % poly1305::BLOCKSIZE == 0) {
+ return;
+ };
+
+ const pad: [poly1305::BLOCKSIZE]u8 = [0...];
+ const padlen = poly1305::BLOCKSIZE - (n % poly1305::BLOCKSIZE);
+ mac::write(p, pad[..padlen]);
+};
+
// Authenticates and decrypts a message encrypted with [[encrypt]]. If the
// decryption is successful, the plaintext slice is returned, and if not,