script/dom/subtlecrypto/
aes_ctr_operation.rs1use aes::{Aes128, Aes192, Aes256};
6use cipher::{KeyIvInit, StreamCipher};
7use ctr::Ctr128BE;
8use js::context::JSContext;
9
10use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::KeyUsage;
11use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::KeyFormat;
12use crate::dom::bindings::error::Error;
13use crate::dom::bindings::root::DomRoot;
14use crate::dom::cryptokey::{CryptoKey, Handle};
15use crate::dom::globalscope::GlobalScope;
16use crate::dom::subtlecrypto::aes_common::AesAlgorithm;
17use crate::dom::subtlecrypto::{
18 ExportedKey, SubtleAesCtrParams, SubtleAesDerivedKeyParams, SubtleAesKeyGenParams, aes_common,
19};
20
21pub(crate) fn encrypt(
23 normalized_algorithm: &SubtleAesCtrParams,
24 key: &CryptoKey,
25 plaintext: &[u8],
26) -> Result<Vec<u8>, Error> {
27 if normalized_algorithm.counter.len() != 16 {
30 return Err(Error::Operation(Some(
31 "The initial counter block length is not 16 bytes".into(),
32 )));
33 }
34
35 if normalized_algorithm.length == 0 {
38 return Err(Error::Operation(Some("The counter length is zero".into())));
39 }
40 if normalized_algorithm.length > 128 {
41 return Err(Error::Operation(Some(
42 "The counter length is greater than 128".into(),
43 )));
44 }
45
46 let iv = normalized_algorithm.counter.as_slice();
52 let mut ciphertext = plaintext.to_vec();
53 match key.handle() {
54 Handle::Aes128Key(key) => {
55 let mut cipher = Ctr128BE::<Aes128>::new(key, iv.into());
56 cipher.apply_keystream(&mut ciphertext);
57 },
58 Handle::Aes192Key(key) => {
59 let mut cipher = Ctr128BE::<Aes192>::new(key, iv.into());
60 cipher.apply_keystream(&mut ciphertext);
61 },
62 Handle::Aes256Key(key) => {
63 let mut cipher = Ctr128BE::<Aes256>::new(key, iv.into());
64 cipher.apply_keystream(&mut ciphertext);
65 },
66 _ => {
67 return Err(Error::Operation(Some(
68 "The key handle is not representing an AES key".to_string(),
69 )));
70 },
71 };
72
73 Ok(ciphertext)
75}
76
77pub(crate) fn decrypt(
79 normalized_algorithm: &SubtleAesCtrParams,
80 key: &CryptoKey,
81 ciphertext: &[u8],
82) -> Result<Vec<u8>, Error> {
83 if normalized_algorithm.counter.len() != 16 {
86 return Err(Error::Operation(Some(
87 "The initial counter block length is not 16 bytes".into(),
88 )));
89 }
90
91 if normalized_algorithm.length == 0 {
94 return Err(Error::Operation(Some("The counter length is zero".into())));
95 }
96 if normalized_algorithm.length > 128 {
97 return Err(Error::Operation(Some(
98 "The counter length is greater than 128".into(),
99 )));
100 }
101
102 let iv = normalized_algorithm.counter.as_slice();
108 let mut plaintext = ciphertext.to_vec();
109 match key.handle() {
110 Handle::Aes128Key(key) => {
111 let mut cipher = Ctr128BE::<Aes128>::new(key, iv.into());
112 cipher.apply_keystream(&mut plaintext);
113 },
114 Handle::Aes192Key(key) => {
115 let mut cipher = Ctr128BE::<Aes192>::new(key, iv.into());
116 cipher.apply_keystream(&mut plaintext);
117 },
118 Handle::Aes256Key(key) => {
119 let mut cipher = Ctr128BE::<Aes256>::new(key, iv.into());
120 cipher.apply_keystream(&mut plaintext);
121 },
122 _ => {
123 return Err(Error::Operation(Some(
124 "The key handle is not representing an AES key".to_string(),
125 )));
126 },
127 };
128
129 Ok(plaintext)
131}
132
133pub(crate) fn generate_key(
135 cx: &mut JSContext,
136 global: &GlobalScope,
137 normalized_algorithm: &SubtleAesKeyGenParams,
138 extractable: bool,
139 usages: Vec<KeyUsage>,
140) -> Result<DomRoot<CryptoKey>, Error> {
141 aes_common::generate_key(
142 AesAlgorithm::AesCtr,
143 cx,
144 global,
145 normalized_algorithm,
146 extractable,
147 usages,
148 )
149}
150
151pub(crate) fn import_key(
153 cx: &mut JSContext,
154 global: &GlobalScope,
155 format: KeyFormat,
156 key_data: &[u8],
157 extractable: bool,
158 usages: Vec<KeyUsage>,
159) -> Result<DomRoot<CryptoKey>, Error> {
160 aes_common::import_key(
161 AesAlgorithm::AesCtr,
162 cx,
163 global,
164 format,
165 key_data,
166 extractable,
167 usages,
168 )
169}
170
171pub(crate) fn export_key(format: KeyFormat, key: &CryptoKey) -> Result<ExportedKey, Error> {
173 aes_common::export_key(AesAlgorithm::AesCtr, format, key)
174}
175
176pub(crate) fn get_key_length(
178 normalized_derived_key_algorithm: &SubtleAesDerivedKeyParams,
179) -> Result<Option<u32>, Error> {
180 aes_common::get_key_length(normalized_derived_key_algorithm)
181}