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