zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit e17998b39655e8af5d2a1134fee7ca4850ad4389 (tree)
parent d6e48abde87400a8a4851c7ab8c918005d81d058
Author: Frank Denis <124872+jedisct1@users.noreply.github.com>
Date:   Tue, 14 Mar 2023 22:40:02 +0100

Argon2: properly handle outputs > 64 bytes in blake2Long() (#14914)

Fixes #14912
Diffstat:
Mlib/std/crypto/argon2.zig | 59+++++++++++++++++++++++++++++------------------------------
1 file changed, 29 insertions(+), 30 deletions(-)

diff --git a/lib/std/crypto/argon2.zig b/lib/std/crypto/argon2.zig @@ -138,40 +138,39 @@ fn initHash( } fn blake2bLong(out: []u8, in: []const u8) void { - var b2 = Blake2b512.init(.{ .expected_out_bits = math.min(512, out.len * 8) }); - - var buffer: [Blake2b512.digest_length]u8 = undefined; - mem.writeIntLittle(u32, buffer[0..4], @intCast(u32, out.len)); - b2.update(buffer[0..4]); - b2.update(in); - b2.final(&buffer); - - if (out.len <= Blake2b512.digest_length) { - mem.copy(u8, out, buffer[0..out.len]); + const H = Blake2b512; + var outlen_bytes: [4]u8 = undefined; + mem.writeIntLittle(u32, &outlen_bytes, @intCast(u32, out.len)); + + var out_buf: [H.digest_length]u8 = undefined; + + if (out.len <= H.digest_length) { + var h = H.init(.{ .expected_out_bits = out.len * 8 }); + h.update(&outlen_bytes); + h.update(in); + h.final(&out_buf); + mem.copy(u8, out, out_buf[0..out.len]); return; } - b2 = Blake2b512.init(.{}); - mem.copy(u8, out, buffer[0..32]); - var out_slice = out[32..]; - while (out_slice.len > Blake2b512.digest_length) : ({ - out_slice = out_slice[32..]; - b2 = Blake2b512.init(.{}); - }) { - b2.update(&buffer); - b2.final(&buffer); - mem.copy(u8, out_slice, buffer[0..32]); - } - - var r = Blake2b512.digest_length; - if (out.len % Blake2b512.digest_length > 0) { - r = ((out.len + 31) / 32) - 2; - b2 = Blake2b512.init(.{ .expected_out_bits = r * 8 }); + var h = H.init(.{}); + h.update(&outlen_bytes); + h.update(in); + h.final(&out_buf); + var out_slice = out; + mem.copy(u8, out_slice, out_buf[0 .. H.digest_length / 2]); + out_slice = out_slice[H.digest_length / 2 ..]; + + var in_buf: [H.digest_length]u8 = undefined; + while (out_slice.len > H.digest_length) { + mem.copy(u8, &in_buf, &out_buf); + H.hash(&in_buf, &out_buf, .{}); + mem.copy(u8, out_slice, out_buf[0 .. H.digest_length / 2]); + out_slice = out_slice[H.digest_length / 2 ..]; } - - b2.update(&buffer); - b2.final(&buffer); - mem.copy(u8, out_slice, buffer[0..r]); + mem.copy(u8, &in_buf, &out_buf); + H.hash(&in_buf, &out_buf, .{ .expected_out_bits = out_slice.len * 8 }); + mem.copy(u8, out_slice, out_buf[0..out_slice.len]); } fn initBlocks(