script/dom/subtlecrypto/
aes_cbc_operation.rs1use aes::{Aes128, Aes192, Aes256};
6use cbc::{Decryptor, Encryptor};
7use cipher::block_padding::Pkcs7;
8use cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit};
9use js::context::JSContext;
10
11use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::KeyUsage;
12use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::KeyFormat;
13use crate::dom::bindings::error::Error;
14use crate::dom::bindings::root::DomRoot;
15use crate::dom::cryptokey::{CryptoKey, Handle};
16use crate::dom::globalscope::GlobalScope;
17use crate::dom::subtlecrypto::aes_common::AesAlgorithm;
18use crate::dom::subtlecrypto::{
19 ExportedKey, SubtleAesCbcParams, SubtleAesDerivedKeyParams, SubtleAesKeyGenParams, aes_common,
20};
21
22pub(crate) fn encrypt(
24 normalized_algorithm: &SubtleAesCbcParams,
25 key: &CryptoKey,
26 plaintext: &[u8],
27) -> Result<Vec<u8>, Error> {
28 if normalized_algorithm.iv.len() != 16 {
31 return Err(Error::Operation(Some(
32 "The initialization vector length is not 16 bytes".into(),
33 )));
34 }
35
36 let iv = normalized_algorithm.iv.as_slice();
42 let ciphertext = match key.handle() {
43 Handle::Aes128Key(key) => {
44 let encryptor = Encryptor::<Aes128>::new(key, iv.into());
45 encryptor.encrypt_padded_vec_mut::<Pkcs7>(plaintext)
46 },
47 Handle::Aes192Key(key) => {
48 let encryptor = Encryptor::<Aes192>::new(key, iv.into());
49 encryptor.encrypt_padded_vec_mut::<Pkcs7>(plaintext)
50 },
51 Handle::Aes256Key(key) => {
52 let encryptor = Encryptor::<Aes256>::new(key, iv.into());
53 encryptor.encrypt_padded_vec_mut::<Pkcs7>(plaintext)
54 },
55 _ => {
56 return Err(Error::Operation(Some(
57 "The key handle is not representing an AES key".to_string(),
58 )));
59 },
60 };
61
62 Ok(ciphertext)
64}
65
66pub(crate) fn decrypt(
68 normalized_algorithm: &SubtleAesCbcParams,
69 key: &CryptoKey,
70 ciphertext: &[u8],
71) -> Result<Vec<u8>, Error> {
72 if normalized_algorithm.iv.len() != 16 {
75 return Err(Error::Operation(Some(
76 "The initialization vector length is not 16 bytes".into(),
77 )));
78 }
79
80 if ciphertext.is_empty() {
83 return Err(Error::Operation(Some("The ciphertext is empty".into())));
84 }
85 if ciphertext.len() % 16 != 0 {
86 return Err(Error::Operation(Some(
87 "The ciphertext length is not a multiple of 16 bytes".into(),
88 )));
89 }
90
91 let iv = normalized_algorithm.iv.as_slice();
99 let plaintext = match key.handle() {
100 Handle::Aes128Key(key) => {
101 let decryptor = Decryptor::<Aes128>::new(key, iv.into());
102 decryptor
103 .decrypt_padded_vec_mut::<Pkcs7>(ciphertext)
104 .map_err(|_| {
105 Error::Operation(Some("Failed to perform AES-CBC decryption".to_string()))
106 })?
107 },
108 Handle::Aes192Key(key) => {
109 let decryptor = Decryptor::<Aes192>::new(key, iv.into());
110 decryptor
111 .decrypt_padded_vec_mut::<Pkcs7>(ciphertext)
112 .map_err(|_| {
113 Error::Operation(Some("Failed to perform AES-CBC decryption".to_string()))
114 })?
115 },
116 Handle::Aes256Key(key) => {
117 let decryptor = Decryptor::<Aes256>::new(key, iv.into());
118 decryptor
119 .decrypt_padded_vec_mut::<Pkcs7>(ciphertext)
120 .map_err(|_| {
121 Error::Operation(Some("Failed to perform AES-CBC decryption".to_string()))
122 })?
123 },
124 _ => {
125 return Err(Error::Operation(Some(
126 "The key handle is not representing an AES key".to_string(),
127 )));
128 },
129 };
130 Ok(plaintext)
132}
133
134pub(crate) fn generate_key(
136 cx: &mut JSContext,
137 global: &GlobalScope,
138 normalized_algorithm: &SubtleAesKeyGenParams,
139 extractable: bool,
140 usages: Vec<KeyUsage>,
141) -> Result<DomRoot<CryptoKey>, Error> {
142 aes_common::generate_key(
143 AesAlgorithm::AesCbc,
144 cx,
145 global,
146 normalized_algorithm,
147 extractable,
148 usages,
149 )
150}
151
152pub(crate) fn import_key(
154 cx: &mut JSContext,
155 global: &GlobalScope,
156 format: KeyFormat,
157 key_data: &[u8],
158 extractable: bool,
159 usages: Vec<KeyUsage>,
160) -> Result<DomRoot<CryptoKey>, Error> {
161 aes_common::import_key(
162 AesAlgorithm::AesCbc,
163 cx,
164 global,
165 format,
166 key_data,
167 extractable,
168 usages,
169 )
170}
171
172pub(crate) fn export_key(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
174 aes_common::export_key(AesAlgorithm::AesCbc, format, key)
175}
176
177pub(crate) fn get_key_length(
179 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
180) -> Result<Option<u32>, Error> {
181 aes_common::get_key_length(normalized_derived_key_algorithm)
182}