// Copyright 2021 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 mod test_encrypt_decrypt_2 { use crate::common::create_ctx_without_session; use std::convert::{TryFrom, TryInto}; use tss_esapi::{ abstraction::cipher::Cipher, attributes::ObjectAttributesBuilder, interface_types::{ algorithm::{HashingAlgorithm, PublicAlgorithm, SymmetricMode}, key_bits::RsaKeyBits, resource_handles::Hierarchy, session_handles::AuthSession, }, structures::{ Auth, InitialValue, MaxBuffer, PublicBuilder, RsaExponent, SensitiveData, SymmetricCipherParameters, }, }; #[test] fn test_encrypt_decrypt_with_aes_128_cfb_symmetric_key() { let mut context = create_ctx_without_session(); context .tr_set_auth(Hierarchy::Owner.into(), Auth::default()) .expect("Failed to set auth to empty for owner"); let mut random_digest = vec![0u8; 16]; getrandom::getrandom(&mut random_digest).expect("get_rand call failed"); let primary_key_auth = Auth::try_from(random_digest).expect("Failed to create primary key auth"); let primary_key_handle = context.execute_with_session(Some(AuthSession::Password), |ctx| { ctx.create_primary( Hierarchy::Owner, tss_esapi::utils::create_restricted_decryption_rsa_public( Cipher::aes_128_cfb() .try_into() .expect("Failed to convert from Cipher"), RsaKeyBits::Rsa2048, RsaExponent::default(), ) .expect("Failed to create public for primary key"), Some(primary_key_auth.clone()), None, None, None, ) .expect("Failed to create primary handle") .key_handle }); context .tr_set_auth(primary_key_handle.into(), primary_key_auth) .expect("Failed to set auth from primary key handle."); let symmetric_key_object_attributes = ObjectAttributesBuilder::new() .with_user_with_auth(true) .with_sign_encrypt(true) .with_decrypt(true) .build() .expect("Failed to create object attributes for symmetric key"); let symmetric_key_public = PublicBuilder::new() .with_public_algorithm(PublicAlgorithm::SymCipher) .with_name_hashing_algorithm(HashingAlgorithm::Sha256) .with_object_attributes(symmetric_key_object_attributes) .with_symmetric_cipher_parameters(SymmetricCipherParameters::new( Cipher::aes_128_cfb() .try_into() .expect("Failed to create symmteric cipher parameters from cipher"), )) .with_symmetric_cipher_unique_identifier(Default::default()) .build() .expect("Failed to create public for symmetric key public"); let mut random_digest = vec![0u8; 16]; getrandom::getrandom(&mut random_digest).expect("get_rand call failed"); let symmetric_key_auth = Auth::try_from(random_digest).expect("Failed to create symmetric key auth"); let symmetric_key_value = SensitiveData::try_from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) .expect("Failed to create sensitive data from data"); // if this fails with "tpm:parameter(2):inconsistent attributes" then the symmetric // cipher is probably not supported. let symmetric_key_creation_data = context.execute_with_session(Some(AuthSession::Password), |ctx| { ctx.create( primary_key_handle, symmetric_key_public, Some(symmetric_key_auth.clone()), Some(symmetric_key_value), None, None, ) .expect("Failed to create symmetric key") }); let symmetric_key_handle = context.execute_with_session(Some(AuthSession::Password), |ctx| { ctx.load( primary_key_handle, symmetric_key_creation_data.out_private, symmetric_key_creation_data.out_public, ) .expect("Failed to load symmetric key") }); context .tr_set_auth(symmetric_key_handle.into(), symmetric_key_auth) .expect("Failed to set auth on symmetric key handle"); let initial_value = InitialValue::try_from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) .expect("Failed to create InitialValue from data"); let data = MaxBuffer::try_from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16]) .expect("Failed to create MaxBuffer from data"); let (encrypted_data, _) = context.execute_with_session(Some(AuthSession::Password), |ctx| { ctx.encrypt_decrypt_2( symmetric_key_handle, false, SymmetricMode::Cfb, data.clone(), initial_value.clone(), ) .expect("Call to encrypt_decrypt_2 failed when encrypting data") }); assert_ne!(data, encrypted_data); let (decrypted_data, _) = context.execute_with_session(Some(AuthSession::Password), |ctx| { ctx.encrypt_decrypt_2( symmetric_key_handle, true, SymmetricMode::Cfb, encrypted_data, initial_value, ) .expect("Call to encrypt_decrypt_2 failed when decrypting data") }); debug_assert_eq!(data, decrypted_data); } } mod test_hash { use crate::common::create_ctx_without_session; use std::convert::TryFrom; use tss_esapi::{ interface_types::{algorithm::HashingAlgorithm, resource_handles::Hierarchy}, structures::{MaxBuffer, Ticket}, }; #[test] fn test_hash_with_sha_256() { let mut context = create_ctx_without_session(); let data = "There is no spoon"; let expected_hashed_data: [u8; 32] = [ 0x6b, 0x38, 0x4d, 0x2b, 0xfb, 0x0e, 0x0d, 0xfb, 0x64, 0x89, 0xdb, 0xf4, 0xf8, 0xe9, 0xe5, 0x2f, 0x71, 0xee, 0xb1, 0x0d, 0x06, 0x4c, 0x56, 0x59, 0x70, 0xcd, 0xd9, 0x44, 0x43, 0x18, 0x5d, 0xc1, ]; let expected_hierarchy = Hierarchy::Owner; let (actual_hashed_data, ticket) = context .hash( MaxBuffer::try_from(data.as_bytes().to_vec()).unwrap(), HashingAlgorithm::Sha256, expected_hierarchy, ) .unwrap(); assert_eq!(expected_hashed_data.len(), actual_hashed_data.len()); assert_eq!(&expected_hashed_data[..], &actual_hashed_data[..]); assert_eq!(ticket.hierarchy(), expected_hierarchy); assert_ne!(ticket.digest().len(), 0); // Should do some better checking of the digest } } mod test_hmac { use crate::common::create_ctx_with_session; use std::convert::TryFrom; use tss_esapi::{ attributes::ObjectAttributesBuilder, interface_types::{ algorithm::{HashingAlgorithm, PublicAlgorithm}, resource_handles::Hierarchy, }, structures::{KeyedHashScheme, MaxBuffer, PublicBuilder, PublicKeyedHashParameters}, }; #[test] fn test_hmac() { let mut context = create_ctx_with_session(); let object_attributes = ObjectAttributesBuilder::new() .with_sign_encrypt(true) .with_sensitive_data_origin(true) .with_user_with_auth(true) .build() .expect("Failed to build object attributes"); let key_pub = PublicBuilder::new() .with_public_algorithm(PublicAlgorithm::KeyedHash) .with_name_hashing_algorithm(HashingAlgorithm::Sha256) .with_object_attributes(object_attributes) .with_keyed_hash_parameters(PublicKeyedHashParameters::new( KeyedHashScheme::HMAC_SHA_256, )) .with_keyed_hash_unique_identifier(Default::default()) .build() .expect("Failed to build public structure for key."); let key = context .create_primary(Hierarchy::Owner, key_pub, None, None, None, None) .unwrap(); let data = vec![1, 2, 3, 4]; let buf = MaxBuffer::try_from(data).unwrap(); context .hmac(key.key_handle.into(), buf, HashingAlgorithm::Sha256) .unwrap(); } }