Function kdf [src]
Apply scrypt to generate a key from a password.
scrypt is defined in RFC 7914.
allocator: mem.Allocator.
derived_key: Slice of appropriate size for generated key. Generally 16 or 32 bytes in length.
May be uninitialized. All bytes will be overwritten.
Maximum size is derived_key.len / 32 == 0xffff_ffff.
password: Arbitrary sequence of bytes of any length.
salt: Arbitrary sequence of bytes of any length.
params: Params.
Prototype
pub fn kdf( allocator: mem.Allocator, derived_key: []u8, password: []const u8, salt: []const u8, params: Params, ) KdfError!void
Parameters
allocator: mem.Allocator
derived_key: []u8
password: []const u8
salt: []const u8
params: Params
Possible Errors
mlockall
is enabled, and the memory needed to spawn the thread
would exceed the limit.
Not enough userland memory to spawn the thread.
The kernel cannot allocate sufficient memory to allocate a task structure for the child, or to copy those parts of the caller's context that need to be copied.
A system-imposed limit on the number of threads was encountered. There are a number of limits that may trigger this error:
- the RLIMIT_NPROC soft resource limit (set via setrlimit(2)), which limits the number of processes and threads for a real user ID, was reached;
- the kernel's system-wide limit on the number of processes and threads, /proc/sys/kernel/threads-max, was reached (see proc(5));
- the maximum number of PIDs, /proc/sys/kernel/pid_max, was reached (see proc(5)); or
- the PID limit (pids.max) imposed by the cgroup "process num‐ ber" (PIDs) controller was reached.
Source
pub fn kdf(
allocator: mem.Allocator,
derived_key: []u8,
password: []const u8,
salt: []const u8,
params: Params,
) KdfError!void {
if (derived_key.len == 0) return KdfError.WeakParameters;
if (derived_key.len / 32 > 0xffff_ffff) return KdfError.OutputTooLong;
if (params.ln == 0 or params.r == 0 or params.p == 0) return KdfError.WeakParameters;
const n64 = @as(u64, 1) << params.ln;
if (n64 > max_size) return KdfError.WeakParameters;
const n = @as(usize, @intCast(n64));
if (@as(u64, params.r) * @as(u64, params.p) >= 1 << 30 or
params.r > max_int / 128 / @as(u64, params.p) or
params.r > max_int / 256 or
n > max_int / 128 / @as(u64, params.r)) return KdfError.WeakParameters;
const xy = try allocator.alignedAlloc(u32, 16, 64 * params.r);
defer allocator.free(xy);
const v = try allocator.alignedAlloc(u32, 16, 32 * n * params.r);
defer allocator.free(v);
var dk = try allocator.alignedAlloc(u8, 16, params.p * 128 * params.r);
defer allocator.free(dk);
try pwhash.pbkdf2(dk, password, salt, 1, HmacSha256);
var i: u32 = 0;
while (i < params.p) : (i += 1) {
smix(@alignCast(dk[i * 128 * params.r ..]), params.r, n, v, xy);
}
try pwhash.pbkdf2(derived_key, password, dk, 1, HmacSha256);
}