Skip to content

Commit 8eb88c5

Browse files
committed
add bcrypt_pbkdf
1 parent 6b0c8a7 commit 8eb88c5

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

src/rust-crypto/bcrypt_pbkdf.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4+
// option. This file may not be copied, modified, or distributed
5+
// except according to those terms.
6+
7+
use std::iter::range_step;
8+
use blowfish::Blowfish;
9+
use cryptoutil::{read_u32v_be, write_u32_be, write_u32_le};
10+
use sha2::Sha512;
11+
use digest::Digest;
12+
13+
fn bcrypt_hash(hpass: &[u8], hsalt: &[u8], output: &mut [u8, ..32]) {
14+
let mut bf = Blowfish::init_state();
15+
bf.salted_expand_key(hsalt, hpass);
16+
17+
for _ in range(0, 64) {
18+
bf.expand_key(hsalt);
19+
bf.expand_key(hpass);
20+
}
21+
22+
let mut buf = [0u32, ..8];
23+
read_u32v_be(buf, bytes!("OxychromaticBlowfishSwatDynamite"));
24+
25+
for i in range_step(0u, 8, 2) {
26+
for _ in range(0, 64) {
27+
let (l, r) = bf.encrypt(buf[i], buf[i+1]);
28+
buf[i] = l;
29+
buf[i+1] = r;
30+
}
31+
}
32+
33+
for i in range(0u, 8) {
34+
write_u32_le(output.mut_slice(i*4, (i+1)*4), buf[i]);
35+
}
36+
}
37+
38+
pub fn bcrypt_pbkdf(password: &[u8], salt: &[u8], rounds: uint, output: &mut [u8]) {
39+
let mut hpass = [0u8, ..64];
40+
41+
assert!(password.len() > 0);
42+
assert!(salt.len() > 0);
43+
assert!(rounds > 0);
44+
assert!(output.len() > 0);
45+
assert!(output.len() <= 1024);
46+
47+
let nblocks = (output.len() + 31) / 32;
48+
49+
let mut h = Sha512::new();
50+
h.input(password);
51+
h.result(hpass.as_mut_slice());
52+
53+
for block in range(1u, (nblocks+1)) {
54+
let mut count = [0u8, ..4];
55+
let mut hsalt = [0u8, ..64];
56+
let mut out = [0u8, ..32];
57+
write_u32_be(count.as_mut_slice(), block as u32);
58+
59+
h.reset();
60+
h.input(salt);
61+
h.input(count);
62+
h.result(hsalt);
63+
64+
bcrypt_hash(hpass, hsalt, &mut out);
65+
let mut tmp = out;
66+
67+
for _ in range(1, rounds) {
68+
h.reset();
69+
h.input(tmp);
70+
h.result(hsalt);
71+
72+
bcrypt_hash(hpass, hsalt, &mut tmp);
73+
for i in range(0, out.len()) {
74+
out[i] ^= tmp[i];
75+
}
76+
77+
for i in range(0, out.len()) {
78+
let idx = i * nblocks + (block-1);
79+
if idx < output.len() {
80+
output[idx] = out[i];
81+
}
82+
}
83+
}
84+
}
85+
}

src/rust-crypto/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub mod aes;
1717
pub mod aesni;
1818
pub mod aessafe;
1919
pub mod bcrypt;
20+
pub mod bcrypt_pbkdf;
2021
pub mod blockmodes;
2122
pub mod blowfish;
2223
pub mod buffer;

0 commit comments

Comments
 (0)