From d343b75e7fa11d94e9668fb306b9e6b2ba68a0da Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 5 Oct 2020 23:50:38 +0200 Subject: [PATCH] ghash & poly1305: fix handling of partial blocks and add pad() pad() aligns the next input to the first byte of a block, which is useful to implement the IETF version of ChaCha20Poly1305 and AES-GCM. --- lib/std/crypto/ghash.zig | 23 +++++++++++++++-------- lib/std/crypto/poly1305.zig | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/std/crypto/ghash.zig b/lib/std/crypto/ghash.zig index 6a1bf7c186..04bc6a8275 100644 --- a/lib/std/crypto/ghash.zig +++ b/lib/std/crypto/ghash.zig @@ -250,7 +250,7 @@ pub const Ghash = struct { } mb = mb[want..]; st.leftover += want; - if (st.leftover > block_size) { + if (st.leftover < block_size) { return; } st.blocks(&st.buf); @@ -269,14 +269,21 @@ pub const Ghash = struct { } } - pub fn final(st: *Ghash, out: *[mac_length]u8) void { - if (st.leftover > 0) { - var i = st.leftover; - while (i < block_size) : (i += 1) { - st.buf[i] = 0; - } - st.blocks(&st.buf); + /// Zero-pad to align the next input to the first byte of a block + pub fn pad(st: *Ghash) void { + if (st.leftover == 0) { + return; } + var i = st.leftover; + while (i < block_size) : (i += 1) { + st.buf[i] = 0; + } + st.blocks(&st.buf); + st.leftover = 0; + } + + pub fn final(st: *Ghash, out: *[mac_length]u8) void { + st.pad(); mem.writeIntBig(u64, out[0..8], st.y1); mem.writeIntBig(u64, out[8..16], st.y0); diff --git a/lib/std/crypto/poly1305.zig b/lib/std/crypto/poly1305.zig index 31d1d6ba5a..c6613f64ba 100644 --- a/lib/std/crypto/poly1305.zig +++ b/lib/std/crypto/poly1305.zig @@ -91,7 +91,7 @@ pub const Poly1305 = struct { } mb = mb[want..]; st.leftover += want; - if (st.leftover > block_size) { + if (st.leftover < block_size) { return; } st.blocks(&st.buf, false); @@ -114,6 +114,19 @@ pub const Poly1305 = struct { } } + /// Zero-pad to align the next input to the first byte of a block + pub fn pad(st: *Poly1305) void { + if (st.leftover == 0) { + return; + } + var i = st.leftover; + while (i < block_size) : (i += 1) { + st.buf[i] = 0; + } + st.blocks(&st.buf); + st.leftover = 0; + } + pub fn final(st: *Poly1305, out: *[mac_length]u8) void { if (st.leftover > 0) { var i = st.leftover;