authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2023-03-14 22:40:02+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-03-14 21:40:02+00:00
loge17998b39655e8af5d2a1134fee7ca4850ad4389
treec65510685e12b5b98f824fc888c3797eae3dba7c
parentd6e48abde87400a8a4851c7ab8c918005d81d058
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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

Fixes #14912

1 files changed, 29 insertions(+), 30 deletions(-)

lib/std/crypto/argon2.zig+29-30
......@@ -138,40 +138,39 @@ fn initHash(
138138}
139139
140140fn blake2bLong(out: []u8, in: []const u8) void {
141 var b2 = Blake2b512.init(.{ .expected_out_bits = math.min(512, out.len * 8) });
142
143 var buffer: [Blake2b512.digest_length]u8 = undefined;
144 mem.writeIntLittle(u32, buffer[0..4], @intCast(u32, out.len));
145 b2.update(buffer[0..4]);
146 b2.update(in);
147 b2.final(&buffer);
148
149 if (out.len <= Blake2b512.digest_length) {
150 mem.copy(u8, out, buffer[0..out.len]);
141 const H = Blake2b512;
142 var outlen_bytes: [4]u8 = undefined;
143 mem.writeIntLittle(u32, &outlen_bytes, @intCast(u32, out.len));
144
145 var out_buf: [H.digest_length]u8 = undefined;
146
147 if (out.len <= H.digest_length) {
148 var h = H.init(.{ .expected_out_bits = out.len * 8 });
149 h.update(&outlen_bytes);
150 h.update(in);
151 h.final(&out_buf);
152 mem.copy(u8, out, out_buf[0..out.len]);
151153 return;
152154 }
153155
154 b2 = Blake2b512.init(.{});
155 mem.copy(u8, out, buffer[0..32]);
156 var out_slice = out[32..];
157 while (out_slice.len > Blake2b512.digest_length) : ({
158 out_slice = out_slice[32..];
159 b2 = Blake2b512.init(.{});
160 }) {
161 b2.update(&buffer);
162 b2.final(&buffer);
163 mem.copy(u8, out_slice, buffer[0..32]);
164 }
165
166 var r = Blake2b512.digest_length;
167 if (out.len % Blake2b512.digest_length > 0) {
168 r = ((out.len + 31) / 32) - 2;
169 b2 = Blake2b512.init(.{ .expected_out_bits = r * 8 });
156 var h = H.init(.{});
157 h.update(&outlen_bytes);
158 h.update(in);
159 h.final(&out_buf);
160 var out_slice = out;
161 mem.copy(u8, out_slice, out_buf[0 .. H.digest_length / 2]);
162 out_slice = out_slice[H.digest_length / 2 ..];
163
164 var in_buf: [H.digest_length]u8 = undefined;
165 while (out_slice.len > H.digest_length) {
166 mem.copy(u8, &in_buf, &out_buf);
167 H.hash(&in_buf, &out_buf, .{});
168 mem.copy(u8, out_slice, out_buf[0 .. H.digest_length / 2]);
169 out_slice = out_slice[H.digest_length / 2 ..];
170170 }
171
172 b2.update(&buffer);
173 b2.final(&buffer);
174 mem.copy(u8, out_slice, buffer[0..r]);
171 mem.copy(u8, &in_buf, &out_buf);
172 H.hash(&in_buf, &out_buf, .{ .expected_out_bits = out_slice.len * 8 });
173 mem.copy(u8, out_slice, out_buf[0..out_slice.len]);
175174}
176175
177176fn initBlocks(