Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bcrypt pbkdf #10331

Merged
merged 2 commits into from Dec 27, 2021
Merged

Bcrypt pbkdf #10331

merged 2 commits into from Dec 27, 2021

Conversation

daurnimator
Copy link
Collaborator

Tested with:

// Test against OpenBSD implementation https://github.com/openbsd/src/blob/6df1256b7792691e66c2ed9d86a8c103069f9e34/lib/libutil/bcrypt_pbkdf.c#L98

const std = @import("std");
const crypto = std.crypto;
const testing = std.testing;
const bcrypt = crypto.pwhash.bcrypt;
const Sha512 = crypto.hash.sha2.Sha512;

extern fn bcrypt_hash(
    sha2pass: *const [Sha512.digest_length]u8,
    sha2salt: *const [Sha512.digest_length]u8,
    out: *[32]u8,
) void;
test "bcrypt_hash" {
    var c_out: [32]u8 = undefined;
    bcrypt_hash("Hi" ** 32, "Salt" ** 16, &c_out);

    const zig_out = bcrypt.pbkdf_prf.hash("Hi".* ** 32, "Salt".* ** 16);

    try testing.expectEqualSlices(u8, &c_out, &zig_out);
}

extern fn bcrypt_pbkdf(
    pass: [*]const u8,
    passlen: usize,
    salt: [*]const u8,
    saltlen: usize,
    key: [*]u8,
    keylen: usize,
    rounds: c_uint,
) c_int;
test "bcrypt_pbkdf" {
    var c_out: [32]u8 = undefined;
    switch (bcrypt_pbkdf("password", 8, "salt", 4, &c_out, c_out.len, 15)) {
        0 => {},
        else => return error.TestFailed,
    }

    var zig_out: [32]u8 = undefined;
    try bcrypt.pbkdf("password", "salt", &zig_out, 15);

    try testing.expectEqualSlices(u8, &c_out, &zig_out);
}

This is useful to implement the various protocols outside of the standard library
This variant is used in e.g. SSH
The OpenBSD implementation was used as a reference
@daurnimator daurnimator added the standard library This issue involves writing Zig code for the standard library. label Dec 13, 2021
@jedisct1
Copy link
Contributor

Looking good!

bcrypt_pbkdf is a strange beast, since key stretching is actually using pbkdf and not bcrypt as in the password hashing function.

In that context, a pbkdf() function as you did instead of the standard kdf() interface makes sense.

One would expect symmetry between a password hashing function used for password storage and the same core function used a generic kdf. This is not the case here; parameters are not comparable.

This is very useful to decrypt SSH keys, so thank you for this!

@jedisct1 jedisct1 merged commit 2c23699 into ziglang:master Dec 27, 2021
@daurnimator daurnimator deleted the bcrypt_pbkdf branch December 28, 2021 02:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants