seq_runtime/crypto/
pbkdf.rs1use crate::seqstring::global_string;
4use crate::stack::{Stack, pop, push};
5use crate::value::Value;
6
7use sha2::Sha256;
8
9use super::{AES_KEY_SIZE, MIN_PBKDF2_ITERATIONS};
10
11#[unsafe(no_mangle)]
27pub unsafe extern "C" fn patch_seq_crypto_pbkdf2_sha256(stack: Stack) -> Stack {
28 assert!(!stack.is_null(), "crypto.pbkdf2-sha256: stack is null");
29
30 let (stack, iterations_val) = unsafe { pop(stack) };
31 let (stack, salt_val) = unsafe { pop(stack) };
32 let (stack, password_val) = unsafe { pop(stack) };
33
34 match (password_val, salt_val, iterations_val) {
35 (Value::String(password), Value::String(salt), Value::Int(iterations)) => {
36 if iterations < MIN_PBKDF2_ITERATIONS {
38 let stack = unsafe { push(stack, Value::String(global_string(String::new()))) };
39 return unsafe { push(stack, Value::Bool(false)) };
40 }
41
42 let key = derive_key_pbkdf2(password.as_bytes(), salt.as_bytes(), iterations as u32);
46 let key_hex = hex::encode(key);
47 let stack = unsafe { push(stack, Value::String(global_string(key_hex))) };
48 unsafe { push(stack, Value::Bool(true)) }
49 }
50 _ => panic!("crypto.pbkdf2-sha256: expected String, String, Int on stack"),
51 }
52}
53
54pub(super) fn derive_key_pbkdf2(
55 password: &[u8],
56 salt: &[u8],
57 iterations: u32,
58) -> [u8; AES_KEY_SIZE] {
59 let mut key = [0u8; AES_KEY_SIZE];
60 pbkdf2::pbkdf2_hmac::<Sha256>(password, salt, iterations, &mut key);
61 key
62}