hare

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

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:
Mcrypto/+test/authenc.ha | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrypto/authenc.ha | 24++++++++++++------------
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,