authorgravatar for rob@neverwood.orgRob Napier <rob@neverwood.org> 2020-09-12 15:02:00-04:00
committergravatar for rob@neverwood.orgRob Napier <rob@neverwood.org> 2020-09-12 15:03:42-04:00
log37db93e4260dfcb90ac1553cf096a35ada1825ca
tree312b8490c7709d7c163904c7756f225a561c0c21
parentc2b02d01d5c0bb684565d5b23b34022b752e9507

Review comments from pbkdf2.zig

Move block definitions inside while loop. Use usize for offset. (This still crashes on overflow) Remove unneeded slice syntax. Add slow test for Very large dkLen

1 files changed, 28 insertions(+), 6 deletions(-)

lib/std/crypto/pbkdf2.zig+28-6
...@@ -95,11 +95,10 @@ pub fn pbkdf2(derivedKey: []u8, password: []const u8, salt: []const u8, rounds:...@@ -95,11 +95,10 @@ pub fn pbkdf2(derivedKey: []u8, password: []const u8, salt: []const u8, rounds:
95 //95 //
96 // DK = T_1 || T_2 || ... || T_l<0..r-1>96 // DK = T_1 || T_2 || ... || T_l<0..r-1>
9797
98 var prevBlock: [hLen]u8 = undefined;
99 var newBlock: [hLen]u8 = undefined;
100
101 var block: u32 = 0; // Spec limits to u3298 var block: u32 = 0; // Spec limits to u32
102 while (block < l) : (block += 1) {99 while (block < l) : (block += 1) {
100 var prevBlock: [hLen]u8 = undefined;
101 var newBlock: [hLen]u8 = undefined;
103102
104 // U_1 = PRF (P, S || INT (i))103 // U_1 = PRF (P, S || INT (i))
105 const blockIndex = mem.toBytes(mem.nativeToBig(u32, block + 1)); // Block index starts at 0001104 const blockIndex = mem.toBytes(mem.nativeToBig(u32, block + 1)); // Block index starts at 0001
...@@ -109,15 +108,15 @@ pub fn pbkdf2(derivedKey: []u8, password: []const u8, salt: []const u8, rounds:...@@ -109,15 +108,15 @@ pub fn pbkdf2(derivedKey: []u8, password: []const u8, salt: []const u8, rounds:
109 ctx.final(prevBlock[0..]);108 ctx.final(prevBlock[0..]);
110109
111 // Choose portion of DK to write into (T_n) and initialize110 // Choose portion of DK to write into (T_n) and initialize
112 const offset = block * hLen;111 const offset: usize = block * hLen;
113 const blockLen = if (block != l - 1) hLen else r;112 const blockLen = if (block != l - 1) hLen else r;
114 var dkBlock = derivedKey[offset..(offset + blockLen)];113 var dkBlock = derivedKey[offset..(offset + blockLen)];
115 mem.copy(u8, dkBlock[0..], prevBlock[0..dkBlock.len]);114 mem.copy(u8, dkBlock, prevBlock[0..dkBlock.len]);
116115
117 var i: u32 = 1;116 var i: u32 = 1;
118 while (i < rounds) : (i += 1) {117 while (i < rounds) : (i += 1) {
119 // U_c = PRF (P, U_{c-1})118 // U_c = PRF (P, U_{c-1})
120 Prf.create(newBlock[0..], prevBlock[0..], password);119 Prf.create(&newBlock, prevBlock[0..], password);
121 mem.copy(u8, prevBlock[0..], newBlock[0..]);120 mem.copy(u8, prevBlock[0..], newBlock[0..]);
122121
123 // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c122 // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
...@@ -225,3 +224,26 @@ test "RFC 6070 embedded NUL" {...@@ -225,3 +224,26 @@ test "RFC 6070 embedded NUL" {
225224
226 htest.assertEqual(expected, derivedKey[0..]);225 htest.assertEqual(expected, derivedKey[0..]);
227}226}
227
228test "Very large dkLen" {
229 // These iteration tests are slow so we always skip them. Results have been verified.
230 if (true) {
231 return error.SkipZigTest;
232 }
233
234 const p = "password";
235 const s = "salt";
236 const c = 1;
237 const dkLen = 1 << 33;
238
239 var derivedKey = try std.testing.allocator.alloc(u8, dkLen);
240 defer {
241 std.testing.allocator.free(derivedKey);
242 }
243
244 pbkdf2(derivedKey, p, s, c, crypto.hash.Sha1);
245
246 const expected = "0c60c80f961f0e71f3a9b524af6012062fe037a6";
247
248 htest.assertEqual(expected, derivedKey[0..]);
249}