script_webcrypto/subtlecrypto/
aes_kw_operation.rs1use aes_kw::{KeyInit, KwAes128, KwAes192, KwAes256};
6use js::context::JSContext;
7use script_bindings::codegen::GenericBindings::CryptoKeyBinding::KeyUsage;
8use script_bindings::codegen::GenericBindings::SubtleCryptoBinding::KeyFormat;
9use script_bindings::error::Error;
10use script_bindings::root::DomRoot;
11use zeroize::Zeroizing;
12
13use crate::cryptokey::{CryptoKey, Handle};
14use crate::subtlecrypto::aes_common::AesAlgorithm;
15use crate::subtlecrypto::{AesDerivedKeyParams, AesKeyGenParams, ExportedKey, aes_common};
16use crate::traits::Equivalence;
17
18pub(crate) fn wrap_key<D: Equivalence>(
20 key: &CryptoKey<D>,
21 plaintext: &[u8],
22) -> Result<Vec<u8>, Error> {
23 if !plaintext.len().is_multiple_of(8) {
25 return Err(Error::Operation(Some(
26 "The plaintext bit-length is not a multiple of 64".into(),
27 )));
28 }
29
30 let mut buffer = vec![0u8; plaintext.len() + 8];
35 let ciphertext = match key.handle() {
36 Handle::Aes128Key(key) => {
37 let key_wrapper = KwAes128::new(key);
38 key_wrapper.wrap_key(plaintext, &mut buffer)
39 },
40 Handle::Aes192Key(key) => {
41 let key_wrapper = KwAes192::new(key);
42 key_wrapper.wrap_key(plaintext, &mut buffer)
43 },
44 Handle::Aes256Key(key) => {
45 let key_wrapper = KwAes256::new(key);
46 key_wrapper.wrap_key(plaintext, &mut buffer)
47 },
48 _ => {
49 return Err(Error::Operation(Some(
50 "The key handle is not representing an AES key".to_string(),
51 )));
52 },
53 }
54 .map_err(|_| {
55 Error::Operation(Some(
56 "AES-KW failed to perform the Key Wrap operation".into(),
57 ))
58 })?;
59
60 Ok(ciphertext.to_vec())
62}
63
64pub(crate) fn unwrap_key<D: Equivalence>(
66 key: &CryptoKey<D>,
67 ciphertext: &[u8],
68) -> Result<Vec<u8>, Error> {
69 let mut buffer = Zeroizing::new(vec![0u8; ciphertext.len()]);
74 let plaintext = match key.handle() {
75 Handle::Aes128Key(key) => {
76 let key_unwrapper = KwAes128::new(key);
77 key_unwrapper.unwrap_key(ciphertext, &mut buffer)
78 },
79 Handle::Aes192Key(key) => {
80 let key_unwrapper = KwAes192::new(key);
81 key_unwrapper.unwrap_key(ciphertext, &mut buffer)
82 },
83 Handle::Aes256Key(key) => {
84 let key_unwrapper = KwAes256::new(key);
85 key_unwrapper.unwrap_key(ciphertext, &mut buffer)
86 },
87 _ => {
88 return Err(Error::Operation(Some(
89 "The key handle is not representing an AES key".to_string(),
90 )));
91 },
92 }
93 .map_err(|_| {
94 Error::Operation(Some(
95 "AES-KW failed to perform the Key Unwrap operation".into(),
96 ))
97 })?;
98
99 Ok(plaintext.to_vec())
101}
102
103pub(crate) fn generate_key<D: Equivalence>(
105 cx: &mut JSContext,
106 global: &D::GlobalScope,
107 normalized_algorithm: &AesKeyGenParams,
108 extractable: bool,
109 usages: Vec<KeyUsage>,
110) -> Result<DomRoot<CryptoKey<D>>, Error> {
111 aes_common::generate_key(
112 cx,
113 global,
114 AesAlgorithm::AesKw,
115 normalized_algorithm,
116 extractable,
117 usages,
118 )
119}
120
121pub(crate) fn import_key<D: Equivalence>(
123 cx: &mut JSContext,
124 global: &D::GlobalScope,
125 format: KeyFormat,
126 key_data: &[u8],
127 extractable: bool,
128 usages: Vec<KeyUsage>,
129) -> Result<DomRoot<CryptoKey<D>>, Error> {
130 aes_common::import_key(
131 cx,
132 global,
133 AesAlgorithm::AesKw,
134 format,
135 key_data,
136 extractable,
137 usages,
138 )
139}
140
141pub(crate) fn export_key<D: Equivalence>(
143 format: KeyFormat,
144 key: &CryptoKey<D>,
145) -> Result<ExportedKey, Error> {
146 aes_common::export_key(AesAlgorithm::AesKw, format, key)
147}
148
149pub(crate) fn get_key_length(
151 normalized_derived_key_algorithm: &AesDerivedKeyParams,
152) -> Result<Option<u32>, Error> {
153 aes_common::get_key_length(normalized_derived_key_algorithm)
154}