| ... | @@ -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); |
| 425 | | 427 | |
| ... | @@ -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); |
| 472 | | 475 | |
| 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 | } |
| 524 | | 528 | |
| ... | @@ -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; |
| 631 | | 635 | |
| 632 | const alloc = std.testing.allocator; | 636 | const alloc = std.testing.allocator; |
| | 637 | const io = std.testing.io; |
| 633 | | 638 | |
| 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)" { |
| 637 | | 642 | |
| 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 | } |
| 643 | | 648 | |
| ... | @@ -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; |
| 646 | | 651 | |
| 647 | const alloc = std.testing.allocator; | 652 | const alloc = std.testing.allocator; |
| | 653 | const io = std.testing.io; |
| 648 | | 654 | |
| 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 | } |