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

crypto: add a crypto.pbkdf2 module #22047

Merged
merged 7 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions vlib/crypto/pbkdf2/pbkdf2.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Based off: https://golang.org/x/crypto/pbkdf2
module pbkdf2

import crypto.hmac
import crypto.sha256
import crypto.sha512
import hash

// key derives a key from the password, salt and iteration count
// example pbkdf2.key('test'.bytes(), '123456'.bytes(), 1000, 64, sha512.new())
pub fn key(password []u8, salt []u8, count int, key_length int, h hash.Hash) ![]u8 {
spytheman marked this conversation as resolved.
Show resolved Hide resolved
mut fun := fn (b []u8) []u8 {
return []u8{}
}
mut block_size := 0
mut size := 0
match h {
sha256.Digest {
fun = sha256.sum256
block_size = sha256.block_size
size = sha256.size
}
sha512.Digest {
fun = sha512.sum512
block_size = sha512.block_size
size = sha512.size
}
else {
panic('Unsupported hash')
}
}

hash_length := size
block_count := (key_length + hash_length - 1) / hash_length
mut output := []u8{}
mut last := []u8{}
mut buf := []u8{len: 4}
for i := 1; i <= block_count; i++ {
last << salt

buf[0] = u8(i >> 24)
buf[1] = u8(i >> 16)
buf[2] = u8(i >> 8)
buf[3] = u8(i)

last << buf
mut xorsum := hmac.new(password, last, fun, block_size)
mut last_hash := xorsum.clone()
for j := 1; j < count; j++ {
last_hash = hmac.new(password, last_hash, fun, block_size)
for k in 0 .. xorsum.len {
xorsum[k] ^= last_hash[k]
}
}
output << xorsum
}
return output[..key_length]
spytheman marked this conversation as resolved.
Show resolved Hide resolved
}
18 changes: 18 additions & 0 deletions vlib/crypto/pbkdf2/pbkdf2_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import crypto.sha512
import crypto.sha256
import crypto.pbkdf2

const data = 'test'
const password = '123456'

fn test_sha512() {
// vfmt off
assert pbkdf2.key(data.bytes(), password.bytes(), 1000, 64, sha512.new())! == [u8(149) 155 168 16 77 243 26 192 128 222 29 139 38 173 131 82 73 152 197 253 66 64 11 103 32 110 95 116 143 4 104 70 176 24 99 48 224 77 47 184 193 59 98 191 18 172 4 119 83 93 198 101 118 131 223 150 215 172 170 166 205 187 247 160]
// vfmt on
}

fn test_sha256() {
// vfmt off
assert pbkdf2.key(data.bytes(), password.bytes(), 1000, 32, sha256.new())! == [u8(110) 95 68 212 254 34 114 21 43 19 155 141 36 158 236 51 16 244 85 107 245 172 219 25 128 109 111 18 25 14 9 149]
// vfmt on
}
Loading