Commit d343b75e7f

Frank Denis <github@pureftpd.org>
2020-10-05 23:50:38
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.
1 parent 7f7e2d6
Changed files (2)
lib
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);
 
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;