authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-01-07 23:01:38+01:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-01-07 23:01:38+01:00
log2153759a22f584c5ad43e15fdc13b1afcb5449a7
treee3645db8a4bb0020e91ec1db9df71f60d469b8e5
parent62d6bbc7dc36dbb2f45da08e767076157deeb259

crypto.scrypt: accept an std.Io parameter instead of direct entropy

Safer, and consistent with what is being done in other similar functions.

1 files changed, 15 insertions(+), 7 deletions(-)

lib/std/crypto/scrypt.zig+15-7
......@@ -417,9 +417,11 @@ const PhcFormatHasher = struct {
417417 password: []const u8,
418418 params: Params,
419419 buf: []u8,
420 /// Filled with cryptographically secure entropy.
421 salt: []const u8,
420 io: std.Io,
422421 ) HasherError![]const u8 {
422 var salt: [default_salt_len]u8 = undefined;
423 io.random(&salt);
424
423425 var hash: [default_hash_len]u8 = undefined;
424426 try kdf(allocator, &hash, password, &salt, params);
425427
......@@ -465,9 +467,10 @@ const CryptFormatHasher = struct {
465467 password: []const u8,
466468 params: Params,
467469 buf: []u8,
468 /// Filled with cryptographically secure entropy.
469 salt_bin: []const u8,
470 io: std.Io,
470471 ) HasherError![]const u8 {
472 var salt_bin: [default_salt_len]u8 = undefined;
473 io.random(&salt_bin);
471474 const salt = crypt_format.saltFromBin(salt_bin.len, salt_bin);
472475
473476 var hash: [default_hash_len]u8 = undefined;
......@@ -514,11 +517,12 @@ pub fn strHash(
514517 password: []const u8,
515518 options: HashOptions,
516519 out: []u8,
520 io: std.Io,
517521) Error![]const u8 {
518522 const allocator = options.allocator orelse return Error.AllocatorRequired;
519523 switch (options.encoding) {
520 .phc => return PhcFormatHasher.create(allocator, password, options.params, out),
521 .crypt => return CryptFormatHasher.create(allocator, password, options.params, out),
524 .phc => return PhcFormatHasher.create(allocator, password, options.params, out, io),
525 .crypt => return CryptFormatHasher.create(allocator, password, options.params, out, io),
522526 }
523527}
524528
......@@ -630,6 +634,7 @@ test "password hashing (crypt format)" {
630634 if (!run_long_tests) return error.SkipZigTest;
631635
632636 const alloc = std.testing.allocator;
637 const io = std.testing.io;
633638
634639 const str = "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5";
635640 const password = "Y0!?iQa9M%5ekffW(`";
......@@ -637,7 +642,7 @@ test "password hashing (crypt format)" {
637642
638643 const params = Params.interactive;
639644 var buf: [CryptFormatHasher.pwhash_str_length]u8 = undefined;
640 const str2 = try CryptFormatHasher.create(alloc, password, params, &buf);
645 const str2 = try CryptFormatHasher.create(alloc, password, params, &buf, io);
641646 try CryptFormatHasher.verify(alloc, str2, password);
642647}
643648
......@@ -645,6 +650,7 @@ test "strHash and strVerify" {
645650 if (!run_long_tests) return error.SkipZigTest;
646651
647652 const alloc = std.testing.allocator;
653 const io = std.testing.io;
648654
649655 const password = "testpass";
650656 const params = Params.interactive;
......@@ -656,6 +662,7 @@ test "strHash and strVerify" {
656662 password,
657663 .{ .allocator = alloc, .params = params, .encoding = .crypt },
658664 &buf,
665 io,
659666 );
660667 try strVerify(str, password, verify_options);
661668 }
......@@ -664,6 +671,7 @@ test "strHash and strVerify" {
664671 password,
665672 .{ .allocator = alloc, .params = params, .encoding = .phc },
666673 &buf,
674 io,
667675 );
668676 try strVerify(str, password, verify_options);
669677 }