HKDF rejects maximum key size
guidovranken opened this issue · comments
Guido Vranken commented
Zig Version
0.10.0
Steps to Reproduce and Observed Behavior
const std = @import("std");
const hkdf = std.crypto.kdf.hkdf;
pub fn main() !void {
var salt: [2]u8 = [2]u8{0xFF, 0xFF};
var password: [2]u8 = [2]u8{0xFF, 0xFF};
var info: [2]u8 = [2]u8{0xFF, 0xFF};
var out: [16320]u8 = undefined;
const prk = hkdf.HkdfSha512.extract(&salt, &password);
hkdf.HkdfSha512.expand(&out, &info, prk);
}
thread 1503604 panic: reached unreachable code
/snap/zig/5939/lib/std/debug.zig:278:14: 0x215f90 in assert (hello)
if (!ok) unreachable; // assertion failure
^
/snap/zig/5939/lib/std/crypto/hkdf.zig:25:19: 0x2138e8 in expand (hello)
assert(out.len < Hmac.mac_length * 255); // output size is too large for the Hkdf construction
^
./hello.zig:11:27: 0x2137b9 in main (hello)
hkdf.HkdfSha512.expand(&out, &info, prk);
^
/snap/zig/5939/lib/std/start.zig:606:37: 0x2132c7 in posixCallMainAndExit (hello)
const result = root.main() catch |err| {
^
/snap/zig/5939/lib/std/start.zig:368:5: 0x212d51 in _start (hello)
@call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
^
Aborted (core dumped)
Expected Behavior
No crash because HKDF permits key sizes up to and including 255 * hash size
. The hash size of SHA512 is 64 bytes. So a key size of 255 * 64 = 16320 bytes should be permitted. See https://www.rfc-editor.org/rfc/rfc5869 section 2.3:
L length of output keying material in octets
(<= 255*HashLen)
Guido Vranken commented
Change:
Line 25 in f211c15
to:
assert(out.len <= Hmac.mac_length * 255); // output size is too large for the Hkdf construction
Frank Denis commented
Good catch, thanks!
Changing the assert()
would not be enough, since the counter could overflow, but #14051 should address this.
Thanks again!