1use aes::cipher::crypto_common::Key;
6use aes::{Aes128, Aes192, Aes256};
7use cipher::{KeyIvInit, StreamCipher};
8use ctr::Ctr128BE;
9
10use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{KeyType, KeyUsage};
11use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::KeyFormat;
12use crate::dom::bindings::error::Error;
13use crate::dom::bindings::root::DomRoot;
14use crate::dom::cryptokey::{CryptoKey, Handle};
15use crate::dom::globalscope::GlobalScope;
16use crate::dom::subtlecrypto::aes_common::AesAlgorithm;
17use crate::dom::subtlecrypto::{
18 ALG_AES_CTR, ExportedKey, KeyAlgorithmAndDerivatives, SubtleAesCtrParams,
19 SubtleAesDerivedKeyParams, SubtleAesKeyAlgorithm, SubtleAesKeyGenParams, aes_common,
20};
21use crate::script_runtime::CanGc;
22
23pub(crate) fn encrypt(
25 normalized_algorithm: &SubtleAesCtrParams,
26 key: &CryptoKey,
27 plaintext: &[u8],
28) -> Result<Vec<u8>, Error> {
29 if normalized_algorithm.counter.len() != 16 {
32 return Err(Error::Operation(Some(
33 "The initial counter block length is not 16 bytes".into(),
34 )));
35 }
36
37 if normalized_algorithm.length == 0 {
40 return Err(Error::Operation(Some("The counter length is zero".into())));
41 }
42 if normalized_algorithm.length > 128 {
43 return Err(Error::Operation(Some(
44 "The counter length is greater than 128".into(),
45 )));
46 }
47
48 let iv = normalized_algorithm.counter.as_slice();
54 let mut ciphertext = plaintext.to_vec();
55 match key.handle() {
56 Handle::Aes128Key(key) => {
57 let mut cipher = Ctr128BE::<Aes128>::new(key, iv.into());
58 cipher.apply_keystream(&mut ciphertext);
59 },
60 Handle::Aes192Key(key) => {
61 let mut cipher = Ctr128BE::<Aes192>::new(key, iv.into());
62 cipher.apply_keystream(&mut ciphertext);
63 },
64 Handle::Aes256Key(key) => {
65 let mut cipher = Ctr128BE::<Aes256>::new(key, iv.into());
66 cipher.apply_keystream(&mut ciphertext);
67 },
68 _ => {
69 return Err(Error::Operation(Some(
70 "The key handle is not representing an AES key".to_string(),
71 )));
72 },
73 };
74
75 Ok(ciphertext)
77}
78
79pub(crate) fn decrypt(
81 normalized_algorithm: &SubtleAesCtrParams,
82 key: &CryptoKey,
83 ciphertext: &[u8],
84) -> Result<Vec<u8>, Error> {
85 if normalized_algorithm.counter.len() != 16 {
88 return Err(Error::Operation(Some(
89 "The initial counter block length is not 16 bytes".into(),
90 )));
91 }
92
93 if normalized_algorithm.length == 0 {
96 return Err(Error::Operation(Some("The counter length is zero".into())));
97 }
98 if normalized_algorithm.length > 128 {
99 return Err(Error::Operation(Some(
100 "The counter length is greater than 128".into(),
101 )));
102 }
103
104 let iv = normalized_algorithm.counter.as_slice();
110 let mut plaintext = ciphertext.to_vec();
111 match key.handle() {
112 Handle::Aes128Key(key) => {
113 let mut cipher = Ctr128BE::<Aes128>::new(key, iv.into());
114 cipher.apply_keystream(&mut plaintext);
115 },
116 Handle::Aes192Key(key) => {
117 let mut cipher = Ctr128BE::<Aes192>::new(key, iv.into());
118 cipher.apply_keystream(&mut plaintext);
119 },
120 Handle::Aes256Key(key) => {
121 let mut cipher = Ctr128BE::<Aes256>::new(key, iv.into());
122 cipher.apply_keystream(&mut plaintext);
123 },
124 _ => {
125 return Err(Error::Operation(Some(
126 "The key handle is not representing an AES key".to_string(),
127 )));
128 },
129 };
130
131 Ok(plaintext)
133}
134
135pub(crate) fn generate_key(
137 global: &GlobalScope,
138 normalized_algorithm: &SubtleAesKeyGenParams,
139 extractable: bool,
140 usages: Vec<KeyUsage>,
141 can_gc: CanGc,
142) -> Result<DomRoot<CryptoKey>, Error> {
143 aes_common::generate_key(
144 AesAlgorithm::AesCtr,
145 global,
146 normalized_algorithm,
147 extractable,
148 usages,
149 can_gc,
150 )
151}
152
153pub(crate) fn import_key(
155 global: &GlobalScope,
156 format: KeyFormat,
157 key_data: &[u8],
158 extractable: bool,
159 usages: Vec<KeyUsage>,
160 can_gc: CanGc,
161) -> Result<DomRoot<CryptoKey>, Error> {
162 if usages.iter().any(|usage| {
167 !matches!(
168 usage,
169 KeyUsage::Encrypt | KeyUsage::Decrypt | KeyUsage::WrapKey | KeyUsage::UnwrapKey
170 )
171 }) {
172 return Err(Error::Syntax(Some(
173 "Usages contains an entry which is not one of \"encrypt\", \"decrypt\", \"wrapKey\" \
174 or \"unwrapKey\""
175 .to_string(),
176 )));
177 }
178
179 let data = aes_common::import_key_from_key_data(
181 AesAlgorithm::AesCtr,
182 format,
183 key_data,
184 extractable,
185 &usages,
186 )?;
187
188 let handle = match data.len() {
194 16 => Handle::Aes128Key(Key::<Aes128>::clone_from_slice(&data)),
195 24 => Handle::Aes192Key(Key::<Aes192>::clone_from_slice(&data)),
196 32 => Handle::Aes256Key(Key::<Aes256>::clone_from_slice(&data)),
197 _ => {
198 return Err(Error::Data(Some(
199 "The length in bits of data is not 128, 192 or 256".to_string(),
200 )));
201 },
202 };
203 let algorithm = SubtleAesKeyAlgorithm {
204 name: ALG_AES_CTR.to_string(),
205 length: data.len() as u16 * 8,
206 };
207 let key = CryptoKey::new(
208 global,
209 KeyType::Secret,
210 extractable,
211 KeyAlgorithmAndDerivatives::AesKeyAlgorithm(algorithm),
212 usages,
213 handle,
214 can_gc,
215 );
216
217 Ok(key)
219}
220
221pub(crate) fn export_key(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
223 aes_common::export_key(AesAlgorithm::AesCtr, format, key)
224}
225
226pub(crate) fn get_key_length(
228 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
229) -> Result<Option<u32>, Error> {
230 aes_common::get_key_length(normalized_derived_key_algorithm)
231}