1use aes::cipher::crypto_common::Key;
6use aes::{Aes128, Aes192, Aes256};
7use cipher::generic_array::typenum::{GrEq, IsGreaterOrEqual, IsLessOrEqual, LeEq, NonZero};
8use cipher::{ArrayLength, BlockDecrypt, BlockEncrypt, BlockSizeUser};
9use ocb3::aead::AeadMutInPlace;
10use ocb3::aead::consts::{U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16};
11use ocb3::{KeyInit, Nonce, Ocb3};
12
13use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{KeyType, KeyUsage};
14use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::KeyFormat;
15use crate::dom::bindings::error::Error;
16use crate::dom::bindings::root::DomRoot;
17use crate::dom::cryptokey::{CryptoKey, Handle};
18use crate::dom::globalscope::GlobalScope;
19use crate::dom::subtlecrypto::aes_common::AesAlgorithm;
20use crate::dom::subtlecrypto::{
21 ALG_AES_OCB, ExportedKey, KeyAlgorithmAndDerivatives, SubtleAeadParams,
22 SubtleAesDerivedKeyParams, SubtleAesKeyAlgorithm, SubtleAesKeyGenParams, aes_common,
23};
24use crate::script_runtime::CanGc;
25
26pub(crate) fn encrypt(
28 normalized_algorithm: &SubtleAeadParams,
29 key: &CryptoKey,
30 plaintext: &[u8],
31) -> Result<Vec<u8>, Error> {
32 if normalized_algorithm.iv.len() > 15 {
35 return Err(Error::Operation(Some(
36 "The iv member of normalizedAlgorithm has a length greater than 15 bytes".to_string(),
37 )));
38 }
39
40 let tag_length = match normalized_algorithm.tag_length {
48 None => 128,
49 Some(tag_length) if matches!(tag_length, 64 | 96 | 128) => tag_length,
50 _ => {
51 return Err(Error::Operation(Some(
52 "The tagLength member of normalizedAlgorithm is present, \
53 and not one of 64, 96, or 128"
54 .to_string(),
55 )));
56 },
57 };
58
59 let additional_data = normalized_algorithm
62 .additional_data
63 .as_deref()
64 .unwrap_or_default();
65
66 let iv = &normalized_algorithm.iv;
76 let c = match key.handle() {
77 Handle::Aes128Key(key) => match (iv.len(), tag_length) {
78 (6, 64) => ocb_encrypt::<Aes128, U6, U8>(key, plaintext, iv, additional_data)?,
79 (7, 64) => ocb_encrypt::<Aes128, U7, U8>(key, plaintext, iv, additional_data)?,
80 (8, 64) => ocb_encrypt::<Aes128, U8, U8>(key, plaintext, iv, additional_data)?,
81 (9, 64) => ocb_encrypt::<Aes128, U9, U8>(key, plaintext, iv, additional_data)?,
82 (10, 64) => ocb_encrypt::<Aes128, U10, U8>(key, plaintext, iv, additional_data)?,
83 (11, 64) => ocb_encrypt::<Aes128, U11, U8>(key, plaintext, iv, additional_data)?,
84 (12, 64) => ocb_encrypt::<Aes128, U12, U8>(key, plaintext, iv, additional_data)?,
85 (13, 64) => ocb_encrypt::<Aes128, U13, U8>(key, plaintext, iv, additional_data)?,
86 (14, 64) => ocb_encrypt::<Aes128, U14, U8>(key, plaintext, iv, additional_data)?,
87 (15, 64) => ocb_encrypt::<Aes128, U15, U8>(key, plaintext, iv, additional_data)?,
88
89 (6, 96) => ocb_encrypt::<Aes128, U6, U12>(key, plaintext, iv, additional_data)?,
90 (7, 96) => ocb_encrypt::<Aes128, U7, U12>(key, plaintext, iv, additional_data)?,
91 (8, 96) => ocb_encrypt::<Aes128, U8, U12>(key, plaintext, iv, additional_data)?,
92 (9, 96) => ocb_encrypt::<Aes128, U9, U12>(key, plaintext, iv, additional_data)?,
93 (10, 96) => ocb_encrypt::<Aes128, U10, U12>(key, plaintext, iv, additional_data)?,
94 (11, 96) => ocb_encrypt::<Aes128, U11, U12>(key, plaintext, iv, additional_data)?,
95 (12, 96) => ocb_encrypt::<Aes128, U12, U12>(key, plaintext, iv, additional_data)?,
96 (13, 96) => ocb_encrypt::<Aes128, U13, U12>(key, plaintext, iv, additional_data)?,
97 (14, 96) => ocb_encrypt::<Aes128, U14, U12>(key, plaintext, iv, additional_data)?,
98 (15, 96) => ocb_encrypt::<Aes128, U15, U12>(key, plaintext, iv, additional_data)?,
99
100 (6, 128) => ocb_encrypt::<Aes128, U6, U16>(key, plaintext, iv, additional_data)?,
101 (7, 128) => ocb_encrypt::<Aes128, U7, U16>(key, plaintext, iv, additional_data)?,
102 (8, 128) => ocb_encrypt::<Aes128, U8, U16>(key, plaintext, iv, additional_data)?,
103 (9, 128) => ocb_encrypt::<Aes128, U9, U16>(key, plaintext, iv, additional_data)?,
104 (10, 128) => ocb_encrypt::<Aes128, U10, U16>(key, plaintext, iv, additional_data)?,
105 (11, 128) => ocb_encrypt::<Aes128, U11, U16>(key, plaintext, iv, additional_data)?,
106 (12, 128) => ocb_encrypt::<Aes128, U12, U16>(key, plaintext, iv, additional_data)?,
107 (13, 128) => ocb_encrypt::<Aes128, U13, U16>(key, plaintext, iv, additional_data)?,
108 (14, 128) => ocb_encrypt::<Aes128, U14, U16>(key, plaintext, iv, additional_data)?,
109 (15, 128) => ocb_encrypt::<Aes128, U15, U16>(key, plaintext, iv, additional_data)?,
110
111 _ => {
112 return Err(Error::Operation(Some(format!(
113 "Unsupported IV size ({}-bytes) and/or tag length ({}-bit)",
114 iv.len(),
115 tag_length
116 ))));
117 },
118 },
119 Handle::Aes192Key(key) => match (iv.len(), tag_length) {
120 (6, 64) => ocb_encrypt::<Aes192, U6, U8>(key, plaintext, iv, additional_data)?,
121 (7, 64) => ocb_encrypt::<Aes192, U7, U8>(key, plaintext, iv, additional_data)?,
122 (8, 64) => ocb_encrypt::<Aes192, U8, U8>(key, plaintext, iv, additional_data)?,
123 (9, 64) => ocb_encrypt::<Aes192, U9, U8>(key, plaintext, iv, additional_data)?,
124 (10, 64) => ocb_encrypt::<Aes192, U10, U8>(key, plaintext, iv, additional_data)?,
125 (11, 64) => ocb_encrypt::<Aes192, U11, U8>(key, plaintext, iv, additional_data)?,
126 (12, 64) => ocb_encrypt::<Aes192, U12, U8>(key, plaintext, iv, additional_data)?,
127 (13, 64) => ocb_encrypt::<Aes192, U13, U8>(key, plaintext, iv, additional_data)?,
128 (14, 64) => ocb_encrypt::<Aes192, U14, U8>(key, plaintext, iv, additional_data)?,
129 (15, 64) => ocb_encrypt::<Aes192, U15, U8>(key, plaintext, iv, additional_data)?,
130
131 (6, 96) => ocb_encrypt::<Aes192, U6, U12>(key, plaintext, iv, additional_data)?,
132 (7, 96) => ocb_encrypt::<Aes192, U7, U12>(key, plaintext, iv, additional_data)?,
133 (8, 96) => ocb_encrypt::<Aes192, U8, U12>(key, plaintext, iv, additional_data)?,
134 (9, 96) => ocb_encrypt::<Aes192, U9, U12>(key, plaintext, iv, additional_data)?,
135 (10, 96) => ocb_encrypt::<Aes192, U10, U12>(key, plaintext, iv, additional_data)?,
136 (11, 96) => ocb_encrypt::<Aes192, U11, U12>(key, plaintext, iv, additional_data)?,
137 (12, 96) => ocb_encrypt::<Aes192, U12, U12>(key, plaintext, iv, additional_data)?,
138 (13, 96) => ocb_encrypt::<Aes192, U13, U12>(key, plaintext, iv, additional_data)?,
139 (14, 96) => ocb_encrypt::<Aes192, U14, U12>(key, plaintext, iv, additional_data)?,
140 (15, 96) => ocb_encrypt::<Aes192, U15, U12>(key, plaintext, iv, additional_data)?,
141
142 (6, 128) => ocb_encrypt::<Aes192, U6, U16>(key, plaintext, iv, additional_data)?,
143 (7, 128) => ocb_encrypt::<Aes192, U7, U16>(key, plaintext, iv, additional_data)?,
144 (8, 128) => ocb_encrypt::<Aes192, U8, U16>(key, plaintext, iv, additional_data)?,
145 (9, 128) => ocb_encrypt::<Aes192, U9, U16>(key, plaintext, iv, additional_data)?,
146 (10, 128) => ocb_encrypt::<Aes192, U10, U16>(key, plaintext, iv, additional_data)?,
147 (11, 128) => ocb_encrypt::<Aes192, U11, U16>(key, plaintext, iv, additional_data)?,
148 (12, 128) => ocb_encrypt::<Aes192, U12, U16>(key, plaintext, iv, additional_data)?,
149 (13, 128) => ocb_encrypt::<Aes192, U13, U16>(key, plaintext, iv, additional_data)?,
150 (14, 128) => ocb_encrypt::<Aes192, U14, U16>(key, plaintext, iv, additional_data)?,
151 (15, 128) => ocb_encrypt::<Aes192, U15, U16>(key, plaintext, iv, additional_data)?,
152
153 _ => {
154 return Err(Error::Operation(Some(format!(
155 "Unsupported IV size ({}-bytes) and/or tag length ({}-bit)",
156 iv.len(),
157 tag_length
158 ))));
159 },
160 },
161 Handle::Aes256Key(key) => match (iv.len(), tag_length) {
162 (6, 64) => ocb_encrypt::<Aes256, U6, U8>(key, plaintext, iv, additional_data)?,
163 (7, 64) => ocb_encrypt::<Aes256, U7, U8>(key, plaintext, iv, additional_data)?,
164 (8, 64) => ocb_encrypt::<Aes256, U8, U8>(key, plaintext, iv, additional_data)?,
165 (9, 64) => ocb_encrypt::<Aes256, U9, U8>(key, plaintext, iv, additional_data)?,
166 (10, 64) => ocb_encrypt::<Aes256, U10, U8>(key, plaintext, iv, additional_data)?,
167 (11, 64) => ocb_encrypt::<Aes256, U11, U8>(key, plaintext, iv, additional_data)?,
168 (12, 64) => ocb_encrypt::<Aes256, U12, U8>(key, plaintext, iv, additional_data)?,
169 (13, 64) => ocb_encrypt::<Aes256, U13, U8>(key, plaintext, iv, additional_data)?,
170 (14, 64) => ocb_encrypt::<Aes256, U14, U8>(key, plaintext, iv, additional_data)?,
171 (15, 64) => ocb_encrypt::<Aes256, U15, U8>(key, plaintext, iv, additional_data)?,
172
173 (6, 96) => ocb_encrypt::<Aes256, U6, U12>(key, plaintext, iv, additional_data)?,
174 (7, 96) => ocb_encrypt::<Aes256, U7, U12>(key, plaintext, iv, additional_data)?,
175 (8, 96) => ocb_encrypt::<Aes256, U8, U12>(key, plaintext, iv, additional_data)?,
176 (9, 96) => ocb_encrypt::<Aes256, U9, U12>(key, plaintext, iv, additional_data)?,
177 (10, 96) => ocb_encrypt::<Aes256, U10, U12>(key, plaintext, iv, additional_data)?,
178 (11, 96) => ocb_encrypt::<Aes256, U11, U12>(key, plaintext, iv, additional_data)?,
179 (12, 96) => ocb_encrypt::<Aes256, U12, U12>(key, plaintext, iv, additional_data)?,
180 (13, 96) => ocb_encrypt::<Aes256, U13, U12>(key, plaintext, iv, additional_data)?,
181 (14, 96) => ocb_encrypt::<Aes256, U14, U12>(key, plaintext, iv, additional_data)?,
182 (15, 96) => ocb_encrypt::<Aes256, U15, U12>(key, plaintext, iv, additional_data)?,
183
184 (6, 128) => ocb_encrypt::<Aes256, U6, U16>(key, plaintext, iv, additional_data)?,
185 (7, 128) => ocb_encrypt::<Aes256, U7, U16>(key, plaintext, iv, additional_data)?,
186 (8, 128) => ocb_encrypt::<Aes256, U8, U16>(key, plaintext, iv, additional_data)?,
187 (9, 128) => ocb_encrypt::<Aes256, U9, U16>(key, plaintext, iv, additional_data)?,
188 (10, 128) => ocb_encrypt::<Aes256, U10, U16>(key, plaintext, iv, additional_data)?,
189 (11, 128) => ocb_encrypt::<Aes256, U11, U16>(key, plaintext, iv, additional_data)?,
190 (12, 128) => ocb_encrypt::<Aes256, U12, U16>(key, plaintext, iv, additional_data)?,
191 (13, 128) => ocb_encrypt::<Aes256, U13, U16>(key, plaintext, iv, additional_data)?,
192 (14, 128) => ocb_encrypt::<Aes256, U14, U16>(key, plaintext, iv, additional_data)?,
193 (15, 128) => ocb_encrypt::<Aes256, U15, U16>(key, plaintext, iv, additional_data)?,
194
195 _ => {
196 return Err(Error::Operation(Some(format!(
197 "Unsupported IV size ({}-bytes) and/or tag length ({}-bit)",
198 iv.len(),
199 tag_length
200 ))));
201 },
202 },
203 _ => {
204 return Err(Error::Operation(Some(
205 "The key handle is not representing an AES key".to_string(),
206 )));
207 },
208 };
209
210 Ok(c)
212}
213
214fn ocb_encrypt<Cipher, NonceSize, TagSize>(
216 key: &Key<Cipher>,
217 plaintext: &[u8],
218 iv: &[u8],
219 additional_data: &[u8],
220) -> Result<Vec<u8>, Error>
221where
222 Cipher: BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit + BlockDecrypt,
223 NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U6> + IsLessOrEqual<U15>,
224 GrEq<NonceSize, U6>: NonZero,
225 LeEq<NonceSize, U15>: NonZero,
226 TagSize: ArrayLength<u8> + NonZero + IsLessOrEqual<U16>,
227 LeEq<TagSize, U16>: NonZero,
228{
229 let mut c = plaintext.to_vec();
230 let mut cipher = Ocb3::<Cipher, NonceSize, TagSize>::new(key);
231 cipher
232 .encrypt_in_place(Nonce::from_slice(iv), additional_data, &mut c)
233 .map_err(|_| {
234 Error::Operation(Some("AES-OCB authenticated encryption failed".to_string()))
235 })?;
236 Ok(c)
237}
238
239pub(crate) fn decrypt(
241 normalized_algorithm: &SubtleAeadParams,
242 key: &CryptoKey,
243 ciphertext: &[u8],
244) -> Result<Vec<u8>, Error> {
245 if normalized_algorithm.iv.len() > 15 {
248 return Err(Error::Operation(Some(
249 "The iv member of normalizedAlgorithm has a length greater than 15 bytes".to_string(),
250 )));
251 }
252
253 let tag_length = match normalized_algorithm.tag_length {
261 None => 128,
262 Some(tag_length) if matches!(tag_length, 64 | 96 | 128) => tag_length,
263 _ => {
264 return Err(Error::Operation(Some(
265 "The tagLength member of normalizedAlgorithm is present, \
266 and not one of 64, 96, or 128"
267 .to_string(),
268 )));
269 },
270 };
271
272 if ciphertext.len() * 8 < tag_length as usize {
274 return Err(Error::Operation(Some(
275 "Ciphertext has a length less than tagLength bits".to_string(),
276 )));
277 }
278
279 let additional_data = normalized_algorithm
282 .additional_data
283 .as_deref()
284 .unwrap_or_default();
285
286 let iv = &normalized_algorithm.iv;
301 let plaintext = match key.handle() {
302 Handle::Aes128Key(key) => match (iv.len(), tag_length) {
303 (6, 64) => ocb_decrypt::<Aes128, U6, U8>(key, ciphertext, iv, additional_data)?,
304 (7, 64) => ocb_decrypt::<Aes128, U7, U8>(key, ciphertext, iv, additional_data)?,
305 (8, 64) => ocb_decrypt::<Aes128, U8, U8>(key, ciphertext, iv, additional_data)?,
306 (9, 64) => ocb_decrypt::<Aes128, U9, U8>(key, ciphertext, iv, additional_data)?,
307 (10, 64) => ocb_decrypt::<Aes128, U10, U8>(key, ciphertext, iv, additional_data)?,
308 (11, 64) => ocb_decrypt::<Aes128, U11, U8>(key, ciphertext, iv, additional_data)?,
309 (12, 64) => ocb_decrypt::<Aes128, U12, U8>(key, ciphertext, iv, additional_data)?,
310 (13, 64) => ocb_decrypt::<Aes128, U13, U8>(key, ciphertext, iv, additional_data)?,
311 (14, 64) => ocb_decrypt::<Aes128, U14, U8>(key, ciphertext, iv, additional_data)?,
312 (15, 64) => ocb_decrypt::<Aes128, U15, U8>(key, ciphertext, iv, additional_data)?,
313
314 (6, 96) => ocb_decrypt::<Aes128, U6, U12>(key, ciphertext, iv, additional_data)?,
315 (7, 96) => ocb_decrypt::<Aes128, U7, U12>(key, ciphertext, iv, additional_data)?,
316 (8, 96) => ocb_decrypt::<Aes128, U8, U12>(key, ciphertext, iv, additional_data)?,
317 (9, 96) => ocb_decrypt::<Aes128, U9, U12>(key, ciphertext, iv, additional_data)?,
318 (10, 96) => ocb_decrypt::<Aes128, U10, U12>(key, ciphertext, iv, additional_data)?,
319 (11, 96) => ocb_decrypt::<Aes128, U11, U12>(key, ciphertext, iv, additional_data)?,
320 (12, 96) => ocb_decrypt::<Aes128, U12, U12>(key, ciphertext, iv, additional_data)?,
321 (13, 96) => ocb_decrypt::<Aes128, U13, U12>(key, ciphertext, iv, additional_data)?,
322 (14, 96) => ocb_decrypt::<Aes128, U14, U12>(key, ciphertext, iv, additional_data)?,
323 (15, 96) => ocb_decrypt::<Aes128, U15, U12>(key, ciphertext, iv, additional_data)?,
324
325 (6, 128) => ocb_decrypt::<Aes128, U6, U16>(key, ciphertext, iv, additional_data)?,
326 (7, 128) => ocb_decrypt::<Aes128, U7, U16>(key, ciphertext, iv, additional_data)?,
327 (8, 128) => ocb_decrypt::<Aes128, U8, U16>(key, ciphertext, iv, additional_data)?,
328 (9, 128) => ocb_decrypt::<Aes128, U9, U16>(key, ciphertext, iv, additional_data)?,
329 (10, 128) => ocb_decrypt::<Aes128, U10, U16>(key, ciphertext, iv, additional_data)?,
330 (11, 128) => ocb_decrypt::<Aes128, U11, U16>(key, ciphertext, iv, additional_data)?,
331 (12, 128) => ocb_decrypt::<Aes128, U12, U16>(key, ciphertext, iv, additional_data)?,
332 (13, 128) => ocb_decrypt::<Aes128, U13, U16>(key, ciphertext, iv, additional_data)?,
333 (14, 128) => ocb_decrypt::<Aes128, U14, U16>(key, ciphertext, iv, additional_data)?,
334 (15, 128) => ocb_decrypt::<Aes128, U15, U16>(key, ciphertext, iv, additional_data)?,
335
336 _ => {
337 return Err(Error::Operation(Some(format!(
338 "Unsupported IV size ({}-bytes) and/or tag length ({}-bit)",
339 iv.len(),
340 tag_length
341 ))));
342 },
343 },
344 Handle::Aes192Key(key) => match (iv.len(), tag_length) {
345 (6, 64) => ocb_decrypt::<Aes192, U6, U8>(key, ciphertext, iv, additional_data)?,
346 (7, 64) => ocb_decrypt::<Aes192, U7, U8>(key, ciphertext, iv, additional_data)?,
347 (8, 64) => ocb_decrypt::<Aes192, U8, U8>(key, ciphertext, iv, additional_data)?,
348 (9, 64) => ocb_decrypt::<Aes192, U9, U8>(key, ciphertext, iv, additional_data)?,
349 (10, 64) => ocb_decrypt::<Aes192, U10, U8>(key, ciphertext, iv, additional_data)?,
350 (11, 64) => ocb_decrypt::<Aes192, U11, U8>(key, ciphertext, iv, additional_data)?,
351 (12, 64) => ocb_decrypt::<Aes192, U12, U8>(key, ciphertext, iv, additional_data)?,
352 (13, 64) => ocb_decrypt::<Aes192, U13, U8>(key, ciphertext, iv, additional_data)?,
353 (14, 64) => ocb_decrypt::<Aes192, U14, U8>(key, ciphertext, iv, additional_data)?,
354 (15, 64) => ocb_decrypt::<Aes192, U15, U8>(key, ciphertext, iv, additional_data)?,
355
356 (6, 96) => ocb_decrypt::<Aes192, U6, U12>(key, ciphertext, iv, additional_data)?,
357 (7, 96) => ocb_decrypt::<Aes192, U7, U12>(key, ciphertext, iv, additional_data)?,
358 (8, 96) => ocb_decrypt::<Aes192, U8, U12>(key, ciphertext, iv, additional_data)?,
359 (9, 96) => ocb_decrypt::<Aes192, U9, U12>(key, ciphertext, iv, additional_data)?,
360 (10, 96) => ocb_decrypt::<Aes192, U10, U12>(key, ciphertext, iv, additional_data)?,
361 (11, 96) => ocb_decrypt::<Aes192, U11, U12>(key, ciphertext, iv, additional_data)?,
362 (12, 96) => ocb_decrypt::<Aes192, U12, U12>(key, ciphertext, iv, additional_data)?,
363 (13, 96) => ocb_decrypt::<Aes192, U13, U12>(key, ciphertext, iv, additional_data)?,
364 (14, 96) => ocb_decrypt::<Aes192, U14, U12>(key, ciphertext, iv, additional_data)?,
365 (15, 96) => ocb_decrypt::<Aes192, U15, U12>(key, ciphertext, iv, additional_data)?,
366
367 (6, 128) => ocb_decrypt::<Aes192, U6, U16>(key, ciphertext, iv, additional_data)?,
368 (7, 128) => ocb_decrypt::<Aes192, U7, U16>(key, ciphertext, iv, additional_data)?,
369 (8, 128) => ocb_decrypt::<Aes192, U8, U16>(key, ciphertext, iv, additional_data)?,
370 (9, 128) => ocb_decrypt::<Aes192, U9, U16>(key, ciphertext, iv, additional_data)?,
371 (10, 128) => ocb_decrypt::<Aes192, U10, U16>(key, ciphertext, iv, additional_data)?,
372 (11, 128) => ocb_decrypt::<Aes192, U11, U16>(key, ciphertext, iv, additional_data)?,
373 (12, 128) => ocb_decrypt::<Aes192, U12, U16>(key, ciphertext, iv, additional_data)?,
374 (13, 128) => ocb_decrypt::<Aes192, U13, U16>(key, ciphertext, iv, additional_data)?,
375 (14, 128) => ocb_decrypt::<Aes192, U14, U16>(key, ciphertext, iv, additional_data)?,
376 (15, 128) => ocb_decrypt::<Aes192, U15, U16>(key, ciphertext, iv, additional_data)?,
377
378 _ => {
379 return Err(Error::Operation(Some(format!(
380 "Unsupported IV size ({}-bytes) and/or tag length ({}-bit)",
381 iv.len(),
382 tag_length
383 ))));
384 },
385 },
386 Handle::Aes256Key(key) => match (iv.len(), tag_length) {
387 (6, 64) => ocb_decrypt::<Aes256, U6, U8>(key, ciphertext, iv, additional_data)?,
388 (7, 64) => ocb_decrypt::<Aes256, U7, U8>(key, ciphertext, iv, additional_data)?,
389 (8, 64) => ocb_decrypt::<Aes256, U8, U8>(key, ciphertext, iv, additional_data)?,
390 (9, 64) => ocb_decrypt::<Aes256, U9, U8>(key, ciphertext, iv, additional_data)?,
391 (10, 64) => ocb_decrypt::<Aes256, U10, U8>(key, ciphertext, iv, additional_data)?,
392 (11, 64) => ocb_decrypt::<Aes256, U11, U8>(key, ciphertext, iv, additional_data)?,
393 (12, 64) => ocb_decrypt::<Aes256, U12, U8>(key, ciphertext, iv, additional_data)?,
394 (13, 64) => ocb_decrypt::<Aes256, U13, U8>(key, ciphertext, iv, additional_data)?,
395 (14, 64) => ocb_decrypt::<Aes256, U14, U8>(key, ciphertext, iv, additional_data)?,
396 (15, 64) => ocb_decrypt::<Aes256, U15, U8>(key, ciphertext, iv, additional_data)?,
397
398 (6, 96) => ocb_decrypt::<Aes256, U6, U12>(key, ciphertext, iv, additional_data)?,
399 (7, 96) => ocb_decrypt::<Aes256, U7, U12>(key, ciphertext, iv, additional_data)?,
400 (8, 96) => ocb_decrypt::<Aes256, U8, U12>(key, ciphertext, iv, additional_data)?,
401 (9, 96) => ocb_decrypt::<Aes256, U9, U12>(key, ciphertext, iv, additional_data)?,
402 (10, 96) => ocb_decrypt::<Aes256, U10, U12>(key, ciphertext, iv, additional_data)?,
403 (11, 96) => ocb_decrypt::<Aes256, U11, U12>(key, ciphertext, iv, additional_data)?,
404 (12, 96) => ocb_decrypt::<Aes256, U12, U12>(key, ciphertext, iv, additional_data)?,
405 (13, 96) => ocb_decrypt::<Aes256, U13, U12>(key, ciphertext, iv, additional_data)?,
406 (14, 96) => ocb_decrypt::<Aes256, U14, U12>(key, ciphertext, iv, additional_data)?,
407 (15, 96) => ocb_decrypt::<Aes256, U15, U12>(key, ciphertext, iv, additional_data)?,
408
409 (6, 128) => ocb_decrypt::<Aes256, U6, U16>(key, ciphertext, iv, additional_data)?,
410 (7, 128) => ocb_decrypt::<Aes256, U7, U16>(key, ciphertext, iv, additional_data)?,
411 (8, 128) => ocb_decrypt::<Aes256, U8, U16>(key, ciphertext, iv, additional_data)?,
412 (9, 128) => ocb_decrypt::<Aes256, U9, U16>(key, ciphertext, iv, additional_data)?,
413 (10, 128) => ocb_decrypt::<Aes256, U10, U16>(key, ciphertext, iv, additional_data)?,
414 (11, 128) => ocb_decrypt::<Aes256, U11, U16>(key, ciphertext, iv, additional_data)?,
415 (12, 128) => ocb_decrypt::<Aes256, U12, U16>(key, ciphertext, iv, additional_data)?,
416 (13, 128) => ocb_decrypt::<Aes256, U13, U16>(key, ciphertext, iv, additional_data)?,
417 (14, 128) => ocb_decrypt::<Aes256, U14, U16>(key, ciphertext, iv, additional_data)?,
418 (15, 128) => ocb_decrypt::<Aes256, U15, U16>(key, ciphertext, iv, additional_data)?,
419
420 _ => {
421 return Err(Error::Operation(Some(format!(
422 "Unsupported IV size ({}-bytes) and/or tag length ({}-bit)",
423 iv.len(),
424 tag_length
425 ))));
426 },
427 },
428 _ => {
429 return Err(Error::Operation(Some(
430 "The key handle is not representing an AES key".to_string(),
431 )));
432 },
433 };
434
435 Ok(plaintext)
437}
438
439fn ocb_decrypt<Cipher, NonceSize, TagSize>(
441 key: &Key<Cipher>,
442 ciphertext: &[u8],
443 iv: &[u8],
444 additional_data: &[u8],
445) -> Result<Vec<u8>, Error>
446where
447 Cipher: BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit + BlockDecrypt,
448 NonceSize: ArrayLength<u8> + IsGreaterOrEqual<U6> + IsLessOrEqual<U15>,
449 GrEq<NonceSize, U6>: NonZero,
450 LeEq<NonceSize, U15>: NonZero,
451 TagSize: ArrayLength<u8> + NonZero + IsLessOrEqual<U16>,
452 LeEq<TagSize, U16>: NonZero,
453{
454 let mut plaintext = ciphertext.to_vec();
455 let mut cipher = Ocb3::<Cipher, NonceSize, TagSize>::new(key);
456 cipher
457 .decrypt_in_place(Nonce::from_slice(iv), additional_data, &mut plaintext)
458 .map_err(|_| {
459 Error::Operation(Some("AES-OCB authenticated decryption failed".to_string()))
460 })?;
461 Ok(plaintext)
462}
463
464pub(crate) fn generate_key(
466 global: &GlobalScope,
467 normalized_algorithm: &SubtleAesKeyGenParams,
468 extractable: bool,
469 usages: Vec<KeyUsage>,
470 can_gc: CanGc,
471) -> Result<DomRoot<CryptoKey>, Error> {
472 aes_common::generate_key(
473 AesAlgorithm::AesOcb,
474 global,
475 normalized_algorithm,
476 extractable,
477 usages,
478 can_gc,
479 )
480}
481
482pub(crate) fn import_key(
484 global: &GlobalScope,
485 format: KeyFormat,
486 key_data: &[u8],
487 extractable: bool,
488 usages: Vec<KeyUsage>,
489 can_gc: CanGc,
490) -> Result<DomRoot<CryptoKey>, Error> {
491 if usages.iter().any(|usage| {
496 !matches!(
497 usage,
498 KeyUsage::Encrypt | KeyUsage::Decrypt | KeyUsage::WrapKey | KeyUsage::UnwrapKey
499 )
500 }) {
501 return Err(Error::Syntax(Some(
502 "Usages contains an entry which is not one of \"encrypt\", \"decrypt\", \"wrapKey\" \
503 or \"unwrapKey\""
504 .to_string(),
505 )));
506 }
507
508 let data = aes_common::import_key_from_key_data(
510 AesAlgorithm::AesOcb,
511 format,
512 key_data,
513 extractable,
514 &usages,
515 )?;
516
517 let handle = match data.len() {
523 16 => Handle::Aes128Key(Key::<Aes128>::clone_from_slice(&data)),
524 24 => Handle::Aes192Key(Key::<Aes192>::clone_from_slice(&data)),
525 32 => Handle::Aes256Key(Key::<Aes256>::clone_from_slice(&data)),
526 _ => {
527 return Err(Error::Data(Some(
528 "The length in bits of key is not 128, 192 or 256".to_string(),
529 )));
530 },
531 };
532 let algorithm = SubtleAesKeyAlgorithm {
533 name: ALG_AES_OCB.to_string(),
534 length: data.len() as u16 * 8,
535 };
536 let key = CryptoKey::new(
537 global,
538 KeyType::Secret,
539 extractable,
540 KeyAlgorithmAndDerivatives::AesKeyAlgorithm(algorithm),
541 usages,
542 handle,
543 can_gc,
544 );
545
546 Ok(key)
548}
549
550pub(crate) fn export_key(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
552 aes_common::export_key(AesAlgorithm::AesOcb, format, key)
553}
554
555pub(crate) fn get_key_length(
557 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
558) -> Result<Option<u32>, Error> {
559 aes_common::get_key_length(normalized_derived_key_algorithm)
560}