1use aes::cipher::block_padding::Pkcs7;
6use aes::cipher::generic_array::GenericArray;
7use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit, StreamCipher};
8use aes::{Aes128, Aes192, Aes256};
9use aes_gcm::{AeadInPlace, AesGcm, KeyInit};
10use aes_kw::{KekAes128, KekAes192, KekAes256};
11use base64::prelude::*;
12use cipher::consts::{U12, U16, U32};
13use servo_rand::{RngCore, ServoRng};
14
15use crate::dom::bindings::cell::DomRefCell;
16use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{
17 CryptoKeyMethods, KeyType, KeyUsage,
18};
19use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::{JsonWebKey, KeyFormat};
20use crate::dom::bindings::error::Error;
21use crate::dom::bindings::root::DomRoot;
22use crate::dom::bindings::str::DOMString;
23use crate::dom::cryptokey::{CryptoKey, Handle};
24use crate::dom::globalscope::GlobalScope;
25use crate::dom::subtlecrypto::{
26 ALG_AES_CBC, ALG_AES_CTR, ALG_AES_GCM, ALG_AES_KW, ExportedKey, JsonWebKeyExt,
27 KeyAlgorithmAndDerivatives, SubtleAesCbcParams, SubtleAesCtrParams, SubtleAesDerivedKeyParams,
28 SubtleAesGcmParams, SubtleAesKeyAlgorithm, SubtleAesKeyGenParams,
29};
30use crate::script_runtime::CanGc;
31
32type Aes128CbcEnc = cbc::Encryptor<Aes128>;
33type Aes128CbcDec = cbc::Decryptor<Aes128>;
34type Aes192CbcEnc = cbc::Encryptor<Aes192>;
35type Aes192CbcDec = cbc::Decryptor<Aes192>;
36type Aes256CbcEnc = cbc::Encryptor<Aes256>;
37type Aes256CbcDec = cbc::Decryptor<Aes256>;
38type Aes128Ctr = ctr::Ctr64BE<Aes128>;
39type Aes192Ctr = ctr::Ctr64BE<Aes192>;
40type Aes256Ctr = ctr::Ctr64BE<Aes256>;
41
42type Aes128Gcm96Iv = AesGcm<Aes128, U12>;
43type Aes128Gcm128Iv = AesGcm<Aes128, U16>;
44type Aes192Gcm96Iv = AesGcm<Aes192, U12>;
45type Aes256Gcm96Iv = AesGcm<Aes256, U12>;
46type Aes128Gcm256Iv = AesGcm<Aes128, U32>;
47type Aes192Gcm256Iv = AesGcm<Aes192, U32>;
48type Aes256Gcm256Iv = AesGcm<Aes256, U32>;
49
50pub(crate) fn encrypt_aes_ctr(
52 normalized_algorithm: &SubtleAesCtrParams,
53 key: &CryptoKey,
54 plaintext: &[u8],
55) -> Result<Vec<u8>, Error> {
56 if normalized_algorithm.counter.len() != 16 ||
61 normalized_algorithm.length == 0 ||
62 normalized_algorithm.length > 128
63 {
64 return Err(Error::Operation);
65 }
66
67 let mut ciphertext = Vec::from(plaintext);
73 let counter = GenericArray::from_slice(&normalized_algorithm.counter);
74
75 match key.handle() {
76 Handle::Aes128(data) => {
77 let key_data = GenericArray::from_slice(data);
78 Aes128Ctr::new(key_data, counter).apply_keystream(&mut ciphertext)
79 },
80 Handle::Aes192(data) => {
81 let key_data = GenericArray::from_slice(data);
82 Aes192Ctr::new(key_data, counter).apply_keystream(&mut ciphertext)
83 },
84 Handle::Aes256(data) => {
85 let key_data = GenericArray::from_slice(data);
86 Aes256Ctr::new(key_data, counter).apply_keystream(&mut ciphertext)
87 },
88 _ => return Err(Error::Data),
89 };
90
91 Ok(ciphertext)
93}
94
95pub(crate) fn decrypt_aes_ctr(
97 normalized_algorithm: &SubtleAesCtrParams,
98 key: &CryptoKey,
99 ciphertext: &[u8],
100) -> Result<Vec<u8>, Error> {
101 encrypt_aes_ctr(normalized_algorithm, key, ciphertext)
103}
104
105pub(crate) fn generate_key_aes_ctr(
107 global: &GlobalScope,
108 normalized_algorithm: &SubtleAesKeyGenParams,
109 extractable: bool,
110 usages: Vec<KeyUsage>,
111 rng: &DomRefCell<ServoRng>,
112 can_gc: CanGc,
113) -> Result<DomRoot<CryptoKey>, Error> {
114 generate_key_aes(
115 global,
116 normalized_algorithm,
117 extractable,
118 usages,
119 rng,
120 ALG_AES_CTR,
121 &[
122 KeyUsage::Encrypt,
123 KeyUsage::Decrypt,
124 KeyUsage::WrapKey,
125 KeyUsage::UnwrapKey,
126 ],
127 can_gc,
128 )
129}
130
131pub(crate) fn import_key_aes_ctr(
133 global: &GlobalScope,
134 format: KeyFormat,
135 key_data: &[u8],
136 extractable: bool,
137 usages: Vec<KeyUsage>,
138 can_gc: CanGc,
139) -> Result<DomRoot<CryptoKey>, Error> {
140 import_key_aes(
141 global,
142 format,
143 key_data,
144 extractable,
145 usages,
146 ALG_AES_CTR,
147 can_gc,
148 )
149}
150
151pub(crate) fn export_key_aes_ctr(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
153 export_key_aes(format, key)
154}
155
156pub(crate) fn get_key_length_aes_ctr(
158 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
159) -> Result<Option<u32>, Error> {
160 get_key_length_aes(normalized_derived_key_algorithm)
161}
162
163pub(crate) fn encrypt_aes_cbc(
165 normalized_algorithm: &SubtleAesCbcParams,
166 key: &CryptoKey,
167 plaintext: &[u8],
168) -> Result<Vec<u8>, Error> {
169 if normalized_algorithm.iv.len() != 16 {
172 return Err(Error::Operation);
173 }
174
175 let plaintext = Vec::from(plaintext);
181 let iv = GenericArray::from_slice(&normalized_algorithm.iv);
182 let ciphertext = match key.handle() {
183 Handle::Aes128(data) => {
184 let key_data = GenericArray::from_slice(data);
185 Aes128CbcEnc::new(key_data, iv).encrypt_padded_vec_mut::<Pkcs7>(&plaintext)
186 },
187 Handle::Aes192(data) => {
188 let key_data = GenericArray::from_slice(data);
189 Aes192CbcEnc::new(key_data, iv).encrypt_padded_vec_mut::<Pkcs7>(&plaintext)
190 },
191 Handle::Aes256(data) => {
192 let key_data = GenericArray::from_slice(data);
193 Aes256CbcEnc::new(key_data, iv).encrypt_padded_vec_mut::<Pkcs7>(&plaintext)
194 },
195 _ => return Err(Error::Data),
196 };
197
198 Ok(ciphertext)
200}
201
202pub(crate) fn decrypt_aes_cbc(
204 normalized_algorithm: &SubtleAesCbcParams,
205 key: &CryptoKey,
206 ciphertext: &[u8],
207) -> Result<Vec<u8>, Error> {
208 if normalized_algorithm.iv.len() != 16 {
211 return Err(Error::Operation);
212 }
213
214 if ciphertext.is_empty() || ciphertext.len() % 16 != 0 {
217 return Err(Error::Operation);
218 }
219
220 let mut ciphertext = Vec::from(ciphertext);
228 let iv = GenericArray::from_slice(&normalized_algorithm.iv);
229 let plaintext = match key.handle() {
230 Handle::Aes128(data) => {
231 let key_data = GenericArray::from_slice(data);
232 Aes128CbcDec::new(key_data, iv)
233 .decrypt_padded_mut::<Pkcs7>(ciphertext.as_mut_slice())
234 .map_err(|_| Error::Operation)?
235 },
236 Handle::Aes192(data) => {
237 let key_data = GenericArray::from_slice(data);
238 Aes192CbcDec::new(key_data, iv)
239 .decrypt_padded_mut::<Pkcs7>(ciphertext.as_mut_slice())
240 .map_err(|_| Error::Operation)?
241 },
242 Handle::Aes256(data) => {
243 let key_data = GenericArray::from_slice(data);
244 Aes256CbcDec::new(key_data, iv)
245 .decrypt_padded_mut::<Pkcs7>(ciphertext.as_mut_slice())
246 .map_err(|_| Error::Operation)?
247 },
248 _ => return Err(Error::Data),
249 };
250
251 Ok(plaintext.to_vec())
253}
254
255pub(crate) fn generate_key_aes_cbc(
257 global: &GlobalScope,
258 normalized_algorithm: &SubtleAesKeyGenParams,
259 extractable: bool,
260 usages: Vec<KeyUsage>,
261 rng: &DomRefCell<ServoRng>,
262 can_gc: CanGc,
263) -> Result<DomRoot<CryptoKey>, Error> {
264 generate_key_aes(
265 global,
266 normalized_algorithm,
267 extractable,
268 usages,
269 rng,
270 ALG_AES_CBC,
271 &[
272 KeyUsage::Encrypt,
273 KeyUsage::Decrypt,
274 KeyUsage::WrapKey,
275 KeyUsage::UnwrapKey,
276 ],
277 can_gc,
278 )
279}
280
281pub(crate) fn import_key_aes_cbc(
283 global: &GlobalScope,
284 format: KeyFormat,
285 key_data: &[u8],
286 extractable: bool,
287 usages: Vec<KeyUsage>,
288 can_gc: CanGc,
289) -> Result<DomRoot<CryptoKey>, Error> {
290 import_key_aes(
291 global,
292 format,
293 key_data,
294 extractable,
295 usages,
296 ALG_AES_CBC,
297 can_gc,
298 )
299}
300
301pub(crate) fn export_key_aes_cbc(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
303 export_key_aes(format, key)
304}
305
306pub(crate) fn get_key_length_aes_cbc(
308 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
309) -> Result<Option<u32>, Error> {
310 get_key_length_aes(normalized_derived_key_algorithm)
311}
312
313pub(crate) fn encrypt_aes_gcm(
315 normalized_algorithm: &SubtleAesGcmParams,
316 key: &CryptoKey,
317 plaintext: &[u8],
318) -> Result<Vec<u8>, Error> {
319 if plaintext.len() as u64 > (2 << 39) - 256 {
321 return Err(Error::Operation);
322 }
323
324 if normalized_algorithm
331 .additional_data
332 .as_ref()
333 .is_some_and(|data| data.len() > u64::MAX as usize)
334 {
335 return Err(Error::Operation);
336 }
337
338 let tag_length = match normalized_algorithm.tag_length {
346 None => 128,
347 Some(length) if matches!(length, 32 | 64 | 96 | 104 | 112 | 120 | 128) => length,
348 _ => {
349 return Err(Error::Operation);
350 },
351 };
352
353 let additional_data = normalized_algorithm
356 .additional_data
357 .as_deref()
358 .unwrap_or_default();
359
360 let key_length = key.handle().as_bytes().len();
366 let iv_length = normalized_algorithm.iv.len();
367 let mut ciphertext = plaintext.to_vec();
368 let key_bytes = key.handle().as_bytes();
369 let tag = match (key_length, iv_length) {
370 (16, 12) => {
371 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
372 <Aes128Gcm96Iv>::new_from_slice(key_bytes)
373 .expect("key length did not match")
374 .encrypt_in_place_detached(nonce, additional_data, &mut ciphertext)
375 },
376 (16, 16) => {
377 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
378 <Aes128Gcm128Iv>::new_from_slice(key_bytes)
379 .expect("key length did not match")
380 .encrypt_in_place_detached(nonce, additional_data, &mut ciphertext)
381 },
382 (24, 12) => {
383 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
384 <Aes192Gcm96Iv>::new_from_slice(key_bytes)
385 .expect("key length did not match")
386 .encrypt_in_place_detached(nonce, additional_data, &mut ciphertext)
387 },
388 (32, 12) => {
389 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
390 <Aes256Gcm96Iv>::new_from_slice(key_bytes)
391 .expect("key length did not match")
392 .encrypt_in_place_detached(nonce, additional_data, &mut ciphertext)
393 },
394 (16, 32) => {
395 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
396 <Aes128Gcm256Iv>::new_from_slice(key_bytes)
397 .expect("key length did not match")
398 .encrypt_in_place_detached(nonce, additional_data, &mut ciphertext)
399 },
400 (24, 32) => {
401 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
402 <Aes192Gcm256Iv>::new_from_slice(key_bytes)
403 .expect("key length did not match")
404 .encrypt_in_place_detached(nonce, additional_data, &mut ciphertext)
405 },
406 (32, 32) => {
407 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
408 <Aes256Gcm256Iv>::new_from_slice(key_bytes)
409 .expect("key length did not match")
410 .encrypt_in_place_detached(nonce, additional_data, &mut ciphertext)
411 },
412 _ => {
413 log::warn!(
414 "Missing AES-GCM encryption implementation with {key_length}-byte key and {iv_length}-byte IV"
415 );
416 return Err(Error::NotSupported);
417 },
418 };
419
420 ciphertext.extend_from_slice(&tag.unwrap()[..tag_length as usize / 8]);
422
423 Ok(ciphertext)
425}
426
427pub(crate) fn decrypt_aes_gcm(
429 normalized_algorithm: &SubtleAesGcmParams,
430 key: &CryptoKey,
431 ciphertext: &[u8],
432) -> Result<Vec<u8>, Error> {
433 let tag_length = match normalized_algorithm.tag_length {
441 None => 128,
442 Some(length) if matches!(length, 32 | 64 | 96 | 104 | 112 | 120 | 128) => length as usize,
443 _ => {
444 return Err(Error::Operation);
445 },
446 };
447
448 if ciphertext.len() * 8 < tag_length {
451 return Err(Error::Operation);
452 }
453
454 let additional_data = normalized_algorithm
470 .additional_data
471 .as_deref()
472 .unwrap_or_default();
473
474 let mut plaintext = ciphertext.to_vec();
484 let key_length = key.handle().as_bytes().len();
485 let iv_length = normalized_algorithm.iv.len();
486 let key_bytes = key.handle().as_bytes();
487 let result = match (key_length, iv_length) {
488 (16, 12) => {
489 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
490 <Aes128Gcm96Iv>::new_from_slice(key_bytes)
491 .expect("key length did not match")
492 .decrypt_in_place(nonce, additional_data, &mut plaintext)
493 },
494 (16, 16) => {
495 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
496 <Aes128Gcm128Iv>::new_from_slice(key_bytes)
497 .expect("key length did not match")
498 .decrypt_in_place(nonce, additional_data, &mut plaintext)
499 },
500 (24, 12) => {
501 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
502 <Aes192Gcm96Iv>::new_from_slice(key_bytes)
503 .expect("key length did not match")
504 .decrypt_in_place(nonce, additional_data, &mut plaintext)
505 },
506 (32, 12) => {
507 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
508 <Aes256Gcm96Iv>::new_from_slice(key_bytes)
509 .expect("key length did not match")
510 .decrypt_in_place(nonce, additional_data, &mut plaintext)
511 },
512 (16, 32) => {
513 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
514 <Aes128Gcm256Iv>::new_from_slice(key_bytes)
515 .expect("key length did not match")
516 .decrypt_in_place(nonce, additional_data, &mut plaintext)
517 },
518 (24, 32) => {
519 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
520 <Aes192Gcm256Iv>::new_from_slice(key_bytes)
521 .expect("key length did not match")
522 .decrypt_in_place(nonce, additional_data, &mut plaintext)
523 },
524 (32, 32) => {
525 let nonce = GenericArray::from_slice(&normalized_algorithm.iv);
526 <Aes256Gcm256Iv>::new_from_slice(key_bytes)
527 .expect("key length did not match")
528 .decrypt_in_place(nonce, additional_data, &mut plaintext)
529 },
530 _ => {
531 log::warn!(
532 "Missing AES-GCM decryption implementation with {key_length}-byte key and {iv_length}-byte IV"
533 );
534 return Err(Error::NotSupported);
535 },
536 };
537 if result.is_err() {
538 return Err(Error::Operation);
539 }
540
541 Ok(plaintext)
542}
543
544pub(crate) fn generate_key_aes_gcm(
546 global: &GlobalScope,
547 normalized_algorithm: &SubtleAesKeyGenParams,
548 extractable: bool,
549 usages: Vec<KeyUsage>,
550 rng: &DomRefCell<ServoRng>,
551 can_gc: CanGc,
552) -> Result<DomRoot<CryptoKey>, Error> {
553 generate_key_aes(
554 global,
555 normalized_algorithm,
556 extractable,
557 usages,
558 rng,
559 ALG_AES_GCM,
560 &[
561 KeyUsage::Encrypt,
562 KeyUsage::Decrypt,
563 KeyUsage::WrapKey,
564 KeyUsage::UnwrapKey,
565 ],
566 can_gc,
567 )
568}
569
570pub(crate) fn import_key_aes_gcm(
572 global: &GlobalScope,
573 format: KeyFormat,
574 key_data: &[u8],
575 extractable: bool,
576 usages: Vec<KeyUsage>,
577 can_gc: CanGc,
578) -> Result<DomRoot<CryptoKey>, Error> {
579 import_key_aes(
580 global,
581 format,
582 key_data,
583 extractable,
584 usages,
585 ALG_AES_GCM,
586 can_gc,
587 )
588}
589
590pub(crate) fn export_key_aes_gcm(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
592 export_key_aes(format, key)
593}
594
595pub(crate) fn get_key_length_aes_gcm(
597 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
598) -> Result<Option<u32>, Error> {
599 get_key_length_aes(normalized_derived_key_algorithm)
600}
601
602pub(crate) fn wrap_key_aes_kw(key: &CryptoKey, plaintext: &[u8]) -> Result<Vec<u8>, Error> {
604 if plaintext.len() % 8 != 0 {
606 return Err(Error::Operation);
607 }
608
609 let key_data = key.handle().as_bytes();
613 let ciphertext = match key_data.len() {
614 16 => {
615 let key_array = GenericArray::from_slice(key_data);
616 let kek = KekAes128::new(key_array);
617 match kek.wrap_vec(plaintext) {
618 Ok(key) => key,
619 Err(_) => return Err(Error::Operation),
620 }
621 },
622 24 => {
623 let key_array = GenericArray::from_slice(key_data);
624 let kek = KekAes192::new(key_array);
625 match kek.wrap_vec(plaintext) {
626 Ok(key) => key,
627 Err(_) => return Err(Error::Operation),
628 }
629 },
630 32 => {
631 let key_array = GenericArray::from_slice(key_data);
632 let kek = KekAes256::new(key_array);
633 match kek.wrap_vec(plaintext) {
634 Ok(key) => key,
635 Err(_) => return Err(Error::Operation),
636 }
637 },
638 _ => return Err(Error::Operation),
639 };
640
641 Ok(ciphertext)
643}
644
645pub(crate) fn unwrap_key_aes_kw(key: &CryptoKey, ciphertext: &[u8]) -> Result<Vec<u8>, Error> {
647 let key_data = key.handle().as_bytes();
652 let plaintext = match key_data.len() {
653 16 => {
654 let key_array = GenericArray::from_slice(key_data);
655 let kek = KekAes128::new(key_array);
656 match kek.unwrap_vec(ciphertext) {
657 Ok(key) => key,
658 Err(_) => return Err(Error::Operation),
659 }
660 },
661 24 => {
662 let key_array = GenericArray::from_slice(key_data);
663 let kek = KekAes192::new(key_array);
664 match kek.unwrap_vec(ciphertext) {
665 Ok(key) => key,
666 Err(_) => return Err(Error::Operation),
667 }
668 },
669 32 => {
670 let key_array = GenericArray::from_slice(key_data);
671 let kek = KekAes256::new(key_array);
672 match kek.unwrap_vec(ciphertext) {
673 Ok(key) => key,
674 Err(_) => return Err(Error::Operation),
675 }
676 },
677 _ => return Err(Error::Operation),
678 };
679
680 Ok(plaintext)
682}
683
684pub(crate) fn generate_key_aes_kw(
686 global: &GlobalScope,
687 normalized_algorithm: &SubtleAesKeyGenParams,
688 extractable: bool,
689 usages: Vec<KeyUsage>,
690 rng: &DomRefCell<ServoRng>,
691 can_gc: CanGc,
692) -> Result<DomRoot<CryptoKey>, Error> {
693 generate_key_aes(
694 global,
695 normalized_algorithm,
696 extractable,
697 usages,
698 rng,
699 ALG_AES_KW,
700 &[KeyUsage::WrapKey, KeyUsage::UnwrapKey],
701 can_gc,
702 )
703}
704
705pub(crate) fn import_key_aes_kw(
707 global: &GlobalScope,
708 format: KeyFormat,
709 key_data: &[u8],
710 extractable: bool,
711 usages: Vec<KeyUsage>,
712 can_gc: CanGc,
713) -> Result<DomRoot<CryptoKey>, Error> {
714 import_key_aes(
715 global,
716 format,
717 key_data,
718 extractable,
719 usages,
720 ALG_AES_KW,
721 can_gc,
722 )
723}
724
725pub(crate) fn export_key_aes_kw(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
727 export_key_aes(format, key)
728}
729
730pub(crate) fn get_key_length_aes_kw(
732 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
733) -> Result<Option<u32>, Error> {
734 get_key_length_aes(normalized_derived_key_algorithm)
735}
736
737#[allow(clippy::too_many_arguments)]
743fn generate_key_aes(
744 global: &GlobalScope,
745 normalized_algorithm: &SubtleAesKeyGenParams,
746 extractable: bool,
747 usages: Vec<KeyUsage>,
748 rng: &DomRefCell<ServoRng>,
749 alg_name: &str,
750 allowed_usages: &[KeyUsage],
751 can_gc: CanGc,
752) -> Result<DomRoot<CryptoKey>, Error> {
753 if usages.iter().any(|usage| !allowed_usages.contains(usage)) {
755 return Err(Error::Syntax(None));
756 }
757
758 if !matches!(normalized_algorithm.length, 128 | 192 | 256) {
761 return Err(Error::Operation);
762 }
763
764 let mut rand = vec![0; normalized_algorithm.length as usize / 8];
767 rng.borrow_mut().fill_bytes(&mut rand);
768 let handle = match normalized_algorithm.length {
769 128 => Handle::Aes128(rand),
770 192 => Handle::Aes192(rand),
771 256 => Handle::Aes256(rand),
772 _ => return Err(Error::Operation),
773 };
774
775 let algorithm = SubtleAesKeyAlgorithm {
779 name: alg_name.to_string(),
780 length: normalized_algorithm.length,
781 };
782
783 let crypto_key = CryptoKey::new(
789 global,
790 KeyType::Secret,
791 extractable,
792 KeyAlgorithmAndDerivatives::AesKeyAlgorithm(algorithm),
793 usages,
794 handle,
795 can_gc,
796 );
797
798 Ok(crypto_key)
800}
801
802fn import_key_aes(
808 global: &GlobalScope,
809 format: KeyFormat,
810 key_data: &[u8],
811 extractable: bool,
812 usages: Vec<KeyUsage>,
813 alg_name: &str,
814 can_gc: CanGc,
815) -> Result<DomRoot<CryptoKey>, Error> {
816 if usages.iter().any(|usage| {
819 !matches!(
820 usage,
821 KeyUsage::Encrypt | KeyUsage::Decrypt | KeyUsage::WrapKey | KeyUsage::UnwrapKey
822 )
823 }) || usages.is_empty()
824 {
825 return Err(Error::Syntax(None));
826 }
827
828 let data;
830 match format {
831 KeyFormat::Raw => {
833 data = key_data.to_vec();
835
836 if !matches!(data.len() * 8, 128 | 192 | 256) {
838 return Err(Error::Data);
839 }
840 },
841 KeyFormat::Jwk => {
843 let jwk = JsonWebKey::parse(GlobalScope::get_cx(), key_data)?;
847
848 if jwk.kty.as_ref().is_none_or(|kty| kty != "oct") {
850 return Err(Error::Data);
851 }
852
853 data = base64::engine::general_purpose::STANDARD_NO_PAD
859 .decode(&*jwk.k.as_ref().ok_or(Error::Data)?.as_bytes())
860 .map_err(|_| Error::Data)?;
861
862 let alg_matching = match alg_name {
865 ALG_AES_CBC => ["A128CBC", "A192CBC", "A256CBC"],
866 ALG_AES_CTR => ["A128CTR", "A192CTR", "A256CTR"],
867 ALG_AES_GCM => ["A128GCM", "A192GCM", "A256GCM"],
868 ALG_AES_KW => ["A128KW", "A192KW", "A256KW"],
869 _ => unreachable!(),
870 };
871
872 match data.len() * 8 {
874 128 => {
876 if jwk.alg.as_ref().is_some_and(|alg| alg != alg_matching[0]) {
882 return Err(Error::Data);
883 }
884 },
885 192 => {
887 if jwk.alg.as_ref().is_some_and(|alg| alg != alg_matching[1]) {
893 return Err(Error::Data);
894 }
895 },
896 256 => {
898 if jwk.alg.as_ref().is_some_and(|alg| alg != alg_matching[2]) {
904 return Err(Error::Data);
905 }
906 },
907 _ => {
909 return Err(Error::Data);
911 },
912 }
913
914 if !usages.is_empty() && jwk.use_.as_ref().is_some_and(|use_| use_ != "enc") {
917 return Err(Error::Data);
918 }
919
920 jwk.check_key_ops(&usages)?;
924
925 if jwk.ext.is_some_and(|ext| !ext) && extractable {
928 return Err(Error::Data);
929 }
930 },
931 _ => {
933 return Err(Error::NotSupported);
935 },
936 };
937
938 let algorithm = SubtleAesKeyAlgorithm {
942 name: alg_name.to_string(),
943 length: (data.len() * 8) as u16,
944 };
945
946 let handle = match data.len() * 8 {
950 128 => Handle::Aes128(data.to_vec()),
951 192 => Handle::Aes192(data.to_vec()),
952 256 => Handle::Aes256(data.to_vec()),
953 _ => {
954 return Err(Error::Data);
955 },
956 };
957 let key = CryptoKey::new(
958 global,
959 KeyType::Secret,
960 extractable,
961 KeyAlgorithmAndDerivatives::AesKeyAlgorithm(algorithm),
962 usages,
963 handle,
964 can_gc,
965 );
966
967 Ok(key)
969}
970
971fn export_key_aes(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
977 let result;
983 match format {
984 KeyFormat::Raw => match key.handle() {
986 Handle::Aes128(key_data) => {
990 result = ExportedKey::Raw(key_data.clone());
991 },
992 Handle::Aes192(key_data) => {
993 result = ExportedKey::Raw(key_data.clone());
994 },
995 Handle::Aes256(key_data) => {
996 result = ExportedKey::Raw(key_data.clone());
997 },
998 _ => unreachable!(),
999 },
1000 KeyFormat::Jwk => {
1002 let k = match key.handle() {
1006 Handle::Aes128(key) => base64::engine::general_purpose::STANDARD_NO_PAD.encode(key),
1007 Handle::Aes192(key) => base64::engine::general_purpose::STANDARD_NO_PAD.encode(key),
1008 Handle::Aes256(key) => base64::engine::general_purpose::STANDARD_NO_PAD.encode(key),
1009 _ => unreachable!(),
1010 };
1011
1012 let alg = match (key.handle(), key.algorithm().name()) {
1031 (Handle::Aes128(_), ALG_AES_CTR) => "A128CTR",
1032 (Handle::Aes192(_), ALG_AES_CTR) => "A192CTR",
1033 (Handle::Aes256(_), ALG_AES_CTR) => "A256CTR",
1034 (Handle::Aes128(_), ALG_AES_CBC) => "A128CBC",
1035 (Handle::Aes192(_), ALG_AES_CBC) => "A192CBC",
1036 (Handle::Aes256(_), ALG_AES_CBC) => "A256CBC",
1037 (Handle::Aes128(_), ALG_AES_GCM) => "A128GCM",
1038 (Handle::Aes192(_), ALG_AES_GCM) => "A192GCM",
1039 (Handle::Aes256(_), ALG_AES_GCM) => "A256GCM",
1040 (Handle::Aes128(_), ALG_AES_KW) => "A128KW",
1041 (Handle::Aes192(_), ALG_AES_KW) => "A192KW",
1042 (Handle::Aes256(_), ALG_AES_KW) => "A256KW",
1043 _ => unreachable!(),
1044 };
1045
1046 let key_ops = key
1048 .usages()
1049 .iter()
1050 .map(|usage| DOMString::from(usage.as_str()))
1051 .collect::<Vec<DOMString>>();
1052
1053 let jwk = JsonWebKey {
1057 kty: Some(DOMString::from("oct")),
1058 k: Some(DOMString::from(k)),
1059 alg: Some(DOMString::from(alg)),
1060 key_ops: Some(key_ops),
1061 ext: Some(key.Extractable()),
1062 ..Default::default()
1063 };
1064
1065 result = ExportedKey::Jwk(Box::new(jwk));
1067 },
1068 _ => {
1070 return Err(Error::NotSupported);
1072 },
1073 };
1074
1075 Ok(result)
1077}
1078
1079pub(crate) fn get_key_length_aes(
1085 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
1086) -> Result<Option<u32>, Error> {
1087 if !matches!(normalized_derived_key_algorithm.length, 128 | 192 | 256) {
1090 return Err(Error::Operation);
1091 }
1092
1093 Ok(Some(normalized_derived_key_algorithm.length as u32))
1095}