script/dom/subtlecrypto/
aes_kw_operation.rs1use aes::cipher::crypto_common::Key;
6use aes::{Aes128, Aes192, Aes256};
7use aes_kw::Kek;
8
9use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{KeyType, KeyUsage};
10use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::KeyFormat;
11use crate::dom::bindings::error::Error;
12use crate::dom::bindings::root::DomRoot;
13use crate::dom::cryptokey::{CryptoKey, Handle};
14use crate::dom::globalscope::GlobalScope;
15use crate::dom::subtlecrypto::aes_common::AesAlgorithm;
16use crate::dom::subtlecrypto::{
17 ALG_AES_KW, ExportedKey, KeyAlgorithmAndDerivatives, SubtleAesDerivedKeyParams,
18 SubtleAesKeyAlgorithm, SubtleAesKeyGenParams, aes_common,
19};
20use crate::script_runtime::CanGc;
21
22pub(crate) fn wrap_key(key: &CryptoKey, plaintext: &[u8]) -> Result<Vec<u8>, Error> {
24 if plaintext.len() % 8 != 0 {
26 return Err(Error::Operation(Some(
27 "The plaintext bit-length is not a multiple of 64".into(),
28 )));
29 }
30
31 let ciphertext = match key.handle() {
35 Handle::Aes128Key(key) => {
36 let kek = Kek::<Aes128>::new(key);
37 kek.wrap_vec(plaintext).map_err(|_| {
38 Error::Operation(Some(
39 "AES-KW failed to perform the Key Wrap operation".to_string(),
40 ))
41 })?
42 },
43 Handle::Aes192Key(key) => {
44 let kek = Kek::<Aes192>::new(key);
45 kek.wrap_vec(plaintext).map_err(|_| {
46 Error::Operation(Some(
47 "AES-KW failed to perform the Key Wrap operation".to_string(),
48 ))
49 })?
50 },
51 Handle::Aes256Key(key) => {
52 let kek = Kek::<Aes256>::new(key);
53 kek.wrap_vec(plaintext).map_err(|_| {
54 Error::Operation(Some(
55 "AES-KW failed to perform the Key Wrap operation".to_string(),
56 ))
57 })?
58 },
59 _ => {
60 return Err(Error::Operation(Some(
61 "The key handle is not representing an AES key".to_string(),
62 )));
63 },
64 };
65
66 Ok(ciphertext)
68}
69
70pub(crate) fn unwrap_key(key: &CryptoKey, ciphertext: &[u8]) -> Result<Vec<u8>, Error> {
72 let plaintext = match key.handle() {
77 Handle::Aes128Key(key) => {
78 let kek = Kek::<Aes128>::new(key);
79 kek.unwrap_vec(ciphertext).map_err(|_| {
80 Error::Operation(Some(
81 "AES-KW failed to perform the Key Unwrap operation".to_string(),
82 ))
83 })?
84 },
85 Handle::Aes192Key(key) => {
86 let kek = Kek::<Aes192>::new(key);
87 kek.unwrap_vec(ciphertext).map_err(|_| {
88 Error::Operation(Some(
89 "AES-KW failed to perform the Key Unwrap operation".to_string(),
90 ))
91 })?
92 },
93 Handle::Aes256Key(key) => {
94 let kek = Kek::<Aes256>::new(key);
95 kek.unwrap_vec(ciphertext).map_err(|_| {
96 Error::Operation(Some(
97 "AES-KW failed to perform the Key Unwrap operation".to_string(),
98 ))
99 })?
100 },
101 _ => {
102 return Err(Error::Operation(Some(
103 "The key handle is not representing an AES key".to_string(),
104 )));
105 },
106 };
107
108 Ok(plaintext)
110}
111
112pub(crate) fn generate_key(
114 global: &GlobalScope,
115 normalized_algorithm: &SubtleAesKeyGenParams,
116 extractable: bool,
117 usages: Vec<KeyUsage>,
118 can_gc: CanGc,
119) -> Result<DomRoot<CryptoKey>, Error> {
120 aes_common::generate_key(
121 AesAlgorithm::AesKw,
122 global,
123 normalized_algorithm,
124 extractable,
125 usages,
126 can_gc,
127 )
128}
129
130pub(crate) fn import_key(
132 global: &GlobalScope,
133 format: KeyFormat,
134 key_data: &[u8],
135 extractable: bool,
136 usages: Vec<KeyUsage>,
137 can_gc: CanGc,
138) -> Result<DomRoot<CryptoKey>, Error> {
139 if usages.iter().any(|usage| {
144 !matches!(
145 usage,
146 KeyUsage::Encrypt | KeyUsage::Decrypt | KeyUsage::WrapKey | KeyUsage::UnwrapKey
147 )
148 }) {
149 return Err(Error::Syntax(Some(
150 "Usages contains an entry which is not one of \"encrypt\", \"decrypt\", \"wrapKey\" \
151 or \"unwrapKey\""
152 .to_string(),
153 )));
154 }
155
156 let data = aes_common::import_key_from_key_data(
158 AesAlgorithm::AesKw,
159 format,
160 key_data,
161 extractable,
162 &usages,
163 )?;
164
165 let handle = match data.len() {
171 16 => Handle::Aes128Key(Key::<Aes128>::clone_from_slice(&data)),
172 24 => Handle::Aes192Key(Key::<Aes192>::clone_from_slice(&data)),
173 32 => Handle::Aes256Key(Key::<Aes256>::clone_from_slice(&data)),
174 _ => {
175 return Err(Error::Data(Some(
176 "The length in bits of data is not 128, 192 or 256".to_string(),
177 )));
178 },
179 };
180 let algorithm = SubtleAesKeyAlgorithm {
181 name: ALG_AES_KW.to_string(),
182 length: data.len() as u16 * 8,
183 };
184 let key = CryptoKey::new(
185 global,
186 KeyType::Secret,
187 extractable,
188 KeyAlgorithmAndDerivatives::AesKeyAlgorithm(algorithm),
189 usages,
190 handle,
191 can_gc,
192 );
193
194 Ok(key)
196}
197
198pub(crate) fn export_key(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
200 aes_common::export_key(AesAlgorithm::AesKw, format, key)
201}
202
203pub(crate) fn get_key_length(
205 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
206) -> Result<Option<u32>, Error> {
207 aes_common::get_key_length(normalized_derived_key_algorithm)
208}