1use openhcl_attestation_protocol::vmgs::AES_GCM_KEY_LENGTH;
7use openhcl_attestation_protocol::vmgs::HMAC_SHA_256_KEY_LENGTH;
8use openssl::pkey::Private;
9use openssl::rsa::Rsa;
10use openssl_kdf::kdf::Kbkdf;
11use thiserror::Error;
12
13#[derive(Debug, Error)]
14pub(crate) enum KbkdfError {
15 #[error("KDF derivation failed")]
16 Derive(#[from] openssl_kdf::kdf::KdfError),
17}
18
19#[derive(Debug, Error)]
20pub(crate) enum Pkcs11RsaAesKeyUnwrapError {
21 #[error("expected wrapped AES key blob to be {0} bytes, but found {1} bytes")]
22 UndersizedWrappedAesKey(usize, usize),
23 #[error("wrapped RSA key blob cannot be empty")]
24 EmptyWrappedRsaKey,
25 #[error("RSA unwrap failed")]
26 RsaUnwrap(#[from] RsaOaepError),
27 #[error("AES unwrap failed")]
28 AesUnwrap(#[from] AesKeyWrapWithPaddingError),
29 #[error("failed to convert PKCS #8 DER format to PKey")]
30 ConvertPkcs8DerToPkey(#[source] openssl::error::ErrorStack),
31 #[error("failed to get an RSA key from PKey")]
32 PkeyToRsa(#[from] openssl::error::ErrorStack),
33}
34
35#[derive(Debug, Error)]
36pub(crate) enum RsaOaepError {
37 #[error("failed to convert an RSA key to PKey")]
38 RsaToPkey(#[source] openssl::error::ErrorStack),
39 #[error("Pkeyctx::new() failed")]
40 PkeyCtxNew(#[source] openssl::error::ErrorStack),
41 #[error("PkeyCtx encrypt_init() failed")]
42 PkeyCtxEncryptInit(#[source] openssl::error::ErrorStack),
43 #[error("PkeyCtx decrypt_init() failed")]
44 PkeyCtxDecryptInit(#[source] openssl::error::ErrorStack),
45 #[error("PkeyCtx set_rsa_padding() failed")]
46 PkeyCtxSetRsaPadding(#[source] openssl::error::ErrorStack),
47 #[error("PkeyCtx set_rsa_oaep_md() failed")]
48 PkeyCtxSetRsaOaepMd(#[source] openssl::error::ErrorStack),
49 #[error("Encryption failed, OAEP hash algorithm {1:?}")]
50 Encrypt(#[source] openssl::error::ErrorStack, RsaOaepHashAlgorithm),
51 #[error("Decryption failed, OAEP hash algorithm {1:?}")]
52 Decrypt(#[source] openssl::error::ErrorStack, RsaOaepHashAlgorithm),
53}
54
55#[derive(Debug, Error)]
56pub(crate) enum AesKeyWrapWithPaddingError {
57 #[error("invalid wrapping key size {0}")]
58 InvalidWrappingKeySize(usize),
59 #[error("Invalid unwrapping key size {0}")]
60 InvalidUnwrappingKeySize(usize),
61 #[error("CipherCtx::new failed")]
62 CipherCtxNew(#[source] openssl::error::ErrorStack),
63 #[error("CipherCtx encrypt_init() failed")]
64 CipherCtxEncryptInit(#[source] openssl::error::ErrorStack),
65 #[error("CipherCtx decrypt_init() failed")]
66 CipherCtxDecryptInit(#[source] openssl::error::ErrorStack),
67 #[error("AES key wrap with padding update failed")]
68 WrapUpdate(#[source] openssl::error::ErrorStack),
69 #[error("AES key unwrap with padding update failed")]
70 UnwrapUpdate(#[source] openssl::error::ErrorStack),
71}
72
73#[derive(Debug, Error)]
74pub(crate) enum Aes256CbcError {
75 #[error("CipherCtx::new failed")]
76 CipherCtxNew(#[source] openssl::error::ErrorStack),
77 #[error("CipherCtx encrypt_init() failed")]
78 CipherCtxEncryptInit(#[source] openssl::error::ErrorStack),
79 #[error("CipherCtx decrypt_init() failed")]
80 CipherCtxDecryptInit(#[source] openssl::error::ErrorStack),
81 #[error("AES-256-CBC encrypt failed")]
82 Encrypt(#[source] openssl::error::ErrorStack),
83 #[error("AES-256-CBC decrypt failed")]
84 Decrypt(#[source] openssl::error::ErrorStack),
85}
86
87#[derive(Debug, Error)]
88pub(crate) enum HmacSha256Error {
89 #[error("failed to convert an HMAC key to PKey")]
90 HmacKeyToPkey(#[source] openssl::error::ErrorStack),
91 #[error("MdCtx::new failed")]
92 MdCtxNew(#[source] openssl::error::ErrorStack),
93 #[error("HMAC init failed")]
94 HmacInit(#[source] openssl::error::ErrorStack),
95 #[error("HMAC update failed")]
96 HmacUpdate(#[source] openssl::error::ErrorStack),
97 #[error("HMAC final failed")]
98 HmacFinal(#[source] openssl::error::ErrorStack),
99 #[error("failed to get the required HMAC output size")]
100 GetHmacRequiredSize(#[source] openssl::error::ErrorStack),
101 #[error("HMAC SHA 256 failed")]
102 OpenSSL(#[from] openssl::error::ErrorStack),
103 #[error("invalid output size {0}, expected {1}")]
104 InvalidOutputSize(usize, usize),
105}
106
107pub fn derive_key(
109 key: &[u8],
110 context: &[u8],
111 label: &[u8],
112) -> Result<[u8; AES_GCM_KEY_LENGTH], KbkdfError> {
113 let mut kdf = Kbkdf::new(
115 openssl::hash::MessageDigest::sha256(),
116 label.to_vec(),
117 key.to_vec(),
118 );
119 kdf.set_context(context.to_vec());
120 let mut output = [0; AES_GCM_KEY_LENGTH];
121 openssl_kdf::kdf::derive(kdf, &mut output)?;
122 Ok(output)
123}
124
125pub fn pkcs11_rsa_aes_key_unwrap(
127 unwrapping_rsa_key: &Rsa<Private>,
128 wrapped_key_blob: &[u8],
129) -> Result<Rsa<Private>, Pkcs11RsaAesKeyUnwrapError> {
130 let modulus_size = unwrapping_rsa_key.size() as usize;
131
132 let (wrapped_aes_key, wrapped_rsa_key) = wrapped_key_blob
133 .split_at_checked(modulus_size)
134 .ok_or_else(|| {
135 Pkcs11RsaAesKeyUnwrapError::UndersizedWrappedAesKey(
136 modulus_size,
137 wrapped_key_blob.len(),
138 )
139 })?;
140
141 if wrapped_rsa_key.is_empty() {
142 return Err(Pkcs11RsaAesKeyUnwrapError::EmptyWrappedRsaKey);
143 }
144
145 let unwrapped_aes_key = rsa_oaep_decrypt(
146 unwrapping_rsa_key,
147 wrapped_aes_key,
148 RsaOaepHashAlgorithm::Sha1,
149 )
150 .map_err(Pkcs11RsaAesKeyUnwrapError::RsaUnwrap)?;
151 let unwrapped_rsa_key = aes_key_unwrap_with_padding(&unwrapped_aes_key, wrapped_rsa_key)
152 .map_err(Pkcs11RsaAesKeyUnwrapError::AesUnwrap)?;
153 let unwrapped_rsa_key = openssl::pkey::PKey::private_key_from_pkcs8(&unwrapped_rsa_key)
154 .map_err(Pkcs11RsaAesKeyUnwrapError::ConvertPkcs8DerToPkey)?;
155 let unwrapped_rsa_key = unwrapped_rsa_key
156 .rsa()
157 .map_err(Pkcs11RsaAesKeyUnwrapError::PkeyToRsa)?;
158
159 Ok(unwrapped_rsa_key)
160}
161
162#[derive(Debug)]
164pub enum RsaOaepHashAlgorithm {
165 Sha1,
167 Sha256,
169}
170
171pub fn rsa_oaep_encrypt(
173 rsa: &Rsa<Private>,
174 input: &[u8],
175 hash_algorithm: RsaOaepHashAlgorithm,
176) -> Result<Vec<u8>, RsaOaepError> {
177 let pkey = openssl::pkey::PKey::from_rsa(rsa.to_owned()).map_err(RsaOaepError::RsaToPkey)?;
178 let mut ctx = openssl::pkey_ctx::PkeyCtx::new(&pkey).map_err(RsaOaepError::PkeyCtxNew)?;
179
180 ctx.encrypt_init()
181 .map_err(RsaOaepError::PkeyCtxEncryptInit)?;
182 ctx.set_rsa_padding(openssl::rsa::Padding::PKCS1_OAEP)
183 .map_err(RsaOaepError::PkeyCtxSetRsaPadding)?;
184
185 match hash_algorithm {
186 RsaOaepHashAlgorithm::Sha1 => ctx.set_rsa_oaep_md(openssl::md::Md::sha1()),
187 RsaOaepHashAlgorithm::Sha256 => ctx.set_rsa_oaep_md(openssl::md::Md::sha256()),
188 }
189 .map_err(RsaOaepError::PkeyCtxSetRsaOaepMd)?;
190
191 let mut output = vec![];
192 ctx.encrypt_to_vec(input, &mut output)
193 .map_err(|e| RsaOaepError::Encrypt(e, hash_algorithm))?;
194
195 Ok(output)
196}
197
198pub fn rsa_oaep_decrypt(
200 rsa: &Rsa<Private>,
201 input: &[u8],
202 hash_algorithm: RsaOaepHashAlgorithm,
203) -> Result<Vec<u8>, RsaOaepError> {
204 let pkey = openssl::pkey::PKey::from_rsa(rsa.to_owned()).map_err(RsaOaepError::RsaToPkey)?;
205 let mut ctx = openssl::pkey_ctx::PkeyCtx::new(&pkey).map_err(RsaOaepError::PkeyCtxNew)?;
206
207 ctx.decrypt_init()
208 .map_err(RsaOaepError::PkeyCtxDecryptInit)?;
209 ctx.set_rsa_padding(openssl::rsa::Padding::PKCS1_OAEP)
210 .map_err(RsaOaepError::PkeyCtxSetRsaPadding)?;
211
212 match hash_algorithm {
213 RsaOaepHashAlgorithm::Sha1 => ctx.set_rsa_oaep_md(openssl::md::Md::sha1()),
214 RsaOaepHashAlgorithm::Sha256 => ctx.set_rsa_oaep_md(openssl::md::Md::sha256()),
215 }
216 .map_err(RsaOaepError::PkeyCtxSetRsaOaepMd)?;
217
218 let mut output = vec![];
219 ctx.decrypt_to_vec(input, &mut output)
220 .map_err(|e| RsaOaepError::Decrypt(e, hash_algorithm))?;
221
222 Ok(output)
223}
224
225pub fn aes_key_wrap_with_padding(
227 wrapping_key: &[u8],
228 payload: &[u8],
229) -> Result<Vec<u8>, AesKeyWrapWithPaddingError> {
230 let cipher = match wrapping_key.len() {
231 16 => openssl::cipher::Cipher::aes_128_wrap_pad(),
232 24 => openssl::cipher::Cipher::aes_192_wrap_pad(),
233 32 => openssl::cipher::Cipher::aes_256_wrap_pad(),
234 key_size => Err(AesKeyWrapWithPaddingError::InvalidWrappingKeySize(key_size))?,
235 };
236 let padding = 8 - payload.len() % 8;
237 let mut output = vec![0; payload.len() + padding + cipher.block_size()];
238 let mut ctx =
239 openssl::cipher_ctx::CipherCtx::new().map_err(AesKeyWrapWithPaddingError::CipherCtxNew)?;
240
241 ctx.set_flags(openssl::cipher_ctx::CipherCtxFlags::FLAG_WRAP_ALLOW);
242 ctx.encrypt_init(Some(cipher), Some(wrapping_key), None)
243 .map_err(AesKeyWrapWithPaddingError::CipherCtxEncryptInit)?;
244
245 let count = ctx
246 .cipher_update(payload, Some(&mut output))
247 .map_err(AesKeyWrapWithPaddingError::WrapUpdate)?;
248 output.truncate(count);
251
252 Ok(output)
253}
254
255pub fn aes_key_unwrap_with_padding(
257 unwrapping_key: &[u8],
258 wrapped_payload: &[u8],
259) -> Result<Vec<u8>, AesKeyWrapWithPaddingError> {
260 let cipher = match unwrapping_key.len() {
261 16 => openssl::cipher::Cipher::aes_128_wrap_pad(),
262 24 => openssl::cipher::Cipher::aes_192_wrap_pad(),
263 32 => openssl::cipher::Cipher::aes_256_wrap_pad(),
264 key_size => Err(AesKeyWrapWithPaddingError::InvalidUnwrappingKeySize(
265 key_size,
266 ))?,
267 };
268 let mut output = vec![0; wrapped_payload.len() + cipher.block_size()];
269 let mut ctx =
270 openssl::cipher_ctx::CipherCtx::new().map_err(AesKeyWrapWithPaddingError::CipherCtxNew)?;
271
272 ctx.set_flags(openssl::cipher_ctx::CipherCtxFlags::FLAG_WRAP_ALLOW);
273 ctx.decrypt_init(Some(cipher), Some(unwrapping_key), None)
274 .map_err(AesKeyWrapWithPaddingError::CipherCtxDecryptInit)?;
275
276 let count = ctx
277 .cipher_update(wrapped_payload, Some(&mut output))
278 .map_err(AesKeyWrapWithPaddingError::UnwrapUpdate)?;
279 output.truncate(count);
282
283 Ok(output)
284}
285
286pub fn aes_256_cbc_encrypt(key: &[u8], data: &[u8], iv: &[u8]) -> Result<Vec<u8>, Aes256CbcError> {
288 let cipher = openssl::cipher::Cipher::aes_256_cbc();
289 let mut output = vec![0u8; data.len() + cipher.block_size()];
290 let mut ctx = openssl::cipher_ctx::CipherCtx::new().map_err(Aes256CbcError::CipherCtxNew)?;
291
292 ctx.encrypt_init(Some(cipher), Some(key), Some(iv))
293 .map_err(Aes256CbcError::CipherCtxEncryptInit)?;
294 ctx.set_padding(false);
295
296 let count = ctx
297 .cipher_update(data, Some(&mut output))
298 .map_err(Aes256CbcError::Encrypt)?;
299 let rest = ctx
300 .cipher_final(&mut output[count..])
301 .map_err(Aes256CbcError::Encrypt)?;
302 output.truncate(count + rest);
303
304 Ok(output)
305}
306
307pub fn aes_256_cbc_decrypt(key: &[u8], data: &[u8], iv: &[u8]) -> Result<Vec<u8>, Aes256CbcError> {
309 let cipher = openssl::cipher::Cipher::aes_256_cbc();
310 let mut output = vec![0u8; data.len() + cipher.block_size()];
311 let mut ctx = openssl::cipher_ctx::CipherCtx::new().map_err(Aes256CbcError::CipherCtxNew)?;
312
313 ctx.decrypt_init(Some(cipher), Some(key), Some(iv))
314 .map_err(Aes256CbcError::CipherCtxDecryptInit)?;
315 ctx.set_padding(false);
316
317 let count = ctx
318 .cipher_update(data, Some(&mut output))
319 .map_err(Aes256CbcError::Decrypt)?;
320 let rest = ctx
321 .cipher_final(&mut output[count..])
322 .map_err(Aes256CbcError::Decrypt)?;
323 output.truncate(count + rest);
324
325 Ok(output)
326}
327
328pub fn hmac_sha_256(
330 key: &[u8],
331 data: &[u8],
332) -> Result<[u8; HMAC_SHA_256_KEY_LENGTH], HmacSha256Error> {
333 let pkey = openssl::pkey::PKey::hmac(key).map_err(HmacSha256Error::HmacKeyToPkey)?;
334 let mut ctx = openssl::md_ctx::MdCtx::new().map_err(HmacSha256Error::MdCtxNew)?;
335
336 ctx.digest_sign_init(Some(openssl::md::Md::sha256()), &pkey)
337 .map_err(HmacSha256Error::HmacInit)?;
338 ctx.digest_sign_update(data)
339 .map_err(HmacSha256Error::HmacUpdate)?;
340
341 let size = ctx
342 .digest_sign_final(None)
343 .map_err(HmacSha256Error::GetHmacRequiredSize)?;
344 if size != HMAC_SHA_256_KEY_LENGTH {
345 Err(HmacSha256Error::InvalidOutputSize(
346 size,
347 HMAC_SHA_256_KEY_LENGTH,
348 ))?
349 }
350
351 let mut output = [0u8; HMAC_SHA_256_KEY_LENGTH];
352 ctx.digest_sign_final(Some(&mut output))
353 .map_err(HmacSha256Error::HmacFinal)?;
354
355 Ok(output)
356}
357
358pub fn sha_256(data: &[u8]) -> [u8; 32] {
360 let mut hasher = openssl::sha::Sha256::new();
361 hasher.update(data);
362 hasher.finish()
363}
364
365#[cfg(test)]
366mod tests {
367 use super::*;
368
369 #[test]
370 fn kdf_kat_one() {
371 let key = [0; 32];
372 let context = [
373 0x28, 0x84, 0x18, 0x6c, 0xfe, 0xd2, 0x50, 0x41, 0x10, 0x69, 0x8b, 0x45, 0xd4, 0x80,
374 0x72, 0x88, 0xdf, 0x67, 0x4c, 0x48, 0x26, 0x19, 0x7a, 0x98, 0x69, 0x88, 0xaf, 0x96,
375 0x05, 0x62, 0xf5, 0x7f,
376 ];
377 let expected_result = [
378 0x9d, 0xb5, 0x8b, 0xb7, 0x0c, 0xa6, 0xcb, 0x6f, 0xaa, 0xe3, 0x81, 0x74, 0x64, 0x21,
379 0x76, 0xfa, 0x0d, 0xed, 0x28, 0x67, 0x30, 0x76, 0x90, 0x83, 0x83, 0xa0, 0x1a, 0xd7,
380 0x2e, 0xc3, 0xe2, 0x3b,
381 ];
382
383 let result = derive_key(&key, &context, crate::VMGS_KEY_DERIVE_LABEL).unwrap();
384
385 assert_eq!(result, expected_result);
386 }
387
388 #[test]
389 fn kdf_kat_two() {
390 let key = [0; 32];
391 let context = [
392 0xd6, 0x8a, 0x8d, 0x52, 0x7c, 0x5c, 0xa5, 0x9b, 0x19, 0x5a, 0xe7, 0x45, 0x6c, 0x3f,
393 0xef, 0x4d, 0x0e, 0xb0, 0xbe, 0x16, 0xc7, 0x8d, 0x77, 0xbd, 0x28, 0x5a, 0xa1, 0x45,
394 0x3e, 0x24, 0xeb, 0x3f,
395 ];
396 let expected_result = [
397 0x0a, 0xda, 0x54, 0x91, 0xd6, 0x09, 0x92, 0x87, 0x2f, 0xd7, 0x1a, 0x15, 0x71, 0x24,
398 0x82, 0x36, 0x25, 0xb4, 0xb9, 0x54, 0xc2, 0xf4, 0xeb, 0x47, 0x02, 0x88, 0x42, 0x7b,
399 0x1f, 0x8e, 0xdf, 0x3d,
400 ];
401
402 let result = derive_key(&key, &context, crate::VMGS_KEY_DERIVE_LABEL).unwrap();
403
404 assert_eq!(result, expected_result);
405 }
406
407 #[test]
408 fn test_aes_key_wrap_with_padding_kat() {
409 const KEK: [u8; 24] = [
410 0x58, 0x40, 0xdf, 0x6e, 0x29, 0xb0, 0x2a, 0xf1, 0xab, 0x49, 0x3b, 0x70, 0x5b, 0xf1,
411 0x6e, 0xa1, 0xae, 0x83, 0x38, 0xf4, 0xdc, 0xc1, 0x76, 0xa8,
412 ];
413 const KEY20: [u8; 20] = [
414 0xc3, 0x7b, 0x7e, 0x64, 0x92, 0x58, 0x43, 0x40, 0xbe, 0xd1, 0x22, 0x07, 0x80, 0x89,
415 0x41, 0x15, 0x50, 0x68, 0xf7, 0x38,
416 ];
417 const WRAP20: [u8; 32] = [
418 0x13, 0x8b, 0xde, 0xaa, 0x9b, 0x8f, 0xa7, 0xfc, 0x61, 0xf9, 0x77, 0x42, 0xe7, 0x22,
419 0x48, 0xee, 0x5a, 0xe6, 0xae, 0x53, 0x60, 0xd1, 0xae, 0x6a, 0x5f, 0x54, 0xf3, 0x73,
420 0xfa, 0x54, 0x3b, 0x6a,
421 ];
422 const KEY7: [u8; 7] = [0x46, 0x6f, 0x72, 0x50, 0x61, 0x73, 0x69];
423 const WRAP7: [u8; 16] = [
424 0xaf, 0xbe, 0xb0, 0xf0, 0x7d, 0xfb, 0xf5, 0x41, 0x92, 0x00, 0xf2, 0xcc, 0xb5, 0x0b,
425 0xb2, 0x4f,
426 ];
427
428 let result = aes_key_wrap_with_padding(&KEK, &KEY20);
429 assert!(result.is_ok());
430 let wrapped_key = result.unwrap();
431 assert_eq!(wrapped_key, WRAP20);
432
433 let result = aes_key_unwrap_with_padding(&KEK, &WRAP20);
434 assert!(result.is_ok());
435 let unwrapped_key = result.unwrap();
436 assert_eq!(unwrapped_key, KEY20);
437
438 let result = aes_key_wrap_with_padding(&KEK, &KEY7);
439 assert!(result.is_ok());
440 let wrapped_key = result.unwrap();
441 assert_eq!(wrapped_key, WRAP7);
442
443 let result = aes_key_unwrap_with_padding(&KEK, &WRAP7);
444 assert!(result.is_ok());
445 let unwrapped_key = result.unwrap();
446 assert_eq!(unwrapped_key, KEY7);
447 }
448
449 #[test]
450 fn test_aes_key_wrap_with_padding() {
451 const KEY: [u8; 32] = [
452 0x3f, 0xf4, 0xdb, 0xdb, 0x74, 0xd9, 0x3d, 0x22, 0x35, 0xc6, 0x7c, 0x9e, 0x17, 0x6a,
453 0x88, 0x7f, 0xf9, 0x11, 0xd6, 0x5b, 0x5a, 0x56, 0x06, 0xa7, 0xfb, 0x52, 0x58, 0xfc,
454 0x4e, 0x76, 0xce, 0x49,
455 ];
456
457 const AES_WRAPPED_KEY: [u8; 40] = [
458 0x56, 0x53, 0xe9, 0x29, 0xa9, 0x35, 0x0c, 0x32, 0xd0, 0x24, 0x22, 0xb4, 0x98, 0xe1,
459 0x13, 0xe7, 0x4a, 0x81, 0xc1, 0xf3, 0xb2, 0xa6, 0x27, 0x70, 0x6e, 0x0d, 0x12, 0x97,
460 0xfd, 0xa5, 0x07, 0x0a, 0x5e, 0xb0, 0xd2, 0xde, 0xb2, 0x8a, 0x06, 0x72,
461 ];
462
463 const WRAPPING_KEY: [u8; 32] = [
464 0x10, 0x84, 0xD2, 0x2F, 0x53, 0x5F, 0xD3, 0x10, 0xE2, 0xC6, 0x17, 0x31, 0x3D, 0xCA,
465 0xE7, 0xEF, 0x19, 0xDD, 0x45, 0x2A, 0xED, 0x1C, 0xE6, 0xB1, 0xBE, 0xF5, 0xB9, 0xD0,
466 0x1B, 0xF1, 0x5F, 0x44,
467 ];
468
469 let result = aes_key_wrap_with_padding(&WRAPPING_KEY, &KEY);
470 assert!(result.is_ok());
471 let wrapped_key = result.unwrap();
472 assert_eq!(wrapped_key, AES_WRAPPED_KEY);
473
474 let result = aes_key_unwrap_with_padding(&WRAPPING_KEY, &AES_WRAPPED_KEY);
475 assert!(result.is_ok());
476 let unwrapped_key = result.unwrap();
477 assert_eq!(unwrapped_key, KEY);
478 }
479
480 #[test]
481 fn fail_to_unwrap_pkcs11_rsa_aep_with_undersized_wrapped_key_blob() {
482 let rsa = Rsa::generate(2048).unwrap();
483
484 let wrapped_key_blob = vec![0; 256 - 1];
486 let result = pkcs11_rsa_aes_key_unwrap(&rsa, &wrapped_key_blob);
487 assert!(result.is_err());
488 assert_eq!(
489 result.unwrap_err().to_string(),
490 "expected wrapped AES key blob to be 256 bytes, but found 255 bytes".to_string()
491 );
492
493 let wrapped_key_blob = vec![0; 256];
495 let result = pkcs11_rsa_aes_key_unwrap(&rsa, &wrapped_key_blob);
496 assert!(result.is_err());
497 assert_eq!(
498 result.unwrap_err().to_string(),
499 "wrapped RSA key blob cannot be empty".to_string()
500 );
501 }
502
503 #[test]
504 fn test_pkcs11_rsa_aes_key_unwrap() {
505 let target_key = Rsa::generate(2048).unwrap();
506 let pkcs8_target_key = openssl::pkey::PKey::from_rsa(target_key.clone())
507 .unwrap()
508 .private_key_to_pkcs8()
509 .unwrap();
510
511 let mut wrapping_aes_key = [0u8; 32];
512 openssl::rand::rand_bytes(&mut wrapping_aes_key[..]).unwrap();
513
514 let wrapping_rsa_key = Rsa::generate(2048).unwrap();
515 let wrapped_aes_key = rsa_oaep_encrypt(
516 &wrapping_rsa_key,
517 &wrapping_aes_key,
518 RsaOaepHashAlgorithm::Sha1,
519 )
520 .unwrap();
521 let wrapped_target_key =
522 aes_key_wrap_with_padding(&wrapping_aes_key, &pkcs8_target_key).unwrap();
523 let wrapped_key_blob = [wrapped_aes_key, wrapped_target_key].concat();
524 let unwrapped_target_key =
525 pkcs11_rsa_aes_key_unwrap(&wrapping_rsa_key, wrapped_key_blob.as_slice()).unwrap();
526 assert_eq!(
527 unwrapped_target_key.private_key_to_der().unwrap(),
528 target_key.private_key_to_der().unwrap()
529 );
530 }
531
532 #[test]
533 fn test_hmac_sha_256() {
534 let key: Vec<u8> = (0..32).collect();
535
536 const EMPTY_HMAC: [u8; 32] = [
537 0xd3, 0x8b, 0x42, 0x09, 0x6d, 0x80, 0xf4, 0x5f, 0x82, 0x6b, 0x44, 0xa9, 0xd5, 0x60,
538 0x7d, 0xe7, 0x24, 0x96, 0xa4, 0x15, 0xd3, 0xf4, 0xa1, 0xa8, 0xc8, 0x8e, 0x3b, 0xb9,
539 0xda, 0x8d, 0xc1, 0xcb,
540 ];
541
542 let hmac = hmac_sha_256(key.as_slice(), &[]).unwrap();
543 assert_eq!(hmac, EMPTY_HMAC);
544
545 const PANGRAM: [u8; 32] = [
546 0xf8, 0x7a, 0xd2, 0x56, 0x15, 0x1f, 0xc7, 0xb4, 0xc5, 0xdf, 0xfa, 0x4a, 0xdb, 0x3e,
547 0xbe, 0x91, 0x1a, 0x8e, 0xeb, 0x8a, 0x8e, 0xbd, 0xee, 0x3c, 0x2a, 0x4a, 0x8e, 0x5f,
548 0x5e, 0xc0, 0x2c, 0x32,
549 ];
550
551 let hmac = hmac_sha_256(
552 key.as_slice(),
553 b"The quick brown fox jumps over the lazy dog",
554 )
555 .unwrap();
556 assert_eq!(hmac, PANGRAM);
557 }
558
559 #[test]
560 fn test_sha256() {
561 const EMPTY_HASH: [u8; 32] = [
562 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f,
563 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
564 0x78, 0x52, 0xb8, 0x55,
565 ];
566
567 let hash = sha_256(&[]);
568 assert_eq!(hash, EMPTY_HASH);
569
570 const PANGRAM: [u8; 32] = [
571 0xd7, 0xa8, 0xfb, 0xb3, 0x07, 0xd7, 0x80, 0x94, 0x69, 0xca, 0x9a, 0xbc, 0xb0, 0x08,
572 0x2e, 0x4f, 0x8d, 0x56, 0x51, 0xe4, 0x6d, 0x3c, 0xdb, 0x76, 0x2d, 0x02, 0xd0, 0xbf,
573 0x37, 0xc9, 0xe5, 0x92,
574 ];
575
576 let hash = sha_256(b"The quick brown fox jumps over the lazy dog");
577 assert_eq!(hash, PANGRAM);
578 }
579}