seq_runtime/crypto/
hash.rs1use crate::seqstring::global_string;
4use crate::stack::{Stack, pop, push};
5use crate::value::Value;
6
7use hmac::{Hmac, Mac};
8use sha2::{Digest, Sha256};
9use subtle::ConstantTimeEq;
10
11type HmacSha256 = Hmac<Sha256>;
12
13#[unsafe(no_mangle)]
22pub unsafe extern "C" fn patch_seq_sha256(stack: Stack) -> Stack {
23 assert!(!stack.is_null(), "sha256: stack is empty");
24
25 let (stack, value) = unsafe { pop(stack) };
26
27 match value {
28 Value::String(s) => {
29 let mut hasher = Sha256::new();
30 hasher.update(s.as_str().as_bytes());
31 let result = hasher.finalize();
32 let hex_digest = hex::encode(result);
33 unsafe { push(stack, Value::String(global_string(hex_digest))) }
34 }
35 _ => panic!("sha256: expected String on stack, got {:?}", value),
36 }
37}
38
39#[unsafe(no_mangle)]
49pub unsafe extern "C" fn patch_seq_hmac_sha256(stack: Stack) -> Stack {
50 assert!(!stack.is_null(), "hmac-sha256: stack is empty");
51
52 let (stack, key_value) = unsafe { pop(stack) };
53 let (stack, msg_value) = unsafe { pop(stack) };
54
55 match (msg_value, key_value) {
56 (Value::String(msg), Value::String(key)) => {
57 let mut mac = <HmacSha256 as Mac>::new_from_slice(key.as_str().as_bytes())
58 .expect("HMAC can take any key");
59 mac.update(msg.as_str().as_bytes());
60 let result = mac.finalize();
61 let hex_sig = hex::encode(result.into_bytes());
62 unsafe { push(stack, Value::String(global_string(hex_sig))) }
63 }
64 (msg, key) => panic!(
65 "hmac-sha256: expected (String, String) on stack, got ({:?}, {:?})",
66 msg, key
67 ),
68 }
69}
70
71#[unsafe(no_mangle)]
85pub unsafe extern "C" fn patch_seq_constant_time_eq(stack: Stack) -> Stack {
86 assert!(!stack.is_null(), "constant-time-eq: stack is empty");
87
88 let (stack, b_value) = unsafe { pop(stack) };
89 let (stack, a_value) = unsafe { pop(stack) };
90
91 match (a_value, b_value) {
92 (Value::String(a), Value::String(b)) => {
93 let a_bytes = a.as_str().as_bytes();
94 let b_bytes = b.as_str().as_bytes();
95
96 let eq = a_bytes.ct_eq(b_bytes);
99
100 unsafe { push(stack, Value::Bool(bool::from(eq))) }
101 }
102 (a, b) => panic!(
103 "constant-time-eq: expected (String, String) on stack, got ({:?}, {:?})",
104 a, b
105 ),
106 }
107}