From 13f06e0e2c2cf24922a3cc871ee19bfbc11f14ed Mon Sep 17 00:00:00 2001 From: Jesper Brynolf Date: Tue, 28 Nov 2023 23:33:48 +0100 Subject: [PATCH] Fixes problem with sign requiring a HashcheckTicket. - This fixes #475 by making the HashcheckTicket that was previously required in the ```sign``` context method optional instead. If it is ```None``` it is then internally converted into the HashcheckTicket version of the `Null ticket` before being converted to the corresponding TSS type. This has the benefit of removing the need to use the TSS type in order to create a `Null ticket`. Signed-off-by: Jesper Brynolf --- .../signing_and_signature_verification.rs | 55 ++++++++++++++++++- tss-esapi/src/structures/tickets.rs | 4 +- tss-esapi/src/utils/mod.rs | 10 +--- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/tss-esapi/src/context/tpm_commands/signing_and_signature_verification.rs b/tss-esapi/src/context/tpm_commands/signing_and_signature_verification.rs index 78c15083..0f9dfe37 100644 --- a/tss-esapi/src/context/tpm_commands/signing_and_signature_verification.rs +++ b/tss-esapi/src/context/tpm_commands/signing_and_signature_verification.rs @@ -40,15 +40,66 @@ impl Context { } /// Sign a digest with a key present in the TPM and return the signature. + /// + /// # Details + /// For signatures using a restricted key, a hashcheck must be provided. For unrestricted keys, this may be None. + /// + /// # Parameters + /// `key_handle` - Handle to the key be used for signing. + /// `digest` - The digest that is going to be signed. + /// `scheme` - The scheme to use if the scheme for the key referenced by the key handle is null. + /// `validation` - An optional [HashcheckTicket] that proof that the digest was created by the TPM. + /// N.B. None will be treated as a "Null ticket". + /// # Example + /// + /// ```rust + /// # use tss_esapi::{Context, TctiNameConf, + /// # interface_types::{ + /// # algorithm::{HashingAlgorithm, RsaSchemeAlgorithm}, + /// # key_bits::RsaKeyBits, + /// # resource_handles::Hierarchy, + /// # }, + /// # structures::{RsaScheme, RsaExponent}, + /// # utils::create_unrestricted_signing_rsa_public + /// # }; + /// use tss_esapi::structures::SignatureScheme; + /// # let mut context = + /// # Context::new( + /// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"), + /// # ).expect("Failed to create Context"); + /// # let signing_key_pub = create_unrestricted_signing_rsa_public( + /// # RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256)) + /// # .expect("Failed to create RSA scheme"), + /// # RsaKeyBits::Rsa2048, + /// # RsaExponent::default(), + /// # ) + /// # .expect("Failed to create an unrestricted signing rsa public structure"); + /// # let unrestricted_signing_key_handle = context + /// # .execute_with_nullauth_session(|ctx| { + /// # ctx.create_primary(Hierarchy::Owner, signing_key_pub, None, None, None, None) + /// # }) + /// # .unwrap() + /// # .key_handle; + /// # let digest = context.get_random(32).unwrap(); + /// let signature = context.execute_with_nullauth_session(|ctx| { + /// ctx.sign( + /// unrestricted_signing_key_handle, + /// digest, + /// SignatureScheme::Null, + /// None, + /// ) + /// }) + /// .expect("Failed to sign digest"); + /// ``` pub fn sign( &mut self, key_handle: KeyHandle, digest: Digest, scheme: SignatureScheme, - validation: Option, + validation: impl Into>, ) -> Result { let mut signature_ptr = null_mut(); - let validation_ticket = validation.unwrap_or_default().try_into()?; + let validation_ticket = validation.into().unwrap_or_default().try_into()?; ReturnCode::ensure_success( unsafe { Esys_Sign( diff --git a/tss-esapi/src/structures/tickets.rs b/tss-esapi/src/structures/tickets.rs index 6693c618..0cca6381 100644 --- a/tss-esapi/src/structures/tickets.rs +++ b/tss-esapi/src/structures/tickets.rs @@ -130,11 +130,11 @@ pub struct HashcheckTicket { impl Default for HashcheckTicket { /// The default for the Hashcheck ticket is the Null ticket. fn default() -> Self { - return Self { + Self { tag: StructureTag::Hashcheck, hierarchy: Hierarchy::Null, digest: Vec::::new(), - }; + } } } diff --git a/tss-esapi/src/utils/mod.rs b/tss-esapi/src/utils/mod.rs index 151a8258..95639204 100644 --- a/tss-esapi/src/utils/mod.rs +++ b/tss-esapi/src/utils/mod.rs @@ -57,13 +57,9 @@ impl TryFrom for TpmsContext { hierarchy: tss2_context.hierarchy, context_blob: tss2_context.contextBlob.buffer.to_vec(), }; - context.context_blob.truncate( - tss2_context - .contextBlob - .size - .try_into() - .map_err(|_| Error::local_error(WrapperErrorKind::WrongParamSize))?, - ); + context + .context_blob + .truncate(tss2_context.contextBlob.size.into()); Ok(context) } }