script/dom/webcrypto/subtlecrypto/
aes_ctr_operation.rs1use aes::{Aes128, Aes192, Aes256};
6use ctr::Ctr128BE;
7use ctr::cipher::StreamCipher;
8use ctr::cipher::common::KeyIvInit;
9use js::context::JSContext;
10
11use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::KeyUsage;
12use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::KeyFormat;
13use crate::dom::bindings::error::Error;
14use crate::dom::bindings::root::DomRoot;
15use crate::dom::cryptokey::{CryptoKey, Handle};
16use crate::dom::globalscope::GlobalScope;
17use crate::dom::subtlecrypto::aes_common::AesAlgorithm;
18use crate::dom::subtlecrypto::{
19 ExportedKey, SubtleAesCtrParams, SubtleAesDerivedKeyParams, SubtleAesKeyGenParams, aes_common,
20};
21
22type Ctr<T> = Ctr128BE<T>;
25
26pub(crate) fn encrypt(
28 normalized_algorithm: &SubtleAesCtrParams,
29 key: &CryptoKey,
30 plaintext: &[u8],
31) -> Result<Vec<u8>, Error> {
32 if normalized_algorithm.counter.len() != 16 {
35 return Err(Error::Operation(Some(
36 "The initial counter block length is not 16 bytes".into(),
37 )));
38 }
39
40 if normalized_algorithm.length == 0 {
43 return Err(Error::Operation(Some("The counter length is zero".into())));
44 }
45 if normalized_algorithm.length > 128 {
46 return Err(Error::Operation(Some(
47 "The counter length is greater than 128".into(),
48 )));
49 }
50
51 let iv = normalized_algorithm
57 .counter
58 .as_slice()
59 .try_into()
60 .map_err(|_| Error::Operation(Some("Invalid AES-CTR counter".into())))?;
61 let mut ciphertext = plaintext.to_vec();
62 match key.handle() {
63 Handle::Aes128Key(key) => {
64 let mut cipher = Ctr::<Aes128>::new(key, iv);
65 cipher.apply_keystream(&mut ciphertext);
66 },
67 Handle::Aes192Key(key) => {
68 let mut cipher = Ctr::<Aes192>::new(key, iv);
69 cipher.apply_keystream(&mut ciphertext);
70 },
71 Handle::Aes256Key(key) => {
72 let mut cipher = Ctr::<Aes256>::new(key, iv);
73 cipher.apply_keystream(&mut ciphertext);
74 },
75 _ => {
76 return Err(Error::Operation(Some(
77 "The key handle is not representing an AES key".to_string(),
78 )));
79 },
80 };
81
82 Ok(ciphertext)
84}
85
86pub(crate) fn decrypt(
88 normalized_algorithm: &SubtleAesCtrParams,
89 key: &CryptoKey,
90 ciphertext: &[u8],
91) -> Result<Vec<u8>, Error> {
92 if normalized_algorithm.counter.len() != 16 {
95 return Err(Error::Operation(Some(
96 "The initial counter block length is not 16 bytes".into(),
97 )));
98 }
99
100 if normalized_algorithm.length == 0 {
103 return Err(Error::Operation(Some("The counter length is zero".into())));
104 }
105 if normalized_algorithm.length > 128 {
106 return Err(Error::Operation(Some(
107 "The counter length is greater than 128".into(),
108 )));
109 }
110
111 let iv = normalized_algorithm
117 .counter
118 .as_slice()
119 .try_into()
120 .map_err(|_| Error::Operation(Some("Invalid AES-CTR counter".into())))?;
121 let mut plaintext = ciphertext.to_vec();
122 match key.handle() {
123 Handle::Aes128Key(key) => {
124 let mut cipher = Ctr::<Aes128>::new(key, &iv);
125 cipher.apply_keystream(&mut plaintext);
126 },
127 Handle::Aes192Key(key) => {
128 let mut cipher = Ctr::<Aes192>::new(key, &iv);
129 cipher.apply_keystream(&mut plaintext);
130 },
131 Handle::Aes256Key(key) => {
132 let mut cipher = Ctr::<Aes256>::new(key, &iv);
133 cipher.apply_keystream(&mut plaintext);
134 },
135 _ => {
136 return Err(Error::Operation(Some(
137 "The key handle is not representing an AES key".to_string(),
138 )));
139 },
140 };
141
142 Ok(plaintext)
144}
145
146pub(crate) fn generate_key(
148 cx: &mut JSContext,
149 global: &GlobalScope,
150 normalized_algorithm: &SubtleAesKeyGenParams,
151 extractable: bool,
152 usages: Vec<KeyUsage>,
153) -> Result<DomRoot<CryptoKey>, Error> {
154 aes_common::generate_key(
155 AesAlgorithm::AesCtr,
156 cx,
157 global,
158 normalized_algorithm,
159 extractable,
160 usages,
161 )
162}
163
164pub(crate) fn import_key(
166 cx: &mut JSContext,
167 global: &GlobalScope,
168 format: KeyFormat,
169 key_data: &[u8],
170 extractable: bool,
171 usages: Vec<KeyUsage>,
172) -> Result<DomRoot<CryptoKey>, Error> {
173 aes_common::import_key(
174 AesAlgorithm::AesCtr,
175 cx,
176 global,
177 format,
178 key_data,
179 extractable,
180 usages,
181 )
182}
183
184pub(crate) fn export_key(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
186 aes_common::export_key(AesAlgorithm::AesCtr, format, key)
187}
188
189pub(crate) fn get_key_length(
191 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
192) -> Result<Option<u32>, Error> {
193 aes_common::get_key_length(normalized_derived_key_algorithm)
194}