// Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use std::convert::{TryFrom, TryInto}; use tss_esapi::{ abstraction::{ak, ek, KeyCustomization}, attributes::{ObjectAttributesBuilder, SessionAttributesBuilder}, constants::SessionType, handles::AuthHandle, interface_types::{ algorithm::{AsymmetricAlgorithm, HashingAlgorithm, SignatureSchemeAlgorithm}, session_handles::PolicySession, }, structures::{Auth, Digest, PublicBuilder, SymmetricDefinition}, }; use crate::common::create_ctx_without_session; #[test] fn test_create_ak_rsa_rsa() { let mut context = create_ctx_without_session(); let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap(); ak::create_ak( &mut context, ek_rsa, HashingAlgorithm::Sha256, SignatureSchemeAlgorithm::RsaPss, None, None, ) .unwrap(); } #[test] fn test_create_ak_rsa_ecc() { let mut context = create_ctx_without_session(); let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap(); if ak::create_ak( &mut context, ek_rsa, HashingAlgorithm::Sha256, SignatureSchemeAlgorithm::Sm2, None, None, ) .is_ok() { // We can't use unwrap_err because that requires Debug on the T panic!("Should have errored"); } } #[test] fn test_create_and_use_ak() { let mut context = create_ctx_without_session(); let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap(); let ak_auth = Auth::try_from(vec![0x1, 0x2, 0x42]).unwrap(); let att_key = ak::create_ak( &mut context, ek_rsa, HashingAlgorithm::Sha256, SignatureSchemeAlgorithm::RsaPss, Some(ak_auth.clone()), None, ) .unwrap(); let loaded_ak = ak::load_ak( &mut context, ek_rsa, Some(ak_auth), att_key.out_private, att_key.out_public, ) .unwrap(); let (_, key_name, _) = context.read_public(loaded_ak).unwrap(); let cred = vec![1, 2, 3, 4, 5]; let expected = Digest::try_from(vec![1, 2, 3, 4, 5]).unwrap(); let (session_aastributes, session_attributes_mask) = SessionAttributesBuilder::new().build(); let session_1 = context .start_auth_session( None, None, None, SessionType::Hmac, SymmetricDefinition::AES_256_CFB, HashingAlgorithm::Sha256, ) .expect("Failed to call start_auth_session") .expect("Failed invalid session value"); context .tr_sess_set_attributes(session_1, session_aastributes, session_attributes_mask) .unwrap(); let session_2 = context .start_auth_session( None, None, None, SessionType::Policy, SymmetricDefinition::AES_256_CFB, HashingAlgorithm::Sha256, ) .expect("Failed to call start_auth_session") .expect("Failed invalid session value"); context .tr_sess_set_attributes(session_2, session_aastributes, session_attributes_mask) .expect("Failed to call tr_sess_set_attributes"); let (credential_blob, secret) = context .execute_without_session(|ctx| { ctx.make_credential(ek_rsa, cred.try_into().unwrap(), key_name) }) .unwrap(); let _ = context .execute_with_session(Some(session_1), |ctx| { ctx.policy_secret( PolicySession::try_from(session_2) .expect("Failed to convert auth session to policy session"), AuthHandle::Endorsement, Default::default(), Default::default(), Default::default(), None, ) }) .unwrap(); context.set_sessions((Some(session_1), Some(session_2), None)); let decrypted = context .activate_credential(loaded_ak, ek_rsa, credential_blob, secret) .unwrap(); assert_eq!(expected, decrypted); } #[test] fn test_create_custom_ak() { struct CustomizeKey; impl KeyCustomization for &CustomizeKey { fn attributes( &self, attributes_builder: ObjectAttributesBuilder, ) -> ObjectAttributesBuilder { attributes_builder.with_st_clear(true) } fn template(&self, template_builder: PublicBuilder) -> PublicBuilder { template_builder.with_name_hashing_algorithm(HashingAlgorithm::Sha1) } } let mut context = create_ctx_without_session(); let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap(); let ak_auth = Auth::try_from(vec![0x1, 0x2, 0x42]).unwrap(); // Without customization, no st clear let att_key_without = ak::create_ak( &mut context, ek_rsa, HashingAlgorithm::Sha256, SignatureSchemeAlgorithm::RsaPss, Some(ak_auth.clone()), None, ) .unwrap(); assert!( !att_key_without.out_public.object_attributes().st_clear(), "ST Clear was set" ); // With a customization, we get a new attribute let att_key = ak::create_ak( &mut context, ek_rsa, HashingAlgorithm::Sha256, SignatureSchemeAlgorithm::RsaPss, Some(ak_auth), &CustomizeKey, ) .unwrap(); assert_eq!( att_key.out_public.object_attributes().0 & tss_esapi::constants::tss::TPMA_OBJECT_STCLEAR, tss_esapi::constants::tss::TPMA_OBJECT_STCLEAR ); assert_eq!( att_key.out_public.object_attributes().0, att_key_without.out_public.object_attributes().0 | tss_esapi::constants::tss::TPMA_OBJECT_STCLEAR ); assert_eq!( att_key.out_public.name_hashing_algorithm(), HashingAlgorithm::Sha1, ); }