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 {...@@ -417,9 +417,11 @@ const PhcFormatHasher = struct {
417 password: []const u8,417 password: []const u8,
418 params: Params,418 params: Params,
419 buf: []u8,419 buf: []u8,
420 /// Filled with cryptographically secure entropy.420 io: std.Io,
421 salt: []const u8,
422 ) HasherError![]const u8 {421 ) HasherError![]const u8 {
422 var salt: [default_salt_len]u8 = undefined;
423 io.random(&salt);
424
423 var hash: [default_hash_len]u8 = undefined;425 var hash: [default_hash_len]u8 = undefined;
424 try kdf(allocator, &hash, password, &salt, params);426 try kdf(allocator, &hash, password, &salt, params);
425427
...@@ -465,9 +467,10 @@ const CryptFormatHasher = struct {...@@ -465,9 +467,10 @@ const CryptFormatHasher = struct {
465 password: []const u8,467 password: []const u8,
466 params: Params,468 params: Params,
467 buf: []u8,469 buf: []u8,
468 /// Filled with cryptographically secure entropy.470 io: std.Io,
469 salt_bin: []const u8,
470 ) HasherError![]const u8 {471 ) HasherError![]const u8 {
472 var salt_bin: [default_salt_len]u8 = undefined;
473 io.random(&salt_bin);
471 const salt = crypt_format.saltFromBin(salt_bin.len, salt_bin);474 const salt = crypt_format.saltFromBin(salt_bin.len, salt_bin);
472475
473 var hash: [default_hash_len]u8 = undefined;476 var hash: [default_hash_len]u8 = undefined;
...@@ -514,11 +517,12 @@ pub fn strHash(...@@ -514,11 +517,12 @@ pub fn strHash(
514 password: []const u8,517 password: []const u8,
515 options: HashOptions,518 options: HashOptions,
516 out: []u8,519 out: []u8,
520 io: std.Io,
517) Error![]const u8 {521) Error![]const u8 {
518 const allocator = options.allocator orelse return Error.AllocatorRequired;522 const allocator = options.allocator orelse return Error.AllocatorRequired;
519 switch (options.encoding) {523 switch (options.encoding) {
520 .phc => return PhcFormatHasher.create(allocator, password, options.params, out),524 .phc => return PhcFormatHasher.create(allocator, password, options.params, out, io),
521 .crypt => return CryptFormatHasher.create(allocator, password, options.params, out),525 .crypt => return CryptFormatHasher.create(allocator, password, options.params, out, io),
522 }526 }
523}527}
524528
...@@ -630,6 +634,7 @@ test "password hashing (crypt format)" {...@@ -630,6 +634,7 @@ test "password hashing (crypt format)" {
630 if (!run_long_tests) return error.SkipZigTest;634 if (!run_long_tests) return error.SkipZigTest;
631635
632 const alloc = std.testing.allocator;636 const alloc = std.testing.allocator;
637 const io = std.testing.io;
633638
634 const str = "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5";639 const str = "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5";
635 const password = "Y0!?iQa9M%5ekffW(`";640 const password = "Y0!?iQa9M%5ekffW(`";
...@@ -637,7 +642,7 @@ test "password hashing (crypt format)" {...@@ -637,7 +642,7 @@ test "password hashing (crypt format)" {
637642
638 const params = Params.interactive;643 const params = Params.interactive;
639 var buf: [CryptFormatHasher.pwhash_str_length]u8 = undefined;644 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);
641 try CryptFormatHasher.verify(alloc, str2, password);646 try CryptFormatHasher.verify(alloc, str2, password);
642}647}
643648
...@@ -645,6 +650,7 @@ test "strHash and strVerify" {...@@ -645,6 +650,7 @@ test "strHash and strVerify" {
645 if (!run_long_tests) return error.SkipZigTest;650 if (!run_long_tests) return error.SkipZigTest;
646651
647 const alloc = std.testing.allocator;652 const alloc = std.testing.allocator;
653 const io = std.testing.io;
648654
649 const password = "testpass";655 const password = "testpass";
650 const params = Params.interactive;656 const params = Params.interactive;
...@@ -656,6 +662,7 @@ test "strHash and strVerify" {...@@ -656,6 +662,7 @@ test "strHash and strVerify" {
656 password,662 password,
657 .{ .allocator = alloc, .params = params, .encoding = .crypt },663 .{ .allocator = alloc, .params = params, .encoding = .crypt },
658 &buf,664 &buf,
665 io,
659 );666 );
660 try strVerify(str, password, verify_options);667 try strVerify(str, password, verify_options);
661 }668 }
...@@ -664,6 +671,7 @@ test "strHash and strVerify" {...@@ -664,6 +671,7 @@ test "strHash and strVerify" {
664 password,671 password,
665 .{ .allocator = alloc, .params = params, .encoding = .phc },672 .{ .allocator = alloc, .params = params, .encoding = .phc },
666 &buf,673 &buf,
674 io,
667 );675 );
668 try strVerify(str, password, verify_options);676 try strVerify(str, password, verify_options);
669 }677 }