1use aes::cipher::crypto_common::Key;
6use aes::cipher::typenum::{U12, U13, U14, U15, U16, U32};
7use aes::{Aes128, Aes192, Aes256};
8use aes_gcm::aead::AeadMutInPlace;
9use aes_gcm::{AesGcm, KeyInit};
10use cipher::{ArrayLength, BlockCipher, BlockEncrypt, BlockSizeUser};
11
12use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{KeyType, KeyUsage};
13use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::KeyFormat;
14use crate::dom::bindings::error::Error;
15use crate::dom::bindings::root::DomRoot;
16use crate::dom::cryptokey::{CryptoKey, Handle};
17use crate::dom::globalscope::GlobalScope;
18use crate::dom::subtlecrypto::aes_common::AesAlgorithm;
19use crate::dom::subtlecrypto::{
20 ALG_AES_GCM, ExportedKey, KeyAlgorithmAndDerivatives, SubtleAesDerivedKeyParams,
21 SubtleAesGcmParams, SubtleAesKeyAlgorithm, SubtleAesKeyGenParams, aes_common,
22};
23use crate::script_runtime::CanGc;
24
25pub(crate) fn encrypt(
27 normalized_algorithm: &SubtleAesGcmParams,
28 key: &CryptoKey,
29 plaintext: &[u8],
30) -> Result<Vec<u8>, Error> {
31 if plaintext.len() as u64 > (1 << 39) - 256 {
34 return Err(Error::Operation(Some("The plaintext is too long".into())));
35 }
36
37 if normalized_algorithm.iv.len() > u64::MAX as usize {
40 return Err(Error::Operation(Some(
41 "The iv member of normalizedAlgorithm is too long".into(),
42 )));
43 }
44
45 if normalized_algorithm
48 .additional_data
49 .as_ref()
50 .is_some_and(|data| data.len() > u64::MAX as usize)
51 {
52 return Err(Error::Operation(Some(
53 "The additional authentication data is too long".into(),
54 )));
55 }
56
57 let tag_length = match normalized_algorithm.tag_length {
65 None => 128,
66 Some(tag_length) if matches!(tag_length, 32 | 64 | 96 | 104 | 112 | 120 | 128) => {
67 tag_length
68 },
69 _ => {
70 return Err(Error::Operation(Some(
71 "The tagLength member of normalizedAlgorithm is present, \
72 and not one of 32, 64, 96, 104, 112, 120 or 128"
73 .to_string(),
74 )));
75 },
76 };
77
78 let additional_data = normalized_algorithm
81 .additional_data
82 .as_deref()
83 .unwrap_or_default();
84
85 let iv = normalized_algorithm.iv.as_slice();
100 let ciphertext = match key.handle() {
101 Handle::Aes128Key(key) => match (iv.len(), tag_length) {
102 (12, 32) => {
104 let mut ciphertext =
105 gcm_encrypt::<Aes128, U12, U12>(key, plaintext, iv, additional_data)?;
106 ciphertext.truncate(ciphertext.len() - 8);
107 ciphertext
108 },
109 (12, 64) => {
110 let mut ciphertext =
111 gcm_encrypt::<Aes128, U12, U12>(key, plaintext, iv, additional_data)?;
112 ciphertext.truncate(ciphertext.len() - 4);
113 ciphertext
114 },
115 (12, 96) => gcm_encrypt::<Aes128, U12, U12>(key, plaintext, iv, additional_data)?,
116 (12, 104) => gcm_encrypt::<Aes128, U12, U13>(key, plaintext, iv, additional_data)?,
117 (12, 112) => gcm_encrypt::<Aes128, U12, U14>(key, plaintext, iv, additional_data)?,
118 (12, 120) => gcm_encrypt::<Aes128, U12, U15>(key, plaintext, iv, additional_data)?,
119 (12, 128) => gcm_encrypt::<Aes128, U12, U16>(key, plaintext, iv, additional_data)?,
120
121 (16, 32) => {
123 let mut ciphertext =
124 gcm_encrypt::<Aes128, U16, U12>(key, plaintext, iv, additional_data)?;
125 ciphertext.truncate(ciphertext.len() - 8);
126 ciphertext
127 },
128 (16, 64) => {
129 let mut ciphertext =
130 gcm_encrypt::<Aes128, U16, U12>(key, plaintext, iv, additional_data)?;
131 ciphertext.truncate(ciphertext.len() - 4);
132 ciphertext
133 },
134 (16, 96) => gcm_encrypt::<Aes128, U16, U12>(key, plaintext, iv, additional_data)?,
135 (16, 104) => gcm_encrypt::<Aes128, U16, U13>(key, plaintext, iv, additional_data)?,
136 (16, 112) => gcm_encrypt::<Aes128, U16, U14>(key, plaintext, iv, additional_data)?,
137 (16, 120) => gcm_encrypt::<Aes128, U16, U15>(key, plaintext, iv, additional_data)?,
138 (16, 128) => gcm_encrypt::<Aes128, U16, U16>(key, plaintext, iv, additional_data)?,
139
140 (32, 32) => {
142 let mut ciphertext =
143 gcm_encrypt::<Aes128, U32, U12>(key, plaintext, iv, additional_data)?;
144 ciphertext.truncate(ciphertext.len() - 8);
145 ciphertext
146 },
147 (32, 64) => {
148 let mut ciphertext =
149 gcm_encrypt::<Aes128, U32, U12>(key, plaintext, iv, additional_data)?;
150 ciphertext.truncate(ciphertext.len() - 4);
151 ciphertext
152 },
153 (32, 96) => gcm_encrypt::<Aes128, U32, U12>(key, plaintext, iv, additional_data)?,
154 (32, 104) => gcm_encrypt::<Aes128, U32, U13>(key, plaintext, iv, additional_data)?,
155 (32, 112) => gcm_encrypt::<Aes128, U32, U14>(key, plaintext, iv, additional_data)?,
156 (32, 120) => gcm_encrypt::<Aes128, U32, U15>(key, plaintext, iv, additional_data)?,
157 (32, 128) => gcm_encrypt::<Aes128, U32, U16>(key, plaintext, iv, additional_data)?,
158 _ => {
159 return Err(Error::Operation(Some(format!(
160 "Unsupported iv size ({}-bit) and/or tag length ({}-bit)",
161 iv.len() * 8,
162 tag_length
163 ))));
164 },
165 },
166 Handle::Aes192Key(key) => match (iv.len(), tag_length) {
167 (12, 32) => {
169 let mut ciphertext =
170 gcm_encrypt::<Aes192, U12, U12>(key, plaintext, iv, additional_data)?;
171 ciphertext.truncate(ciphertext.len() - 8);
172 ciphertext
173 },
174 (12, 64) => {
175 let mut ciphertext =
176 gcm_encrypt::<Aes192, U12, U12>(key, plaintext, iv, additional_data)?;
177 ciphertext.truncate(ciphertext.len() - 4);
178 ciphertext
179 },
180 (12, 96) => gcm_encrypt::<Aes192, U12, U12>(key, plaintext, iv, additional_data)?,
181 (12, 104) => gcm_encrypt::<Aes192, U12, U13>(key, plaintext, iv, additional_data)?,
182 (12, 112) => gcm_encrypt::<Aes192, U12, U14>(key, plaintext, iv, additional_data)?,
183 (12, 120) => gcm_encrypt::<Aes192, U12, U15>(key, plaintext, iv, additional_data)?,
184 (12, 128) => gcm_encrypt::<Aes192, U12, U16>(key, plaintext, iv, additional_data)?,
185
186 (16, 32) => {
188 let mut ciphertext =
189 gcm_encrypt::<Aes192, U16, U12>(key, plaintext, iv, additional_data)?;
190 ciphertext.truncate(ciphertext.len() - 8);
191 ciphertext
192 },
193 (16, 64) => {
194 let mut ciphertext =
195 gcm_encrypt::<Aes192, U16, U12>(key, plaintext, iv, additional_data)?;
196 ciphertext.truncate(ciphertext.len() - 4);
197 ciphertext
198 },
199 (16, 96) => gcm_encrypt::<Aes192, U16, U12>(key, plaintext, iv, additional_data)?,
200 (16, 104) => gcm_encrypt::<Aes192, U16, U13>(key, plaintext, iv, additional_data)?,
201 (16, 112) => gcm_encrypt::<Aes192, U16, U14>(key, plaintext, iv, additional_data)?,
202 (16, 120) => gcm_encrypt::<Aes192, U16, U15>(key, plaintext, iv, additional_data)?,
203 (16, 128) => gcm_encrypt::<Aes192, U16, U16>(key, plaintext, iv, additional_data)?,
204
205 (32, 32) => {
207 let mut ciphertext =
208 gcm_encrypt::<Aes192, U32, U12>(key, plaintext, iv, additional_data)?;
209 ciphertext.truncate(ciphertext.len() - 8);
210 ciphertext
211 },
212 (32, 64) => {
213 let mut ciphertext =
214 gcm_encrypt::<Aes192, U32, U12>(key, plaintext, iv, additional_data)?;
215 ciphertext.truncate(ciphertext.len() - 4);
216 ciphertext
217 },
218 (32, 96) => gcm_encrypt::<Aes192, U32, U12>(key, plaintext, iv, additional_data)?,
219 (32, 104) => gcm_encrypt::<Aes192, U32, U13>(key, plaintext, iv, additional_data)?,
220 (32, 112) => gcm_encrypt::<Aes192, U32, U14>(key, plaintext, iv, additional_data)?,
221 (32, 120) => gcm_encrypt::<Aes192, U32, U15>(key, plaintext, iv, additional_data)?,
222 (32, 128) => gcm_encrypt::<Aes192, U32, U16>(key, plaintext, iv, additional_data)?,
223 _ => {
224 return Err(Error::Operation(Some(format!(
225 "Unsupported iv size ({}-bit) and/or tag length ({}-bit)",
226 iv.len() * 8,
227 tag_length
228 ))));
229 },
230 },
231 Handle::Aes256Key(key) => match (iv.len(), tag_length) {
232 (12, 32) => {
234 let mut ciphertext =
235 gcm_encrypt::<Aes256, U12, U12>(key, plaintext, iv, additional_data)?;
236 ciphertext.truncate(ciphertext.len() - 8);
237 ciphertext
238 },
239 (12, 64) => {
240 let mut ciphertext =
241 gcm_encrypt::<Aes256, U12, U12>(key, plaintext, iv, additional_data)?;
242 ciphertext.truncate(ciphertext.len() - 4);
243 ciphertext
244 },
245 (12, 96) => gcm_encrypt::<Aes256, U12, U12>(key, plaintext, iv, additional_data)?,
246 (12, 104) => gcm_encrypt::<Aes256, U12, U13>(key, plaintext, iv, additional_data)?,
247 (12, 112) => gcm_encrypt::<Aes256, U12, U14>(key, plaintext, iv, additional_data)?,
248 (12, 120) => gcm_encrypt::<Aes256, U12, U15>(key, plaintext, iv, additional_data)?,
249 (12, 128) => gcm_encrypt::<Aes256, U12, U16>(key, plaintext, iv, additional_data)?,
250
251 (16, 32) => {
253 let mut ciphertext =
254 gcm_encrypt::<Aes256, U16, U12>(key, plaintext, iv, additional_data)?;
255 ciphertext.truncate(ciphertext.len() - 8);
256 ciphertext
257 },
258 (16, 64) => {
259 let mut ciphertext =
260 gcm_encrypt::<Aes256, U16, U12>(key, plaintext, iv, additional_data)?;
261 ciphertext.truncate(ciphertext.len() - 4);
262 ciphertext
263 },
264 (16, 96) => gcm_encrypt::<Aes256, U16, U12>(key, plaintext, iv, additional_data)?,
265 (16, 104) => gcm_encrypt::<Aes256, U16, U13>(key, plaintext, iv, additional_data)?,
266 (16, 112) => gcm_encrypt::<Aes256, U16, U14>(key, plaintext, iv, additional_data)?,
267 (16, 120) => gcm_encrypt::<Aes256, U16, U15>(key, plaintext, iv, additional_data)?,
268 (16, 128) => gcm_encrypt::<Aes256, U16, U16>(key, plaintext, iv, additional_data)?,
269
270 (32, 32) => {
272 let mut ciphertext =
273 gcm_encrypt::<Aes256, U32, U12>(key, plaintext, iv, additional_data)?;
274 ciphertext.truncate(ciphertext.len() - 8);
275 ciphertext
276 },
277 (32, 64) => {
278 let mut ciphertext =
279 gcm_encrypt::<Aes256, U32, U12>(key, plaintext, iv, additional_data)?;
280 ciphertext.truncate(ciphertext.len() - 4);
281 ciphertext
282 },
283 (32, 96) => gcm_encrypt::<Aes256, U32, U12>(key, plaintext, iv, additional_data)?,
284 (32, 104) => gcm_encrypt::<Aes256, U32, U13>(key, plaintext, iv, additional_data)?,
285 (32, 112) => gcm_encrypt::<Aes256, U32, U14>(key, plaintext, iv, additional_data)?,
286 (32, 120) => gcm_encrypt::<Aes256, U32, U15>(key, plaintext, iv, additional_data)?,
287 (32, 128) => gcm_encrypt::<Aes256, U32, U16>(key, plaintext, iv, additional_data)?,
288 _ => {
289 return Err(Error::Operation(Some(format!(
290 "Unsupported iv size ({}-bit) and/or tag length ({}-bit)",
291 iv.len() * 8,
292 tag_length
293 ))));
294 },
295 },
296 _ => {
297 return Err(Error::Operation(Some(
298 "The key handle is not representing an AES key".to_string(),
299 )));
300 },
301 };
302
303 Ok(ciphertext)
305}
306
307fn gcm_encrypt<Aes, NonceSize, TagSize>(
309 key: &Key<Aes>,
310 plaintext: &[u8],
311 iv: &[u8],
312 additional_data: &[u8],
313) -> Result<Vec<u8>, Error>
314where
315 Aes: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit,
316 NonceSize: ArrayLength<u8>,
317 TagSize: aes_gcm::TagSize,
318{
319 let mut ciphertext = plaintext.to_vec();
320
321 let mut cipher = AesGcm::<Aes, NonceSize, TagSize>::new(key);
322 cipher
323 .encrypt_in_place(iv.into(), additional_data, &mut ciphertext)
324 .map_err(|_| {
325 Error::Operation(Some(
326 "AES-GCM failed to perform the Authenticated Encryption Function".to_string(),
327 ))
328 })?;
329
330 Ok(ciphertext)
331}
332
333pub(crate) fn decrypt(
335 normalized_algorithm: &SubtleAesGcmParams,
336 key: &CryptoKey,
337 ciphertext: &[u8],
338) -> Result<Vec<u8>, Error> {
339 let tag_length = match normalized_algorithm.tag_length {
347 None => 128,
348 Some(tag_length) if matches!(tag_length, 32 | 64 | 96 | 104 | 112 | 120 | 128) => {
349 tag_length
350 },
351 _ => {
352 return Err(Error::Operation(Some(
353 "The tagLength member of normalizedAlgorithm is present, \
354 and not one of 32, 64, 96, 104, 112, 120 or 128"
355 .to_string(),
356 )));
357 },
358 };
359
360 if ciphertext.len() * 8 < tag_length as usize {
363 return Err(Error::Operation(Some(
364 "The ciphertext is shorter than the tag".into(),
365 )));
366 }
367
368 if normalized_algorithm.iv.len() > u64::MAX as usize {
371 return Err(Error::Operation(Some(
372 "The iv member of normalizedAlgorithm is too long".into(),
373 )));
374 }
375
376 if normalized_algorithm
379 .additional_data
380 .as_ref()
381 .is_some_and(|data| data.len() > u64::MAX as usize)
382 {
383 return Err(Error::Operation(Some(
384 "The additional authentication data is too long".into(),
385 )));
386 }
387
388 let additional_data = normalized_algorithm
396 .additional_data
397 .as_deref()
398 .unwrap_or_default();
399
400 let iv = normalized_algorithm.iv.as_slice();
418 let plaintext = match key.handle() {
419 Handle::Aes128Key(key) => match (iv.len(), tag_length) {
420 (12, 96) => gcm_decrypt::<Aes128, U12, U12>(key, ciphertext, iv, additional_data)?,
422 (12, 104) => gcm_decrypt::<Aes128, U12, U13>(key, ciphertext, iv, additional_data)?,
423 (12, 112) => gcm_decrypt::<Aes128, U12, U14>(key, ciphertext, iv, additional_data)?,
424 (12, 120) => gcm_decrypt::<Aes128, U12, U15>(key, ciphertext, iv, additional_data)?,
425 (12, 128) => gcm_decrypt::<Aes128, U12, U16>(key, ciphertext, iv, additional_data)?,
426
427 (16, 96) => gcm_decrypt::<Aes128, U16, U12>(key, ciphertext, iv, additional_data)?,
429 (16, 104) => gcm_decrypt::<Aes128, U16, U13>(key, ciphertext, iv, additional_data)?,
430 (16, 112) => gcm_decrypt::<Aes128, U16, U14>(key, ciphertext, iv, additional_data)?,
431 (16, 120) => gcm_decrypt::<Aes128, U16, U15>(key, ciphertext, iv, additional_data)?,
432 (16, 128) => gcm_decrypt::<Aes128, U16, U16>(key, ciphertext, iv, additional_data)?,
433
434 (32, 96) => gcm_decrypt::<Aes128, U32, U12>(key, ciphertext, iv, additional_data)?,
436 (32, 104) => gcm_decrypt::<Aes128, U32, U13>(key, ciphertext, iv, additional_data)?,
437 (32, 112) => gcm_decrypt::<Aes128, U32, U14>(key, ciphertext, iv, additional_data)?,
438 (32, 120) => gcm_decrypt::<Aes128, U32, U15>(key, ciphertext, iv, additional_data)?,
439 (32, 128) => gcm_decrypt::<Aes128, U32, U16>(key, ciphertext, iv, additional_data)?,
440
441 _ => {
442 return Err(Error::Operation(Some(format!(
443 "Unsupported iv size ({}-bit) and/or tag length ({}-bit)",
444 iv.len() * 8,
445 tag_length
446 ))));
447 },
448 },
449 Handle::Aes192Key(key) => match (iv.len(), tag_length) {
450 (12, 96) => gcm_decrypt::<Aes192, U12, U12>(key, ciphertext, iv, additional_data)?,
452 (12, 104) => gcm_decrypt::<Aes192, U12, U13>(key, ciphertext, iv, additional_data)?,
453 (12, 112) => gcm_decrypt::<Aes192, U12, U14>(key, ciphertext, iv, additional_data)?,
454 (12, 120) => gcm_decrypt::<Aes192, U12, U15>(key, ciphertext, iv, additional_data)?,
455 (12, 128) => gcm_decrypt::<Aes192, U12, U16>(key, ciphertext, iv, additional_data)?,
456
457 (16, 96) => gcm_decrypt::<Aes192, U16, U12>(key, ciphertext, iv, additional_data)?,
459 (16, 104) => gcm_decrypt::<Aes192, U16, U13>(key, ciphertext, iv, additional_data)?,
460 (16, 112) => gcm_decrypt::<Aes192, U16, U14>(key, ciphertext, iv, additional_data)?,
461 (16, 120) => gcm_decrypt::<Aes192, U16, U15>(key, ciphertext, iv, additional_data)?,
462 (16, 128) => gcm_decrypt::<Aes192, U16, U16>(key, ciphertext, iv, additional_data)?,
463
464 (32, 96) => gcm_decrypt::<Aes192, U32, U12>(key, ciphertext, iv, additional_data)?,
466 (32, 104) => gcm_decrypt::<Aes192, U32, U13>(key, ciphertext, iv, additional_data)?,
467 (32, 112) => gcm_decrypt::<Aes192, U32, U14>(key, ciphertext, iv, additional_data)?,
468 (32, 120) => gcm_decrypt::<Aes192, U32, U15>(key, ciphertext, iv, additional_data)?,
469 (32, 128) => gcm_decrypt::<Aes192, U32, U16>(key, ciphertext, iv, additional_data)?,
470
471 _ => {
472 return Err(Error::Operation(Some(format!(
473 "Unsupported iv size ({}-bit) and/or tag length ({}-bit)",
474 iv.len() * 8,
475 tag_length
476 ))));
477 },
478 },
479 Handle::Aes256Key(key) => match (iv.len(), tag_length) {
480 (12, 96) => gcm_decrypt::<Aes256, U12, U12>(key, ciphertext, iv, additional_data)?,
482 (12, 104) => gcm_decrypt::<Aes256, U12, U13>(key, ciphertext, iv, additional_data)?,
483 (12, 112) => gcm_decrypt::<Aes256, U12, U14>(key, ciphertext, iv, additional_data)?,
484 (12, 120) => gcm_decrypt::<Aes256, U12, U15>(key, ciphertext, iv, additional_data)?,
485 (12, 128) => gcm_decrypt::<Aes256, U12, U16>(key, ciphertext, iv, additional_data)?,
486
487 (16, 96) => gcm_decrypt::<Aes256, U16, U12>(key, ciphertext, iv, additional_data)?,
489 (16, 104) => gcm_decrypt::<Aes256, U16, U13>(key, ciphertext, iv, additional_data)?,
490 (16, 112) => gcm_decrypt::<Aes256, U16, U14>(key, ciphertext, iv, additional_data)?,
491 (16, 120) => gcm_decrypt::<Aes256, U16, U15>(key, ciphertext, iv, additional_data)?,
492 (16, 128) => gcm_decrypt::<Aes256, U16, U16>(key, ciphertext, iv, additional_data)?,
493
494 (32, 96) => gcm_decrypt::<Aes256, U32, U12>(key, ciphertext, iv, additional_data)?,
496 (32, 104) => gcm_decrypt::<Aes256, U32, U13>(key, ciphertext, iv, additional_data)?,
497 (32, 112) => gcm_decrypt::<Aes256, U32, U14>(key, ciphertext, iv, additional_data)?,
498 (32, 120) => gcm_decrypt::<Aes256, U32, U15>(key, ciphertext, iv, additional_data)?,
499 (32, 128) => gcm_decrypt::<Aes256, U32, U16>(key, ciphertext, iv, additional_data)?,
500
501 _ => {
502 return Err(Error::Operation(Some(format!(
503 "Unsupported iv size ({}-bit) and/or tag length ({}-bit)",
504 iv.len() * 8,
505 tag_length
506 ))));
507 },
508 },
509 _ => {
510 return Err(Error::Operation(Some(
511 "The key handle is not representing an AES key".to_string(),
512 )));
513 },
514 };
515
516 Ok(plaintext)
518}
519
520fn gcm_decrypt<Aes, NonceSize, TagSize>(
522 key: &Key<Aes>,
523 ciphertext: &[u8],
524 iv: &[u8],
525 additional_data: &[u8],
526) -> Result<Vec<u8>, Error>
527where
528 Aes: BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt + KeyInit,
529 NonceSize: ArrayLength<u8>,
530 TagSize: aes_gcm::TagSize,
531{
532 let mut plaintext = ciphertext.to_vec();
533
534 let mut cipher = AesGcm::<Aes, NonceSize, TagSize>::new(key);
535 cipher
536 .decrypt_in_place(iv.into(), additional_data, &mut plaintext)
537 .map_err(|_| {
538 Error::Operation(Some(
539 "AES-GCM failed to perform the Authenticated Decryption Function".to_string(),
540 ))
541 })?;
542
543 Ok(plaintext)
544}
545
546pub(crate) fn generate_key(
548 global: &GlobalScope,
549 normalized_algorithm: &SubtleAesKeyGenParams,
550 extractable: bool,
551 usages: Vec<KeyUsage>,
552 can_gc: CanGc,
553) -> Result<DomRoot<CryptoKey>, Error> {
554 aes_common::generate_key(
555 AesAlgorithm::AesGcm,
556 global,
557 normalized_algorithm,
558 extractable,
559 usages,
560 can_gc,
561 )
562}
563
564pub(crate) fn import_key(
566 global: &GlobalScope,
567 format: KeyFormat,
568 key_data: &[u8],
569 extractable: bool,
570 usages: Vec<KeyUsage>,
571 can_gc: CanGc,
572) -> Result<DomRoot<CryptoKey>, Error> {
573 if usages.iter().any(|usage| {
578 !matches!(
579 usage,
580 KeyUsage::Encrypt | KeyUsage::Decrypt | KeyUsage::WrapKey | KeyUsage::UnwrapKey
581 )
582 }) {
583 return Err(Error::Syntax(Some(
584 "Usages contains an entry which is not one of \"encrypt\", \"decrypt\", \"wrapKey\" \
585 or \"unwrapKey\""
586 .to_string(),
587 )));
588 }
589
590 let data = aes_common::import_key_from_key_data(
592 AesAlgorithm::AesGcm,
593 format,
594 key_data,
595 extractable,
596 &usages,
597 )?;
598
599 let handle = match data.len() {
605 16 => Handle::Aes128Key(Key::<Aes128>::clone_from_slice(&data)),
606 24 => Handle::Aes192Key(Key::<Aes192>::clone_from_slice(&data)),
607 32 => Handle::Aes256Key(Key::<Aes256>::clone_from_slice(&data)),
608 _ => {
609 return Err(Error::Data(Some(
610 "The length in bits of data is not 128, 192 or 256".to_string(),
611 )));
612 },
613 };
614 let algorithm = SubtleAesKeyAlgorithm {
615 name: ALG_AES_GCM.to_string(),
616 length: data.len() as u16 * 8,
617 };
618 let key = CryptoKey::new(
619 global,
620 KeyType::Secret,
621 extractable,
622 KeyAlgorithmAndDerivatives::AesKeyAlgorithm(algorithm),
623 usages,
624 handle,
625 can_gc,
626 );
627
628 Ok(key)
630}
631
632pub(crate) fn export_key(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
634 aes_common::export_key(AesAlgorithm::AesGcm, format, key)
635}
636
637pub(crate) fn get_key_length(
639 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
640) -> Result<Option<u32>, Error> {
641 aes_common::get_key_length(normalized_derived_key_algorithm)
642}