Function opensshKdf [src]

The function used in OpenSSH to derive encryption keys from passphrases. This implementation is compatible with the OpenBSD implementation (https://github.com/openbsd/src/blob/master/lib/libutil/bcrypt_pbkdf.c).

Prototype

pub fn opensshKdf(pass: []const u8, salt: []const u8, key: []u8, rounds: u32) !void

Parameters

pass: []const u8salt: []const u8key: []u8rounds: u32

Source

pub fn opensshKdf(pass: []const u8, salt: []const u8, key: []u8, rounds: u32) !void { var tmp: [32]u8 = undefined; var tmp2: [32]u8 = undefined; if (rounds < 1 or pass.len == 0 or salt.len == 0 or key.len == 0 or key.len > tmp.len * tmp.len) { return error.InvalidInput; } var sha2pass: [Sha512.digest_length]u8 = undefined; Sha512.hash(pass, &sha2pass, .{}); const stride = (key.len + tmp.len - 1) / tmp.len; var amt = (key.len + stride - 1) / stride; if (math.shr(usize, key.len, 32) >= amt) { return error.InvalidInput; } var key_remainder = key.len; var count: u32 = 1; while (key_remainder > 0) : (count += 1) { var count_salt: [4]u8 = undefined; std.mem.writeInt(u32, count_salt[0..], count, .big); var sha2salt: [Sha512.digest_length]u8 = undefined; var h = Sha512.init(.{}); h.update(salt); h.update(&count_salt); h.final(&sha2salt); tmp2 = pbkdf_prf.hash(sha2pass, sha2salt); tmp = tmp2; for (1..rounds) |_| { Sha512.hash(&tmp2, &sha2salt, .{}); tmp2 = pbkdf_prf.hash(sha2pass, sha2salt); for (&tmp, tmp2) |*o, t| o.* ^= t; } amt = @min(amt, key_remainder); key_remainder -= for (0..amt) |i| { const dest = i * stride + (count - 1); if (dest >= key.len) break i; key[dest] = tmp[i]; } else amt; } crypto.secureZero(u8, &tmp); crypto.secureZero(u8, &tmp2); crypto.secureZero(u8, &sha2pass); }