Commit 5275b01202

J.W <jakwings@gmail.com>
2020-02-23 18:45:37
hashing algorithms: fix logic and index out of bounds
1 parent 907c558
Changed files (5)
lib/std/crypto/blake2.zig
@@ -94,7 +94,7 @@ fn Blake2s(comptime out_len: usize) type {
             var off: usize = 0;
 
             // Partial buffer exists from previous update. Copy into buffer then hash.
-            if (d.buf_len != 0 and d.buf_len + b.len > 64) {
+            if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
                 off += 64 - d.buf_len;
                 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
                 d.t += 64;
@@ -331,7 +331,7 @@ fn Blake2b(comptime out_len: usize) type {
             var off: usize = 0;
 
             // Partial buffer exists from previous update. Copy into buffer then hash.
-            if (d.buf_len != 0 and d.buf_len + b.len > 128) {
+            if (d.buf_len != 0 and d.buf_len + b.len >= 128) {
                 off += 128 - d.buf_len;
                 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
                 d.t += 128;
lib/std/crypto/md5.zig
@@ -63,7 +63,7 @@ pub const Md5 = struct {
         var off: usize = 0;
 
         // Partial buffer exists from previous update. Copy into buffer then hash.
-        if (d.buf_len != 0 and d.buf_len + b.len > 64) {
+        if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
             off += 64 - d.buf_len;
             mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
 
lib/std/crypto/sha1.zig
@@ -61,7 +61,7 @@ pub const Sha1 = struct {
         var off: usize = 0;
 
         // Partial buffer exists from previous update. Copy into buffer then hash.
-        if (d.buf_len != 0 and d.buf_len + b.len > 64) {
+        if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
             off += 64 - d.buf_len;
             mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
 
lib/std/crypto/sha2.zig
@@ -116,7 +116,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
             var off: usize = 0;
 
             // Partial buffer exists from previous update. Copy into buffer then hash.
-            if (d.buf_len != 0 and d.buf_len + b.len > 64) {
+            if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
                 off += 64 - d.buf_len;
                 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
 
@@ -458,7 +458,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
             var off: usize = 0;
 
             // Partial buffer exists from previous update. Copy into buffer then hash.
-            if (d.buf_len != 0 and d.buf_len + b.len > 128) {
+            if (d.buf_len != 0 and d.buf_len + b.len >= 128) {
                 off += 128 - d.buf_len;
                 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
 
lib/std/crypto.zig
@@ -57,3 +57,34 @@ test "crypto" {
     _ = @import("crypto/sha3.zig");
     _ = @import("crypto/x25519.zig");
 }
+
+test "issue #4532: no index out of bounds" {
+    const types = [_]type{
+        Md5,
+        Sha1,
+        Sha224,
+        Sha256,
+        Sha384,
+        Sha512,
+        Blake2s224,
+        Blake2s256,
+        Blake2b384,
+        Blake2b512,
+    };
+
+    inline for (types) |Hasher| {
+        var block = [_]u8{'#'} ** Hasher.block_length;
+        var out1: [Hasher.digest_length]u8 = undefined;
+        var out2: [Hasher.digest_length]u8 = undefined;
+
+        var h = Hasher.init();
+        h.update(block[0..]);
+        h.final(out1[0..]);
+        h.reset();
+        h.update(block[0..1]);
+        h.update(block[1..]);
+        h.final(out2[0..]);
+
+        std.testing.expectEqual(out1, out2);
+    }
+}