script/dom/webcrypto/subtlecrypto/
hkdf_operation.rs1use hkdf::Hkdf;
6use js::context::JSContext;
7use sha1::Sha1;
8use sha2::{Sha256, Sha384, Sha512};
9
10use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{KeyType, 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, KeyUsageVecHelper};
15use crate::dom::globalscope::GlobalScope;
16use crate::dom::subtlecrypto::{
17 CryptoAlgorithm, HkdfParams, KeyAlgorithm, KeyAlgorithmAndDerivatives, NormalizedAlgorithm,
18};
19
20pub(crate) fn derive_bits(
22 normalized_algorithm: &HkdfParams,
23 key: &CryptoKey,
24 length: Option<u32>,
25) -> Result<Vec<u8>, Error> {
26 let Some(length) = length else {
28 return Err(Error::Operation(Some("length is null".into())));
29 };
30 if length % 8 != 0 {
31 return Err(Error::Operation(Some(
32 "length is not a multiple of 8".into(),
33 )));
34 };
35
36 let hash_length = match normalized_algorithm.hash.name() {
39 CryptoAlgorithm::Sha1 => 160,
40 CryptoAlgorithm::Sha256 => 256,
41 CryptoAlgorithm::Sha384 => 384,
42 CryptoAlgorithm::Sha512 => 512,
43 algorithm_name => {
44 return Err(Error::Operation(Some(format!(
45 "Invalid hash algorithm: {}",
46 algorithm_name.as_str()
47 ))));
48 },
49 };
50
51 if length > 255 * hash_length {
53 return Err(Error::Operation(Some(
54 "length is greater than 255 * hashLength".into(),
55 )));
56 }
57
58 let Handle::HkdfSecret(key_derivation_key) = key.handle() else {
60 return Err(Error::Operation(Some(
61 "The [[handle]] internal slot is not from an HKDF key".into(),
62 )));
63 };
64
65 let mut result = vec![0u8; length as usize / 8];
74 match normalized_algorithm.hash.name() {
75 CryptoAlgorithm::Sha1 => {
76 Hkdf::<Sha1>::new(Some(&normalized_algorithm.salt), key_derivation_key)
77 .expand(&normalized_algorithm.info, &mut result)
78 .map_err(|error| Error::Operation(Some(error.to_string())))?
79 },
80 CryptoAlgorithm::Sha256 => {
81 Hkdf::<Sha256>::new(Some(&normalized_algorithm.salt), key_derivation_key)
82 .expand(&normalized_algorithm.info, &mut result)
83 .map_err(|error| Error::Operation(Some(error.to_string())))?
84 },
85 CryptoAlgorithm::Sha384 => {
86 Hkdf::<Sha384>::new(Some(&normalized_algorithm.salt), key_derivation_key)
87 .expand(&normalized_algorithm.info, &mut result)
88 .map_err(|error| Error::Operation(Some(error.to_string())))?
89 },
90 CryptoAlgorithm::Sha512 => {
91 Hkdf::<Sha512>::new(Some(&normalized_algorithm.salt), key_derivation_key)
92 .expand(&normalized_algorithm.info, &mut result)
93 .map_err(|error| Error::Operation(Some(error.to_string())))?
94 },
95 algorithm_name => {
96 return Err(Error::Operation(Some(format!(
97 "Invalid hash algorithm: {}",
98 algorithm_name.as_str()
99 ))));
100 },
101 }
102
103 Ok(result)
105}
106
107pub(crate) fn import_key(
109 cx: &mut JSContext,
110 global: &GlobalScope,
111 format: KeyFormat,
112 key_data: &[u8],
113 extractable: bool,
114 usages: Vec<KeyUsage>,
115) -> Result<DomRoot<CryptoKey>, Error> {
116 if matches!(format, KeyFormat::Raw | KeyFormat::Raw_secret) {
120 if usages
123 .iter()
124 .any(|usage| !matches!(usage, KeyUsage::DeriveKey | KeyUsage::DeriveBits)) ||
125 usages.is_empty()
126 {
127 return Err(Error::Syntax(Some(
128 "Usages contains an entry which is not \"deriveKey\" or \"deriveBits\"".into(),
129 )));
130 }
131
132 if extractable {
134 return Err(Error::Syntax(Some("'extractable' is not false".into())));
135 }
136
137 let algorithm = KeyAlgorithm {
143 name: CryptoAlgorithm::Hkdf,
144 };
145 let key = CryptoKey::new(
146 cx,
147 global,
148 KeyType::Secret,
149 extractable,
150 KeyAlgorithmAndDerivatives::KeyAlgorithm(algorithm),
151 usages.normalized_value(),
152 Handle::HkdfSecret(key_data.to_vec().into()),
153 );
154
155 Ok(key)
157 }
158 else {
160 Err(Error::NotSupported(Some(
162 "Formats different than \"raw\" are unsupported".into(),
163 )))
164 }
165}
166
167pub(crate) fn get_key_length() -> Result<Option<u32>, Error> {
169 Ok(None)
171}