opcua_crypto/aes/
aeskey.rs1use std::result::Result;
8
9use aes::cipher::generic_array::GenericArray;
10use aes::cipher::{block_padding::NoPadding, BlockDecryptMut, BlockEncryptMut, KeyIvInit};
11
12use opcua_types::status_code::StatusCode;
13use opcua_types::Error;
14
15type Aes128CbcEnc = cbc::Encryptor<aes::Aes128>;
16type Aes128CbcDec = cbc::Decryptor<aes::Aes128>;
17type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
18type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
19
20type AesArray128 = GenericArray<u8, <aes::Aes128 as aes::cipher::BlockSizeUser>::BlockSize>;
21type AesArray256 = GenericArray<u8, <aes::Aes256 as aes::cipher::KeySizeUser>::KeySize>;
22
23type EncryptResult = Result<usize, Error>;
24
25#[derive(Debug)]
26pub struct AesKey {
28 value: Vec<u8>,
29}
30impl AesKey {
31 pub fn new(value: Vec<u8>) -> AesKey {
33 AesKey { value }
34 }
35
36 pub fn value(&self) -> &[u8] {
38 &self.value
39 }
40
41 pub(crate) fn encrypt_aes128_cbc(
42 &self,
43 src: &[u8],
44 iv: &[u8],
45 dst: &mut [u8],
46 ) -> EncryptResult {
47 Aes128CbcEnc::new(
48 AesArray128::from_slice(&self.value),
49 AesArray128::from_slice(iv),
50 )
51 .encrypt_padded_b2b_mut::<NoPadding>(src, dst)
52 .map_err(|e| Error::new(StatusCode::BadUnexpectedError, e.to_string()))?;
53 Ok(src.len())
54 }
55
56 pub(crate) fn encrypt_aes256_cbc(
57 &self,
58 src: &[u8],
59 iv: &[u8],
60 dst: &mut [u8],
61 ) -> EncryptResult {
62 Aes256CbcEnc::new(
63 AesArray256::from_slice(&self.value),
64 AesArray128::from_slice(iv),
65 )
66 .encrypt_padded_b2b_mut::<NoPadding>(src, dst)
67 .map_err(|e| Error::new(StatusCode::BadUnexpectedError, e.to_string()))?;
68 Ok(src.len())
69 }
70
71 pub(crate) fn decrypt_aes128_cbc(
72 &self,
73 src: &[u8],
74 iv: &[u8],
75 dst: &mut [u8],
76 ) -> EncryptResult {
77 Aes128CbcDec::new(
78 AesArray128::from_slice(&self.value),
79 AesArray128::from_slice(iv),
80 )
81 .decrypt_padded_b2b_mut::<NoPadding>(src, dst)
82 .map_err(|e| Error::new(StatusCode::BadUnexpectedError, e.to_string()))?;
83 Ok(src.len())
84 }
85
86 pub(crate) fn decrypt_aes256_cbc(
87 &self,
88 src: &[u8],
89 iv: &[u8],
90 dst: &mut [u8],
91 ) -> EncryptResult {
92 Aes256CbcDec::new(
93 AesArray256::from_slice(&self.value),
94 AesArray128::from_slice(iv),
95 )
96 .decrypt_padded_b2b_mut::<NoPadding>(src, dst)
97 .map_err(|e| Error::new(StatusCode::BadUnexpectedError, e.to_string()))?;
98 Ok(src.len())
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use std::thread;
105
106 use super::*;
107
108 #[test]
109 fn test_aeskey_cross_thread() {
110 let v: [u8; 5] = [1, 2, 3, 4, 5];
111 let k = AesKey::new(v.to_vec());
112 let child = thread::spawn(move || {
113 println!("k={k:?}");
114 });
115 let _ = child.join();
116 }
117}