From 08dc99a3135961ba91243f83fa9586d66903921a Mon Sep 17 00:00:00 2001 From: Jesper Brynolf Date: Wed, 2 Aug 2023 22:32:35 +0200 Subject: [PATCH] Improves tests for tagged schemes. - Adds a file for tests for each individual tagged scheme and adds more tests for each type in ```tss-esapi/src/structures/tagged/schemes.rs```. - Adds missing support for `Hmac` variant when using `signing_scheme` and `set_signing_scheme` methods. - Changes name of variable holding the signing scheme. - Refactors the tagged signature scheme tests. Signed-off-by: Jesper Brynolf --- tss-esapi/src/structures/schemes.rs | 5 + tss-esapi/src/structures/tagged/schemes.rs | 285 ++++++++++----- .../common/tpm2b_types_equality_checks.rs | 2 +- .../common/tpms_types_equality_checks.rs | 15 +- .../common/tpmt_types_equality_checks.rs | 71 +++- .../attestation_commands_tests.rs | 2 +- .../symmetric_tests/sensitive_create_tests.rs | 2 +- .../structures_tests/tagged_tests/mod.rs | 5 + .../tagged_tests/tagged_ecc_scheme_tests.rs | 258 +++++++++++++ ...ed_key_derivation_function_scheme_tests.rs | 68 ++++ .../tagged_keyed_hash_scheme_tests.rs | 109 ++++++ .../tagged_rsa_decryption_scheme_tests.rs | 158 ++++++++ .../tagged_tests/tagged_rsa_scheme_tests.rs | 144 ++++++++ .../tagged_signature_scheme_tests.rs | 343 +++++++++--------- 14 files changed, 1196 insertions(+), 271 deletions(-) create mode 100644 tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_ecc_scheme_tests.rs create mode 100644 tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_key_derivation_function_scheme_tests.rs create mode 100644 tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_keyed_hash_scheme_tests.rs create mode 100644 tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_rsa_decryption_scheme_tests.rs create mode 100644 tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_rsa_scheme_tests.rs diff --git a/tss-esapi/src/structures/schemes.rs b/tss-esapi/src/structures/schemes.rs index 923787d9..c7940ea6 100644 --- a/tss-esapi/src/structures/schemes.rs +++ b/tss-esapi/src/structures/schemes.rs @@ -52,6 +52,11 @@ impl HmacScheme { pub const fn new(hashing_algorithm: HashingAlgorithm) -> HmacScheme { HmacScheme { hashing_algorithm } } + + /// Returns the hashing algorithm + pub const fn hashing_algorithm(&self) -> HashingAlgorithm { + self.hashing_algorithm + } } impl From for HmacScheme { diff --git a/tss-esapi/src/structures/tagged/schemes.rs b/tss-esapi/src/structures/tagged/schemes.rs index 2b28b945..616c6886 100644 --- a/tss-esapi/src/structures/tagged/schemes.rs +++ b/tss-esapi/src/structures/tagged/schemes.rs @@ -88,10 +88,19 @@ pub enum RsaScheme { impl RsaScheme { /// Creates a new RsaScheme /// + /// # Arguments + /// `rsa_scheme_algorithm` - The [RsaSchemeAlgorithm] associated with variant. + /// `hashing_algorithm` - A hashing algorithm that is required by some of the + /// variants. + /// /// # Errors - /// - `InconsistentParams` error will be returned if no hashing algorithm - /// is provided when creating RSA scheme of type RSA SSA, RSA PSS and OAEP - /// or if a hashing algorithm is provided when creating a RSA scheme + /// `ParamMissing` - If optional parameter is not provided when it is required. + /// I.e. when creating RSA scheme of type RSA SSA, RSA PSS and + /// OAEP. + /// + /// `InconsistentParams` - If the optional parameter has been provided when it is + /// not required. I.e. if a hashing algorithm is provided + /// when creating a the RSA scheme of type Null. pub fn create( rsa_scheme_algorithm: RsaSchemeAlgorithm, hashing_algorithm: Option, @@ -102,38 +111,36 @@ impl RsaScheme { error!( "Hashing algorithm is required when creating RSA scheme of type RSA SSA" ); - Error::local_error(WrapperErrorKind::InconsistentParams) + Error::local_error(WrapperErrorKind::ParamsMissing) })?, ))), RsaSchemeAlgorithm::RsaEs => { - if hashing_algorithm.is_none() { - Ok(RsaScheme::RsaEs) - } else { + if hashing_algorithm.is_some() { error!("A hashing algorithm shall not be provided when creating RSA scheme of type RSA ES"); - Err(Error::local_error(WrapperErrorKind::InconsistentParams)) + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); } + Ok(RsaScheme::RsaEs) } RsaSchemeAlgorithm::RsaPss => Ok(RsaScheme::RsaPss(HashScheme::new( hashing_algorithm.ok_or_else(|| { error!( "Hashing algorithm is required when creating RSA scheme of type RSA PSS" ); - Error::local_error(WrapperErrorKind::InconsistentParams) + Error::local_error(WrapperErrorKind::ParamsMissing) })?, ))), RsaSchemeAlgorithm::Oaep => Ok(RsaScheme::Oaep(HashScheme::new( hashing_algorithm.ok_or_else(|| { error!("Hashing algorithm is required when creating RSA scheme of type OAEP"); - Error::local_error(WrapperErrorKind::InconsistentParams) + Error::local_error(WrapperErrorKind::ParamsMissing) })?, ))), RsaSchemeAlgorithm::Null => { - if hashing_algorithm.is_none() { - Ok(RsaScheme::Null) - } else { + if hashing_algorithm.is_some() { error!("A hashing algorithm shall not be provided when creating RSA scheme of type Null"); - Err(Error::local_error(WrapperErrorKind::InconsistentParams)) + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); } + Ok(RsaScheme::Null) } } } @@ -223,61 +230,130 @@ pub enum EccScheme { } impl EccScheme { + /// Creates a EccScheme. + /// + /// # Arguments + /// `ecc_scheme_algorithm` - The ECC scheme algorithm. + /// `hashing_algorithm` - The hashing algorithm associated with some variants. + /// `count` - The counter value that is used between TPM2_Commit() and the sign + /// operation used in the EcDaa variant. + /// + /// # Errors + /// `ParamMissing` - If the algorithm indicates a variant that requires + /// one or more of the optional parameters and they have + /// not been provided. + /// + /// `InconsistentParams` - If an optional parameter has been set but it is + /// not required. pub fn create( ecc_scheme_algorithm: EccSchemeAlgorithm, hashing_algorithm: Option, count: Option, ) -> Result { match ecc_scheme_algorithm { - EccSchemeAlgorithm::EcDsa => Ok(EccScheme::EcDsa(HashScheme::new( - hashing_algorithm.ok_or_else(|| { - error!("Hashing algorithm is required when creating ECC scheme of type EC DSA"); - Error::local_error(WrapperErrorKind::ParamsMissing) - })?, - ))), - EccSchemeAlgorithm::EcDh => Ok(EccScheme::EcDh(HashScheme::new( - hashing_algorithm.ok_or_else(|| { - error!("Hashing algorithm is required when creating ECC scheme of type EC DH"); - Error::local_error(WrapperErrorKind::ParamsMissing) - })?, - ))), + EccSchemeAlgorithm::EcDsa => { + if count.is_some() { + error!( + "`count` should not be provided when creating ECC scheme of type EC DSA." + ); + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); + } + + hashing_algorithm + .ok_or_else(|| { + error!( + "Hashing algorithm is required when creating ECC scheme of type EC DSA." + ); + Error::local_error(WrapperErrorKind::ParamsMissing) + }) + .map(|v| EccScheme::EcDsa(HashScheme::new(v))) + } + EccSchemeAlgorithm::EcDh => { + if count.is_some() { + error!( + "`count` should not be provided when creating ECC scheme of type EC DH." + ); + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); + } + + hashing_algorithm + .ok_or_else(|| { + error!( + "Hashing algorithm is required when creating ECC scheme of type EC DH." + ); + Error::local_error(WrapperErrorKind::ParamsMissing) + }) + .map(|v| EccScheme::EcDh(HashScheme::new(v))) + } EccSchemeAlgorithm::EcDaa => Ok(EccScheme::EcDaa(EcDaaScheme::new( hashing_algorithm.ok_or_else(|| { - error!("Hashing algorithm is required when creating ECC scheme of type EC DAA"); + error!( + "Hashing algorithm is required when creating ECC scheme of type EC DAA." + ); Error::local_error(WrapperErrorKind::ParamsMissing) })?, count.ok_or_else(|| { - error!("Count is required when creating ECC scheme of type EC DAA"); + error!("Count is required when creating ECC scheme of type EC DAA."); Error::local_error(WrapperErrorKind::ParamsMissing) })?, ))), - EccSchemeAlgorithm::Sm2 => Ok(EccScheme::Sm2(HashScheme::new( - hashing_algorithm.ok_or_else(|| { - error!("Hashing algorithm is required when creating ECC scheme of type EC SM2"); - Error::local_error(WrapperErrorKind::ParamsMissing) - })?, - ))), - EccSchemeAlgorithm::EcSchnorr => Ok(EccScheme::EcSchnorr(HashScheme::new( - hashing_algorithm.ok_or_else(|| { + EccSchemeAlgorithm::Sm2 => { + if count.is_some() { + error!("`count` should not be provided when creating ECC scheme of type SM2."); + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); + } + + hashing_algorithm + .ok_or_else(|| { + error!( + "Hashing algorithm is required when creating ECC scheme of type SM2." + ); + Error::local_error(WrapperErrorKind::ParamsMissing) + }) + .map(|v| EccScheme::Sm2(HashScheme::new(v))) + } + EccSchemeAlgorithm::EcSchnorr => { + if count.is_some() { + error!("`count` should not be provided when creating ECC scheme of type EC SCHNORR."); + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); + } + + hashing_algorithm + .ok_or_else(|| { + error!( + "Hashing algorithm is required when creating ECC scheme of type EC SCHNORR." + ); + Error::local_error(WrapperErrorKind::ParamsMissing) + }) + .map(|v| EccScheme::EcSchnorr(HashScheme::new(v))) + } + EccSchemeAlgorithm::EcMqv => { + if count.is_some() { error!( - "Hashing algorithm is required when creating ECC scheme of type EC SCHNORR" + "`count` should not be provided when creating ECC scheme of type EC MQV." ); - Error::local_error(WrapperErrorKind::ParamsMissing) - })?, - ))), - EccSchemeAlgorithm::EcMqv => Ok(EccScheme::EcMqv(HashScheme::new( - hashing_algorithm.ok_or_else(|| { - error!("Hashing algorithm is required when creating ECC scheme of type EC MQV"); - Error::local_error(WrapperErrorKind::ParamsMissing) - })?, - ))), + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); + } + + hashing_algorithm + .ok_or_else(|| { + error!( + "Hashing algorithm is required when creating ECC scheme of type EC MQV." + ); + Error::local_error(WrapperErrorKind::ParamsMissing) + }) + .map(|v| EccScheme::EcMqv(HashScheme::new(v))) + } EccSchemeAlgorithm::Null => { - if hashing_algorithm.is_none() { - Ok(EccScheme::Null) - } else { - error!("A hashing algorithm shall not be provided when creating ECC scheme of type Null"); - Err(Error::local_error(WrapperErrorKind::InconsistentParams)) + if count.is_some() { + error!("`count` should not be provided when creating ECC scheme of type Null."); + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); + } + if hashing_algorithm.is_some() { + error!("A hashing algorithm shall not be provided when creating ECC scheme of type Null."); + return Err(Error::local_error(WrapperErrorKind::InconsistentParams)); } + Ok(EccScheme::Null) } } } @@ -445,7 +521,7 @@ impl TryFrom for KeyDerivationFunctionScheme { /// /// # Details /// This corresponds to TPMT_RSA_DECRYPT. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RsaDecryptionScheme { RsaEs, Oaep(HashScheme), @@ -453,7 +529,15 @@ pub enum RsaDecryptionScheme { } impl RsaDecryptionScheme { - /// Creates a new rsa decrypt scheme + /// Creates a new rsa decrypt scheme. + /// + /// # Arguments + /// `rsa_decrypt_algorithm` - The RSA decryption algorithm. + /// `hashing_algorithm` - The hashing algorithm used in some variants of the scheme. + /// + /// # Errors + /// `InconsistentParams` - If a parameter has been provided when it is not required. + /// `ParamsMissing` - If a required parameter has not been provided. pub fn create( rsa_decrypt_algorithm: RsaDecryptAlgorithm, hashing_algorithm: Option, @@ -550,13 +634,13 @@ impl TryFrom for RsaDecryptionScheme { /// Corresponds to `TPMT_SIG_SCHEME`. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum SignatureScheme { - RsaSsa { hash_scheme: HashScheme }, - RsaPss { hash_scheme: HashScheme }, - EcDsa { hash_scheme: HashScheme }, - Sm2 { hash_scheme: HashScheme }, - EcSchnorr { hash_scheme: HashScheme }, - EcDaa { ecdaa_scheme: EcDaaScheme }, - Hmac { hmac_scheme: HmacScheme }, + RsaSsa { scheme: HashScheme }, + RsaPss { scheme: HashScheme }, + EcDsa { scheme: HashScheme }, + Sm2 { scheme: HashScheme }, + EcSchnorr { scheme: HashScheme }, + EcDaa { scheme: EcDaaScheme }, + Hmac { scheme: HmacScheme }, Null, } @@ -565,19 +649,20 @@ impl SignatureScheme { /// /// # Details /// This is intended to provide the functionality of reading - /// from the ```anySig``` field in the TPMU_SIG_SCHEME union. + /// from the `any` field in the TPMU_SIG_SCHEME union. /// /// # Errors /// Returns an InvalidParam error if the trying to read from /// SignatureScheme that is not a signing scheme. pub fn signing_scheme(&self) -> Result { match self { - SignatureScheme::RsaSsa { hash_scheme } - | SignatureScheme::RsaPss { hash_scheme } - | SignatureScheme::EcDsa { hash_scheme } - | SignatureScheme::Sm2 { hash_scheme } - | SignatureScheme::EcSchnorr { hash_scheme } => Ok(hash_scheme.hashing_algorithm()), - SignatureScheme::EcDaa { ecdaa_scheme } => Ok(ecdaa_scheme.hashing_algorithm()), + SignatureScheme::RsaSsa { scheme } + | SignatureScheme::RsaPss { scheme } + | SignatureScheme::EcDsa { scheme } + | SignatureScheme::Sm2 { scheme } + | SignatureScheme::EcSchnorr { scheme } => Ok(scheme.hashing_algorithm()), + SignatureScheme::EcDaa { scheme } => Ok(scheme.hashing_algorithm()), + SignatureScheme::Hmac { scheme } => Ok(scheme.hashing_algorithm()), _ => { error!("Cannot access digest for a non signing scheme"); Err(Error::local_error(WrapperErrorKind::InvalidParam)) @@ -589,23 +674,27 @@ impl SignatureScheme { /// /// # Details /// This is intended to provide the functionality of writing - /// to the ```anySig``` field in the TPMU_SIG_SCHEME union. + /// to the `any` field in the TPMU_SIG_SCHEME union. /// /// # Errors /// Returns an InvalidParam error if the trying to read from /// SignatureScheme that is not a signing scheme. pub fn set_signing_scheme(&mut self, hashing_algorithm: HashingAlgorithm) -> Result<()> { match self { - SignatureScheme::RsaSsa { hash_scheme } - | SignatureScheme::RsaPss { hash_scheme } - | SignatureScheme::EcDsa { hash_scheme } - | SignatureScheme::Sm2 { hash_scheme } - | SignatureScheme::EcSchnorr { hash_scheme } => { - *hash_scheme = HashScheme::new(hashing_algorithm); + SignatureScheme::RsaSsa { scheme } + | SignatureScheme::RsaPss { scheme } + | SignatureScheme::EcDsa { scheme } + | SignatureScheme::Sm2 { scheme } + | SignatureScheme::EcSchnorr { scheme } => { + *scheme = HashScheme::new(hashing_algorithm); + Ok(()) + } + SignatureScheme::EcDaa { scheme } => { + *scheme = EcDaaScheme::new(hashing_algorithm, scheme.count()); Ok(()) } - SignatureScheme::EcDaa { ecdaa_scheme } => { - *ecdaa_scheme = EcDaaScheme::new(hashing_algorithm, ecdaa_scheme.count()); + SignatureScheme::Hmac { scheme } => { + *scheme = HmacScheme::new(hashing_algorithm); Ok(()) } _ => { @@ -619,51 +708,49 @@ impl SignatureScheme { impl From for TPMT_SIG_SCHEME { fn from(native: SignatureScheme) -> TPMT_SIG_SCHEME { match native { - SignatureScheme::EcDaa { ecdaa_scheme } => TPMT_SIG_SCHEME { + SignatureScheme::EcDaa { scheme } => TPMT_SIG_SCHEME { scheme: SignatureSchemeAlgorithm::EcDaa.into(), details: TPMU_SIG_SCHEME { - ecdaa: ecdaa_scheme.into(), + ecdaa: scheme.into(), }, }, - SignatureScheme::EcDsa { hash_scheme } => TPMT_SIG_SCHEME { + SignatureScheme::EcDsa { scheme } => TPMT_SIG_SCHEME { scheme: SignatureSchemeAlgorithm::EcDsa.into(), details: TPMU_SIG_SCHEME { - ecdsa: hash_scheme.into(), + ecdsa: scheme.into(), }, }, - SignatureScheme::EcSchnorr { hash_scheme } => TPMT_SIG_SCHEME { + SignatureScheme::EcSchnorr { scheme } => TPMT_SIG_SCHEME { scheme: SignatureSchemeAlgorithm::EcSchnorr.into(), details: TPMU_SIG_SCHEME { - ecschnorr: hash_scheme.into(), + ecschnorr: scheme.into(), }, }, - SignatureScheme::Hmac { hmac_scheme } => TPMT_SIG_SCHEME { + SignatureScheme::Hmac { scheme } => TPMT_SIG_SCHEME { scheme: SignatureSchemeAlgorithm::Hmac.into(), details: TPMU_SIG_SCHEME { - hmac: hmac_scheme.into(), + hmac: scheme.into(), }, }, SignatureScheme::Null => TPMT_SIG_SCHEME { scheme: SignatureSchemeAlgorithm::Null.into(), details: Default::default(), }, - SignatureScheme::RsaPss { hash_scheme } => TPMT_SIG_SCHEME { + SignatureScheme::RsaPss { scheme } => TPMT_SIG_SCHEME { scheme: SignatureSchemeAlgorithm::RsaPss.into(), details: TPMU_SIG_SCHEME { - rsapss: hash_scheme.into(), + rsapss: scheme.into(), }, }, - SignatureScheme::RsaSsa { hash_scheme } => TPMT_SIG_SCHEME { + SignatureScheme::RsaSsa { scheme } => TPMT_SIG_SCHEME { scheme: SignatureSchemeAlgorithm::RsaSsa.into(), details: TPMU_SIG_SCHEME { - rsassa: hash_scheme.into(), + rsassa: scheme.into(), }, }, - SignatureScheme::Sm2 { hash_scheme } => TPMT_SIG_SCHEME { + SignatureScheme::Sm2 { scheme } => TPMT_SIG_SCHEME { scheme: SignatureSchemeAlgorithm::Sm2.into(), - details: TPMU_SIG_SCHEME { - sm2: hash_scheme.into(), - }, + details: TPMU_SIG_SCHEME { sm2: scheme.into() }, }, } } @@ -675,26 +762,26 @@ impl TryFrom for SignatureScheme { fn try_from(tss: TPMT_SIG_SCHEME) -> Result { match SignatureSchemeAlgorithm::try_from(tss.scheme)? { SignatureSchemeAlgorithm::EcDaa => Ok(SignatureScheme::EcDaa { - ecdaa_scheme: unsafe { tss.details.ecdaa }.try_into()?, + scheme: unsafe { tss.details.ecdaa }.try_into()?, }), SignatureSchemeAlgorithm::EcDsa => Ok(SignatureScheme::EcDsa { - hash_scheme: unsafe { tss.details.ecdsa }.try_into()?, + scheme: unsafe { tss.details.ecdsa }.try_into()?, }), SignatureSchemeAlgorithm::EcSchnorr => Ok(SignatureScheme::EcSchnorr { - hash_scheme: unsafe { tss.details.ecschnorr }.try_into()?, + scheme: unsafe { tss.details.ecschnorr }.try_into()?, }), SignatureSchemeAlgorithm::Hmac => Ok(SignatureScheme::Hmac { - hmac_scheme: unsafe { tss.details.hmac }.try_into()?, + scheme: unsafe { tss.details.hmac }.try_into()?, }), SignatureSchemeAlgorithm::Null => Ok(SignatureScheme::Null), SignatureSchemeAlgorithm::RsaPss => Ok(SignatureScheme::RsaPss { - hash_scheme: unsafe { tss.details.rsapss }.try_into()?, + scheme: unsafe { tss.details.rsapss }.try_into()?, }), SignatureSchemeAlgorithm::RsaSsa => Ok(SignatureScheme::RsaSsa { - hash_scheme: unsafe { tss.details.rsassa }.try_into()?, + scheme: unsafe { tss.details.rsassa }.try_into()?, }), SignatureSchemeAlgorithm::Sm2 => Ok(SignatureScheme::Sm2 { - hash_scheme: unsafe { tss.details.sm2 }.try_into()?, + scheme: unsafe { tss.details.sm2 }.try_into()?, }), } } diff --git a/tss-esapi/tests/integration_tests/common/tpm2b_types_equality_checks.rs b/tss-esapi/tests/integration_tests/common/tpm2b_types_equality_checks.rs index 09e505ea..c923c62c 100644 --- a/tss-esapi/tests/integration_tests/common/tpm2b_types_equality_checks.rs +++ b/tss-esapi/tests/integration_tests/common/tpm2b_types_equality_checks.rs @@ -58,5 +58,5 @@ pub fn ensure_tpm2b_sensitive_create_equality( expected.size, actual.size, "'size' value in TPM2B_SENSITIVE_CREATE, mismatch between actual and expected", ); - crate::common::ensure_tpms_sensitive_create(&expected.sensitive, &actual.sensitive); + crate::common::ensure_tpms_sensitive_create_equality(&expected.sensitive, &actual.sensitive); } diff --git a/tss-esapi/tests/integration_tests/common/tpms_types_equality_checks.rs b/tss-esapi/tests/integration_tests/common/tpms_types_equality_checks.rs index fde77723..da9bef78 100644 --- a/tss-esapi/tests/integration_tests/common/tpms_types_equality_checks.rs +++ b/tss-esapi/tests/integration_tests/common/tpms_types_equality_checks.rs @@ -7,9 +7,9 @@ use tss_esapi::{ }, tss2_esys::{ TPMS_ALG_PROPERTY, TPMS_ATTEST, TPMS_CERTIFY_INFO, TPMS_CLOCK_INFO, - TPMS_COMMAND_AUDIT_INFO, TPMS_CREATION_INFO, TPMS_ECC_PARMS, TPMS_KEYEDHASH_PARMS, - TPMS_NV_CERTIFY_INFO, TPMS_PCR_SELECTION, TPMS_QUOTE_INFO, TPMS_RSA_PARMS, - TPMS_SCHEME_ECDAA, TPMS_SCHEME_HASH, TPMS_SCHEME_HMAC, TPMS_SCHEME_XOR, + TPMS_COMMAND_AUDIT_INFO, TPMS_CREATION_INFO, TPMS_ECC_PARMS, TPMS_EMPTY, + TPMS_KEYEDHASH_PARMS, TPMS_NV_CERTIFY_INFO, TPMS_PCR_SELECTION, TPMS_QUOTE_INFO, + TPMS_RSA_PARMS, TPMS_SCHEME_ECDAA, TPMS_SCHEME_HASH, TPMS_SCHEME_HMAC, TPMS_SCHEME_XOR, TPMS_SENSITIVE_CREATE, TPMS_SESSION_AUDIT_INFO, TPMS_SYMCIPHER_PARMS, TPMS_TAGGED_PCR_SELECT, TPMS_TAGGED_PROPERTY, TPMS_TIME_ATTEST_INFO, TPMS_TIME_INFO, }, @@ -302,10 +302,17 @@ pub fn ensure_tpms_symcipher_parms_equality( crate::common::ensure_tpmt_sym_def_object_equality(&expected.sym, &actual.sym) } -pub fn ensure_tpms_sensitive_create( +pub fn ensure_tpms_sensitive_create_equality( expected: &TPMS_SENSITIVE_CREATE, actual: &TPMS_SENSITIVE_CREATE, ) { crate::common::ensure_tpm2b_auth_equality(&expected.userAuth, &actual.userAuth); crate::common::ensure_tpm2b_sensitive_data(&expected.data, &actual.data); } + +pub fn ensure_tpms_empty_equality(expected: &TPMS_EMPTY, actual: &TPMS_EMPTY) { + assert_eq!( + expected.empty, actual.empty, + "'empty' value TPMS_EMPTY, mismatch between actual and expected." + ); +} diff --git a/tss-esapi/tests/integration_tests/common/tpmt_types_equality_checks.rs b/tss-esapi/tests/integration_tests/common/tpmt_types_equality_checks.rs index 8b417e1d..2d7342ca 100644 --- a/tss-esapi/tests/integration_tests/common/tpmt_types_equality_checks.rs +++ b/tss-esapi/tests/integration_tests/common/tpmt_types_equality_checks.rs @@ -10,7 +10,7 @@ use tss_esapi::{ }, tss2_esys::{ TPMT_ECC_SCHEME, TPMT_KDF_SCHEME, TPMT_KEYEDHASH_SCHEME, TPMT_PUBLIC_PARMS, - TPMT_RSA_SCHEME, TPMT_SYM_DEF, TPMT_SYM_DEF_OBJECT, + TPMT_RSA_DECRYPT, TPMT_RSA_SCHEME, TPMT_SIG_SCHEME, TPMT_SYM_DEF, TPMT_SYM_DEF_OBJECT, }, }; @@ -336,3 +336,72 @@ pub fn ensure_tpmt_kdf_scheme_equality(expected: &TPMT_KDF_SCHEME, actual: &TPMT _ => panic!("Invalid algorithm in TPMT_KDF_SCHEME"), } } + +pub fn ensure_tpmt_rsa_decrypt_equality(expected: &TPMT_RSA_DECRYPT, actual: &TPMT_RSA_DECRYPT) { + assert_eq!( + expected.scheme, actual.scheme, + "'scheme' value in TPMT_RSA_DECRYPT, mismatch between actual and expected", + ); + + match expected.scheme { + TPM2_ALG_RSAES => { + let expected_scheme = unsafe { &expected.details.rsaes }; + let actual_scheme = unsafe { &actual.details.rsaes }; + crate::common::ensure_tpms_empty_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_OAEP => { + let expected_scheme = unsafe { &expected.details.oaep }; + let actual_scheme = unsafe { &actual.details.oaep }; + crate::common::ensure_tpms_scheme_hash_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_NULL => {} + _ => panic!("Invalid algorithm in TPMT_RSA_DECRYPT"), + } +} + +pub fn ensure_tpmt_sig_scheme_equality(expected: &TPMT_SIG_SCHEME, actual: &TPMT_SIG_SCHEME) { + assert_eq!( + expected.scheme, actual.scheme, + "'scheme' value in TPMT_SIG_SCHEME, mismatch between actual and expected", + ); + + match expected.scheme { + TPM2_ALG_RSASSA => { + let expected_scheme = unsafe { &expected.details.rsassa }; + let actual_scheme = unsafe { &actual.details.rsassa }; + crate::common::ensure_tpms_scheme_hash_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_RSAPSS => { + let expected_scheme = unsafe { &expected.details.rsapss }; + let actual_scheme = unsafe { &actual.details.rsapss }; + crate::common::ensure_tpms_scheme_hash_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_ECDSA => { + let expected_scheme = unsafe { &expected.details.ecdsa }; + let actual_scheme = unsafe { &actual.details.ecdsa }; + crate::common::ensure_tpms_scheme_hash_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_SM2 => { + let expected_scheme = unsafe { &expected.details.sm2 }; + let actual_scheme = unsafe { &actual.details.sm2 }; + crate::common::ensure_tpms_scheme_hash_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_ECSCHNORR => { + let expected_scheme = unsafe { &expected.details.ecschnorr }; + let actual_scheme = unsafe { &actual.details.ecschnorr }; + crate::common::ensure_tpms_scheme_hash_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_ECDAA => { + let expected_scheme = unsafe { &expected.details.ecdaa }; + let actual_scheme = unsafe { &actual.details.ecdaa }; + crate::common::ensure_tpms_scheme_ecdaa_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_HMAC => { + let expected_scheme = unsafe { &expected.details.hmac }; + let actual_scheme = unsafe { &actual.details.hmac }; + crate::common::ensure_tpms_scheme_hmac_equality(expected_scheme, actual_scheme); + } + TPM2_ALG_NULL => {} + _ => panic!("Invalid algorithm in TPMT_SIG_SCHEME"), + } +} diff --git a/tss-esapi/tests/integration_tests/context_tests/tpm_commands/attestation_commands_tests.rs b/tss-esapi/tests/integration_tests/context_tests/tpm_commands/attestation_commands_tests.rs index 34c17f53..1590ad44 100644 --- a/tss-esapi/tests/integration_tests/context_tests/tpm_commands/attestation_commands_tests.rs +++ b/tss-esapi/tests/integration_tests/context_tests/tpm_commands/attestation_commands_tests.rs @@ -131,7 +131,7 @@ mod test_quote { let mut context = create_ctx_with_session(); let qualifying_data = vec![0xff; 16]; let sign_scheme = SignatureScheme::RsaPss { - hash_scheme: HashScheme::new(HashingAlgorithm::Sha256), + scheme: HashScheme::new(HashingAlgorithm::Sha256), }; let obj_key_handle = context diff --git a/tss-esapi/tests/integration_tests/structures_tests/algorithm_tests/symmetric_tests/sensitive_create_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/algorithm_tests/symmetric_tests/sensitive_create_tests.rs index 18c358e5..8d27baf8 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/algorithm_tests/symmetric_tests/sensitive_create_tests.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/algorithm_tests/symmetric_tests/sensitive_create_tests.rs @@ -51,7 +51,7 @@ fn test_tpms_sensitive_create_conversions() { "data() did not return expected value" ); let actual_tpms_sensitive_create: TPMS_SENSITIVE_CREATE = sensitive_create.into(); - crate::common::ensure_tpms_sensitive_create( + crate::common::ensure_tpms_sensitive_create_equality( &expected_tpms_sensitive_create, &actual_tpms_sensitive_create, ); diff --git a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/mod.rs b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/mod.rs index 8db1bce3..2a1014ab 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/mod.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/mod.rs @@ -9,4 +9,9 @@ mod sensitive; mod signature; mod symmetric_definition_object_tests; mod symmetric_definition_tests; +mod tagged_ecc_scheme_tests; +mod tagged_key_derivation_function_scheme_tests; +mod tagged_keyed_hash_scheme_tests; +mod tagged_rsa_decryption_scheme_tests; +mod tagged_rsa_scheme_tests; mod tagged_signature_scheme_tests; diff --git a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_ecc_scheme_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_ecc_scheme_tests.rs new file mode 100644 index 00000000..a2455978 --- /dev/null +++ b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_ecc_scheme_tests.rs @@ -0,0 +1,258 @@ +// Copyright 2023 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +use std::convert::TryFrom; +use tss_esapi::{ + constants::AlgorithmIdentifier, + error::{Error, WrapperErrorKind}, + interface_types::algorithm::{EccSchemeAlgorithm, HashingAlgorithm}, + structures::{EcDaaScheme, EccScheme, HashScheme}, + tss2_esys::{TPMT_ECC_SCHEME, TPMU_ASYM_SCHEME}, +}; + +macro_rules! assert_create_ok { + (EccSchemeAlgorithm::$scheme_alg_item:ident, HashingAlgorithm::$hash_alg:ident, $count_expr:expr) => { + assert_create_ok!( + EccSchemeAlgorithm::$scheme_alg_item, + Some(HashingAlgorithm::$hash_alg), + Some($count_expr) + ); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident, HashingAlgorithm::$hash_alg:ident) => { + assert_create_ok!( + EccSchemeAlgorithm::$scheme_alg_item, + Some(HashingAlgorithm::$hash_alg), + None:: + ); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident) => { + assert_create_ok!( + EccSchemeAlgorithm::$scheme_alg_item, + None::, + None:: + ); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident, $hash_alg_expr:expr, $count_expr:expr) => { + assert!(EccScheme::create( + EccSchemeAlgorithm::$scheme_alg_item, + $hash_alg_expr, + $count_expr + ) + .is_ok()); + }; +} + +#[test] +fn test_create_associated_function() { + assert_create_ok!(EccSchemeAlgorithm::EcDsa, HashingAlgorithm::Sha256); + assert_create_ok!(EccSchemeAlgorithm::EcDh, HashingAlgorithm::Sha256); + assert_create_ok!(EccSchemeAlgorithm::EcDaa, HashingAlgorithm::Sha256, 1u16); + assert_create_ok!(EccSchemeAlgorithm::Sm2, HashingAlgorithm::Sha256); + assert_create_ok!(EccSchemeAlgorithm::EcSchnorr, HashingAlgorithm::Sha256); + assert_create_ok!(EccSchemeAlgorithm::EcMqv, HashingAlgorithm::Sha256); + assert_create_ok!(EccSchemeAlgorithm::Null); +} + +macro_rules! assert_error { + (EccSchemeAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident, HashingAlgorithm::$hash_alg:ident, $count_expr:expr) => { + assert_error!(EccSchemeAlgorithm::$scheme_alg_item, WrapperErrorKind::$error_kind, Some(HashingAlgorithm::$hash_alg), Some($count_expr)); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident, HashingAlgorithm::$hash_alg:ident) => { + assert_error!(EccSchemeAlgorithm::$scheme_alg_item, WrapperErrorKind::$error_kind, Some(HashingAlgorithm::$hash_alg), None::); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident, $count_expr:expr) => { + assert_error!(EccSchemeAlgorithm::$scheme_alg_item, WrapperErrorKind::$error_kind, None::, Some($count_expr)); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident) => { + assert_error!(EccSchemeAlgorithm::$scheme_alg_item, WrapperErrorKind::$error_kind, None::, None::); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident, $hash_alg_expr:expr, $count_expr:expr) => { + let scheme_alg = EccSchemeAlgorithm::$scheme_alg_item; + let hash_alg = $hash_alg_expr; + let count = $count_expr; + if let Err(actual_error) = EccScheme::create(scheme_alg, hash_alg, count) { + assert_eq!( + Error::WrapperError(WrapperErrorKind::$error_kind), + actual_error + ); + } else { + panic!( + "Calling `create` function in `{}` with invalid input({:?}, {:?}, {:?}) did not produce an error.", + std::any::type_name::(), scheme_alg, hash_alg, count, + ); + } + } +} + +#[test] +fn test_create_associated_function_with_invalid_input() { + assert_error!(EccSchemeAlgorithm::EcDsa, WrapperErrorKind::ParamsMissing); + assert_error!( + EccSchemeAlgorithm::EcDsa, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha256, + 1u16 + ); + assert_error!(EccSchemeAlgorithm::EcDh, WrapperErrorKind::ParamsMissing); + assert_error!( + EccSchemeAlgorithm::EcDh, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha256, + 1u16 + ); + assert_error!(EccSchemeAlgorithm::EcDaa, WrapperErrorKind::ParamsMissing); + assert_error!( + EccSchemeAlgorithm::EcDaa, + WrapperErrorKind::ParamsMissing, + HashingAlgorithm::Sha256 + ); + assert_error!( + EccSchemeAlgorithm::EcDaa, + WrapperErrorKind::ParamsMissing, + 1u16 + ); + assert_error!(EccSchemeAlgorithm::Sm2, WrapperErrorKind::ParamsMissing); + assert_error!( + EccSchemeAlgorithm::Sm2, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha256, + 1u16 + ); + assert_error!( + EccSchemeAlgorithm::EcSchnorr, + WrapperErrorKind::ParamsMissing + ); + assert_error!( + EccSchemeAlgorithm::EcSchnorr, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha256, + 1u16 + ); + assert_error!(EccSchemeAlgorithm::EcMqv, WrapperErrorKind::ParamsMissing); + assert_error!( + EccSchemeAlgorithm::EcMqv, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha256, + 1u16 + ); + + assert_error!( + EccSchemeAlgorithm::Null, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha256 + ); + assert_error!( + EccSchemeAlgorithm::Null, + WrapperErrorKind::InconsistentParams, + 1u16 + ); + assert_error!( + EccSchemeAlgorithm::Null, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha256, + 1u16 + ); +} + +macro_rules! assert_algorithm { + (EccSchemeAlgorithm::$scheme_alg_item:ident, HashingAlgorithm::$hash_alg:ident, $count_expr:expr) => { + assert_algorithm!( + EccSchemeAlgorithm::$scheme_alg_item, + EccScheme::$scheme_alg_item(EcDaaScheme::new(HashingAlgorithm::$hash_alg, $count_expr)) + ); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident, HashingAlgorithm::$hash_alg:ident) => { + assert_algorithm!( + EccSchemeAlgorithm::$scheme_alg_item, + EccScheme::$scheme_alg_item(HashScheme::new(HashingAlgorithm::$hash_alg)) + ); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident) => { + assert_algorithm!( + EccSchemeAlgorithm::$scheme_alg_item, + EccScheme::$scheme_alg_item + ); + }; + (EccSchemeAlgorithm::$scheme_alg_item:ident, $scheme_expr:expr) => { + let actual = $scheme_expr.algorithm(); + let expected = EccSchemeAlgorithm::$scheme_alg_item; + assert_eq!(expected, actual); + }; +} + +#[test] +fn test_algorithm_method() { + assert_algorithm!(EccSchemeAlgorithm::EcDsa, HashingAlgorithm::Sha256); + assert_algorithm!(EccSchemeAlgorithm::EcDh, HashingAlgorithm::Sha256); + assert_algorithm!(EccSchemeAlgorithm::EcDaa, HashingAlgorithm::Sha256, 1u16); + assert_algorithm!(EccSchemeAlgorithm::Sm2, HashingAlgorithm::Sha256); + assert_algorithm!(EccSchemeAlgorithm::EcSchnorr, HashingAlgorithm::Sha256); + assert_algorithm!(EccSchemeAlgorithm::EcMqv, HashingAlgorithm::Sha256); + assert_algorithm!(EccSchemeAlgorithm::Null); +} + +macro_rules! test_conversions { + (EccScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident, $count_expr:expr, $details:ident) => { + test_conversions!( + EccScheme::$scheme_item(EcDaaScheme::new(HashingAlgorithm::$hash_item, $count_expr)), + TPMT_ECC_SCHEME { + scheme: EccSchemeAlgorithm::$scheme_item.into(), + details: TPMU_ASYM_SCHEME { + $details: EcDaaScheme::new(HashingAlgorithm::$hash_item, $count_expr).into(), + } + } + ); + }; + (EccScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident, $details:ident) => { + test_conversions!( + EccScheme::$scheme_item(HashScheme::new(HashingAlgorithm::$hash_item)), + TPMT_ECC_SCHEME { + scheme: EccSchemeAlgorithm::$scheme_item.into(), + details: TPMU_ASYM_SCHEME { + $details: HashScheme::new(HashingAlgorithm::$hash_item).into(), + } + } + ); + }; + (EccScheme::$scheme_item:ident) => { + test_conversions!(EccScheme::$scheme_item, TPMT_ECC_SCHEME { + scheme: EccSchemeAlgorithm::$scheme_item.into(), + details: Default::default(), + }); + }; + ($native:expr, $tss:expr) => { + let expected_native = $native; + let expected_tss = $tss; + + let actual_native = EccScheme::try_from(expected_tss) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a `TPMT_ECC_SCHEME` with valid values into a `{}`.", + std::any::type_name::(), + ); + }); + assert_eq!(expected_native, actual_native); + let actual_tss: TPMT_ECC_SCHEME = expected_native.into(); + crate::common::ensure_tpmt_ecc_scheme_equality(&expected_tss, &actual_tss); + } +} + +#[test] +fn test_valid_conversions() { + test_conversions!(EccScheme::EcDsa, HashingAlgorithm::Sha256, ecdsa); + test_conversions!(EccScheme::EcDh, HashingAlgorithm::Sha256, ecdh); + test_conversions!(EccScheme::EcDaa, HashingAlgorithm::Sha256, 1u16, ecdaa); + test_conversions!(EccScheme::Sm2, HashingAlgorithm::Sha256, sm2); + test_conversions!(EccScheme::EcSchnorr, HashingAlgorithm::Sha256, ecschnorr); + test_conversions!(EccScheme::EcMqv, HashingAlgorithm::Sha256, ecmqv); + test_conversions!(EccScheme::Null); +} + +#[test] +fn test_invalid_conversion() { + let invalid_tss = TPMT_ECC_SCHEME { + scheme: AlgorithmIdentifier::Aes.into(), + details: Default::default(), + }; + + assert!(EccScheme::try_from(invalid_tss).is_err()); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_key_derivation_function_scheme_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_key_derivation_function_scheme_tests.rs new file mode 100644 index 00000000..d8c11afa --- /dev/null +++ b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_key_derivation_function_scheme_tests.rs @@ -0,0 +1,68 @@ +// Copyright 2023 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +use std::convert::TryFrom; +use tss_esapi::{ + interface_types::algorithm::{HashingAlgorithm, KeyDerivationFunction}, + structures::{HashScheme, KeyDerivationFunctionScheme}, + tss2_esys::{TPMT_KDF_SCHEME, TPMU_KDF_SCHEME}, +}; + +macro_rules! test_conversions { + (KeyDerivationFunctionScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident, $details:ident) => { + test_conversions!( + KeyDerivationFunctionScheme::$scheme_item(HashScheme::new(HashingAlgorithm::$hash_item)), + TPMT_KDF_SCHEME { + scheme: KeyDerivationFunction::$scheme_item.into(), + details: TPMU_KDF_SCHEME { + $details: HashScheme::new(HashingAlgorithm::$hash_item).into(), + } + } + ); + }; + (KeyDerivationFunctionScheme::$scheme_item:ident) => { + test_conversions!(KeyDerivationFunctionScheme::$scheme_item, TPMT_KDF_SCHEME { + scheme: KeyDerivationFunction::$scheme_item.into(), + details: Default::default(), + }); + }; + ($native:expr, $tss:expr) => { + let expected_native = $native; + let expected_tss = $tss; + + let actual_native = KeyDerivationFunctionScheme::try_from(expected_tss) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a `TPMT_KDF_SCHEME` with valid values into a `{}`.", + std::any::type_name::(), + ); + }); + assert_eq!(expected_native, actual_native); + let actual_tss: TPMT_KDF_SCHEME = expected_native.into(); + crate::common::ensure_tpmt_kdf_scheme_equality(&expected_tss, &actual_tss); + } +} + +#[test] +fn test_valid_conversions() { + test_conversions!( + KeyDerivationFunctionScheme::Kdf1Sp800_56a, + HashingAlgorithm::Sha3_512, + kdf1_sp800_56a + ); + test_conversions!( + KeyDerivationFunctionScheme::Kdf2, + HashingAlgorithm::Sha3_512, + kdf2 + ); + test_conversions!( + KeyDerivationFunctionScheme::Kdf1Sp800_108, + HashingAlgorithm::Sha3_512, + kdf1_sp800_108 + ); + test_conversions!( + KeyDerivationFunctionScheme::Mgf1, + HashingAlgorithm::Sha3_512, + mgf1 + ); + test_conversions!(KeyDerivationFunctionScheme::Null); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_keyed_hash_scheme_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_keyed_hash_scheme_tests.rs new file mode 100644 index 00000000..fa75a106 --- /dev/null +++ b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_keyed_hash_scheme_tests.rs @@ -0,0 +1,109 @@ +// Copyright 2023 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +use crate::common::ensure_tpmt_keyedhash_scheme_equality; +use std::convert::TryFrom; +use tss_esapi::{ + constants::AlgorithmIdentifier, + error::{Error, WrapperErrorKind}, + interface_types::algorithm::{ + HashingAlgorithm, KeyDerivationFunction, KeyedHashSchemeAlgorithm, + }, + structures::{HmacScheme, KeyedHashScheme, XorScheme}, + tss2_esys::{TPMT_KEYEDHASH_SCHEME, TPMU_SCHEME_KEYEDHASH}, +}; + +#[test] +fn test_keyed_hash_xor_scheme_conversions() { + let algorithm = KeyedHashSchemeAlgorithm::Xor; + let scheme_hashing_algorithm = HashingAlgorithm::Sha384; + let scheme_key_derivation_function = KeyDerivationFunction::Kdf2; + let scheme = XorScheme::new(scheme_hashing_algorithm, scheme_key_derivation_function); + + let expected_native = KeyedHashScheme::Xor { xor_scheme: scheme }; + + let expected_tss = TPMT_KEYEDHASH_SCHEME { + scheme: algorithm.into(), + details: TPMU_SCHEME_KEYEDHASH { + exclusiveOr: scheme.into(), + }, + }; + + let actual_native = KeyedHashScheme::try_from(expected_tss).expect( + "It should be possible to convert a valid `TPMT_KEYEDHASH_SCHEME` into a `KeyedHashScheme`.", + ); + + let actual_tss: TPMT_KEYEDHASH_SCHEME = expected_native.into(); + + assert_eq!(expected_native, actual_native); + ensure_tpmt_keyedhash_scheme_equality(&expected_tss, &actual_tss); +} + +#[test] +fn test_keyed_hash_hmac_scheme_conversions() { + let algorithm = KeyedHashSchemeAlgorithm::Hmac; + let scheme_hashing_algorithm = HashingAlgorithm::Sha384; + let scheme = HmacScheme::new(scheme_hashing_algorithm); + + let expected_native = KeyedHashScheme::Hmac { + hmac_scheme: scheme, + }; + + let expected_tss = TPMT_KEYEDHASH_SCHEME { + scheme: algorithm.into(), + details: TPMU_SCHEME_KEYEDHASH { + hmac: scheme.into(), + }, + }; + + let actual_native = KeyedHashScheme::try_from(expected_tss).expect( + "It should be possible to convert a valid `TPMT_KEYEDHASH_SCHEME` into a `KeyedHashScheme`.", + ); + + let actual_tss: TPMT_KEYEDHASH_SCHEME = expected_native.into(); + + assert_eq!(expected_native, actual_native); + ensure_tpmt_keyedhash_scheme_equality(&expected_tss, &actual_tss); +} + +#[test] +fn test_keyed_hash_null_scheme_conversions() { + let algorithm = KeyedHashSchemeAlgorithm::Null; + + let expected_native = KeyedHashScheme::Null; + + let expected_tss = TPMT_KEYEDHASH_SCHEME { + scheme: algorithm.into(), + details: Default::default(), + }; + + let actual_native = KeyedHashScheme::try_from(expected_tss).expect( + "It should be possible to convert a valid `TPMT_KEYEDHASH_SCHEME` into a `KeyedHashScheme`.", + ); + + let actual_tss: TPMT_KEYEDHASH_SCHEME = expected_native.into(); + + assert_eq!(expected_native, actual_native); + ensure_tpmt_keyedhash_scheme_equality(&expected_tss, &actual_tss); +} + +#[test] +fn test_keyed_hash_scheme_invalid_conversion() { + let invalid_algorithm = AlgorithmIdentifier::Rsa; + let scheme_hashing_algorithm = HashingAlgorithm::Sha384; + let scheme = HmacScheme::new(scheme_hashing_algorithm); + + let invalid_tss = TPMT_KEYEDHASH_SCHEME { + scheme: invalid_algorithm.into(), + details: TPMU_SCHEME_KEYEDHASH { + hmac: scheme.into(), + }, + }; + + let expected_error = Error::WrapperError(WrapperErrorKind::InvalidParam); + + if let Err(actual_error) = KeyedHashScheme::try_from(invalid_tss) { + assert_eq!(expected_error, actual_error); + } else { + panic!("`TPMT_KEYEDHASH_SCHEME` with invalid values did not result in an error when converted to `KeyedHashScheme`."); + }; +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_rsa_decryption_scheme_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_rsa_decryption_scheme_tests.rs new file mode 100644 index 00000000..17f94124 --- /dev/null +++ b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_rsa_decryption_scheme_tests.rs @@ -0,0 +1,158 @@ +// Copyright 2023 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 + +use tss_esapi::{ + error::{Error, WrapperErrorKind}, + interface_types::algorithm::{HashingAlgorithm, RsaDecryptAlgorithm}, + structures::{HashScheme, RsaDecryptionScheme}, + tss2_esys::{TPMT_RSA_DECRYPT, TPMU_ASYM_SCHEME}, +}; + +use std::convert::TryFrom; + +macro_rules! assert_create_ok { + (RsaDecryptAlgorithm::$scheme_alg_item:ident, HashingAlgorithm::$hash_alg:ident) => { + assert_create_ok!( + RsaDecryptAlgorithm::$scheme_alg_item, + Some(HashingAlgorithm::$hash_alg) + ); + }; + (RsaDecryptAlgorithm::$scheme_alg_item:ident) => { + assert_create_ok!( + RsaDecryptAlgorithm::$scheme_alg_item, + None:: + ); + }; + (RsaDecryptAlgorithm::$scheme_alg_item:ident, $hash_alg_expr:expr) => { + assert!( + RsaDecryptionScheme::create(RsaDecryptAlgorithm::$scheme_alg_item, $hash_alg_expr) + .is_ok() + ); + }; +} + +#[test] +fn test_create_associated_function() { + assert_create_ok!(RsaDecryptAlgorithm::RsaEs); + assert_create_ok!(RsaDecryptAlgorithm::Oaep, HashingAlgorithm::Sha3_256); + assert_create_ok!(RsaDecryptAlgorithm::Null); +} + +macro_rules! assert_error { + (RsaDecryptAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident, HashingAlgorithm::$hash_alg:ident) => { + assert_error!(RsaDecryptAlgorithm::$scheme_alg_item, WrapperErrorKind::$error_kind, Some(HashingAlgorithm::$hash_alg)); + }; + (RsaDecryptAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident) => { + assert_error!(RsaDecryptAlgorithm::$scheme_alg_item, WrapperErrorKind::$error_kind, None::); + }; + (RsaDecryptAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident, $hash_alg_expr:expr) => { + let scheme_alg = RsaDecryptAlgorithm::$scheme_alg_item; + let hash_alg = $hash_alg_expr; + if let Err(actual_error) = RsaDecryptionScheme::create(scheme_alg, hash_alg) { + assert_eq!( + Error::WrapperError(WrapperErrorKind::$error_kind), + actual_error + ); + } else { + panic!( + "Calling `create` function in `{}` with invalid input({:?}, {:?}) did not produce an error.", + std::any::type_name::(), scheme_alg, hash_alg, + ); + } + } +} + +#[test] +fn test_create_associated_function_with_invalid_input() { + assert_error!( + RsaDecryptAlgorithm::RsaEs, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha3_384 + ); + assert_error!(RsaDecryptAlgorithm::Oaep, WrapperErrorKind::ParamsMissing); + assert_error!( + RsaDecryptAlgorithm::Null, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha3_384 + ); +} + +macro_rules! assert_algorithm { + (RsaDecryptAlgorithm::$scheme_alg_item:ident, HashingAlgorithm::$hash_alg:ident) => { + assert_algorithm!( + RsaDecryptAlgorithm::$scheme_alg_item, + RsaDecryptionScheme::$scheme_alg_item(HashScheme::new(HashingAlgorithm::$hash_alg)) + ); + }; + (RsaDecryptAlgorithm::$scheme_alg_item:ident) => { + assert_algorithm!( + RsaDecryptAlgorithm::$scheme_alg_item, + RsaDecryptionScheme::$scheme_alg_item + ); + }; + (RsaDecryptAlgorithm::$scheme_alg_item:ident, $scheme_expr:expr) => { + let actual = $scheme_expr.algorithm(); + let expected = RsaDecryptAlgorithm::$scheme_alg_item; + assert_eq!(expected, actual); + }; +} + +#[test] +fn test_algorithm_method() { + assert_algorithm!(RsaDecryptAlgorithm::RsaEs); + assert_algorithm!(RsaDecryptAlgorithm::Oaep, HashingAlgorithm::Sha3_256); + assert_algorithm!(RsaDecryptAlgorithm::Null); +} + +macro_rules! test_conversions { + (RsaDecryptionScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident, $details:ident) => { + test_conversions!( + RsaDecryptionScheme::$scheme_item(HashScheme::new(HashingAlgorithm::$hash_item)), + TPMT_RSA_DECRYPT { + scheme: RsaDecryptAlgorithm::$scheme_item.into(), + details: TPMU_ASYM_SCHEME { + $details: HashScheme::new(HashingAlgorithm::$hash_item).into(), + } + } + ); + }; + (RsaDecryptionScheme::$scheme_item:ident, $details:ident) => { + test_conversions!( + RsaDecryptionScheme::$scheme_item, + TPMT_RSA_DECRYPT { + scheme: RsaDecryptAlgorithm::$scheme_item.into(), + details: TPMU_ASYM_SCHEME { + $details: Default::default() + } + } + ); + }; + (RsaDecryptionScheme::$scheme_item:ident) => { + test_conversions!(RsaDecryptionScheme::$scheme_item, TPMT_RSA_DECRYPT { + scheme: RsaDecryptAlgorithm::$scheme_item.into(), + details: Default::default(), + }); + }; + ($native:expr, $tss:expr) => { + let expected_native = $native; + let expected_tss = $tss; + + let actual_native = RsaDecryptionScheme::try_from(expected_tss) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a `TPMT_RSA_DECRYPT` with valid values into a `{}`.", + std::any::type_name::(), + ); + }); + assert_eq!(expected_native, actual_native); + let actual_tss: TPMT_RSA_DECRYPT = expected_native.into(); + crate::common::ensure_tpmt_rsa_decrypt_equality(&expected_tss, &actual_tss); + } +} + +#[test] +fn test_valid_conversions() { + test_conversions!(RsaDecryptionScheme::RsaEs, rsaes); + test_conversions!(RsaDecryptionScheme::Oaep, HashingAlgorithm::Sha3_256, oaep); + test_conversions!(RsaDecryptionScheme::Null); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_rsa_scheme_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_rsa_scheme_tests.rs new file mode 100644 index 00000000..bc023e16 --- /dev/null +++ b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_rsa_scheme_tests.rs @@ -0,0 +1,144 @@ +// Copyright 2023 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 + +use tss_esapi::{ + constants::AlgorithmIdentifier, + error::{Error, WrapperErrorKind}, + interface_types::algorithm::{HashingAlgorithm, RsaSchemeAlgorithm}, + structures::{HashScheme, RsaScheme}, + tss2_esys::{TPMT_RSA_SCHEME, TPMU_ASYM_SCHEME}, +}; + +use std::convert::TryFrom; + +#[test] +fn test_create_associated_function() { + assert!(RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256)).is_ok()); + assert!(RsaScheme::create(RsaSchemeAlgorithm::RsaEs, None).is_ok()); + assert!(RsaScheme::create(RsaSchemeAlgorithm::RsaPss, Some(HashingAlgorithm::Sha1)).is_ok()); + assert!(RsaScheme::create(RsaSchemeAlgorithm::Oaep, Some(HashingAlgorithm::Sha3_384)).is_ok()); + assert!(RsaScheme::create(RsaSchemeAlgorithm::Null, None).is_ok()); +} + +macro_rules! assert_error { + (RsaSchemeAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident, HashingAlgorithm::$hash_alg:ident) => { + assert_error!(RsaSchemeAlgorithm::$scheme_alg_item, WrapperErrorKind::$error_kind, Some(HashingAlgorithm::$hash_alg)); + }; + (RsaSchemeAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident) => { + assert_error!(RsaSchemeAlgorithm::$scheme_alg_item, WrapperErrorKind::$error_kind, None::); + }; + (RsaSchemeAlgorithm::$scheme_alg_item:ident, WrapperErrorKind::$error_kind:ident, $hash_alg_expr:expr) => { + let scheme_alg = RsaSchemeAlgorithm::$scheme_alg_item; + let hash_alg = $hash_alg_expr; + if let Err(actual_error) = RsaScheme::create(scheme_alg, hash_alg) { + assert_eq!( + Error::WrapperError(WrapperErrorKind::$error_kind), + actual_error + ); + } else { + panic!( + "Calling `create` function in `{}` with invalid input({:?}, {:?}) did not produce an error.", + std::any::type_name::(), scheme_alg, hash_alg, + ); + } + } +} + +#[test] +fn test_create_associated_function_with_invalid_input() { + assert_error!(RsaSchemeAlgorithm::RsaSsa, WrapperErrorKind::ParamsMissing); + assert_error!( + RsaSchemeAlgorithm::RsaEs, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha256 + ); + assert_error!(RsaSchemeAlgorithm::RsaPss, WrapperErrorKind::ParamsMissing); + assert_error!(RsaSchemeAlgorithm::Oaep, WrapperErrorKind::ParamsMissing); + assert_error!( + RsaSchemeAlgorithm::Null, + WrapperErrorKind::InconsistentParams, + HashingAlgorithm::Sha3_256 + ); +} + +macro_rules! assert_algorithm { + (RsaScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident) => { + let scheme = RsaScheme::$scheme_item(HashScheme::new(HashingAlgorithm::$hash_item)); + assert_eq!(RsaSchemeAlgorithm::$scheme_item, scheme.algorithm()); + }; + (RsaScheme::$scheme_item:ident) => { + let scheme = RsaScheme::$scheme_item; + assert_eq!(RsaSchemeAlgorithm::$scheme_item, scheme.algorithm()); + }; +} + +#[test] +fn test_algorithm_method() { + assert_algorithm!(RsaScheme::RsaSsa, HashingAlgorithm::Sha256); + assert_algorithm!(RsaScheme::RsaEs); + assert_algorithm!(RsaScheme::RsaPss, HashingAlgorithm::Sha1); + assert_algorithm!(RsaScheme::Oaep, HashingAlgorithm::Sha3_512); + assert_algorithm!(RsaScheme::Null); +} + +macro_rules! test_conversions { + (RsaScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident, $details:ident) => { + test_conversions!(RsaScheme::$scheme_item(HashScheme::new(HashingAlgorithm::$hash_item)), TPMT_RSA_SCHEME { + scheme: RsaSchemeAlgorithm::$scheme_item.into(), + details: TPMU_ASYM_SCHEME { + $details: HashScheme::new(HashingAlgorithm::$hash_item).into(), + }, + }); + }; + + (RsaScheme::$scheme_item:ident, $details:ident) => { + test_conversions!(RsaScheme::$scheme_item, TPMT_RSA_SCHEME { + scheme: RsaSchemeAlgorithm::$scheme_item.into(), + details: TPMU_ASYM_SCHEME { + $details: Default::default(), + }, + }); + }; + + (RsaScheme::$scheme_item:ident) => { + test_conversions!(RsaScheme::$scheme_item, TPMT_RSA_SCHEME { + scheme: RsaSchemeAlgorithm::$scheme_item.into(), + details: Default::default(), + }); + }; + + ($native:expr, $tss:expr) => { + let expected_native = $native; + let expected_tss = $tss; + + let actual_native = RsaScheme::try_from(expected_tss) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a `TPMT_RSA_SCHEME` with valid values into a `{}`.", + std::any::type_name::(), + ); + }); + assert_eq!(expected_native, actual_native); + let actual_tss: TPMT_RSA_SCHEME = expected_native.into(); + crate::common::ensure_tpmt_rsa_scheme_equality(&expected_tss, &actual_tss); + } +} + +#[test] +fn test_valid_conversions() { + test_conversions!(RsaScheme::RsaSsa, HashingAlgorithm::Sha256, rsassa); + test_conversions!(RsaScheme::RsaEs, rsaes); + test_conversions!(RsaScheme::RsaPss, HashingAlgorithm::Sha512, rsapss); + test_conversions!(RsaScheme::Oaep, HashingAlgorithm::Sm3_256, oaep); + test_conversions!(RsaScheme::Null); +} + +#[test] +fn test_invalid_conversion() { + let invalid_tss = TPMT_RSA_SCHEME { + scheme: AlgorithmIdentifier::Aes.into(), + details: Default::default(), + }; + + assert!(RsaScheme::try_from(invalid_tss).is_err()); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_signature_scheme_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_signature_scheme_tests.rs index ce1b3d21..7b146945 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_signature_scheme_tests.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/tagged_signature_scheme_tests.rs @@ -4,200 +4,215 @@ use tss_esapi::{ interface_types::algorithm::{HashingAlgorithm, SignatureSchemeAlgorithm}, structures::{EcDaaScheme, HashScheme, HmacScheme, SignatureScheme}, - tss2_esys::{ - TPMS_SCHEME_ECDAA, TPMS_SCHEME_HASH, TPMS_SCHEME_HMAC, TPMT_SIG_SCHEME, TPMU_SIG_SCHEME, - }, + tss2_esys::{TPMT_SIG_SCHEME, TPMU_SIG_SCHEME}, Error, WrapperErrorKind, }; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryFrom; -fn validate_tss_hash_scheme( - left: &TPMS_SCHEME_HASH, - right: &TPMS_SCHEME_HASH, - union_field_name: &str, -) { - assert_eq!( - left.hashAlg, right.hashAlg, - "{} in details, hashAlg did not match", - union_field_name - ); +macro_rules! assert_signing_scheme { + (SignatureScheme::$scheme_item:ident, $scheme_type:ty, HashingAlgorithm::$hash_item:ident, $count_expr:expr) => { + assert_signing_scheme!( + SignatureScheme::$scheme_item{scheme: <$scheme_type>::new(HashingAlgorithm::$hash_item, $count_expr)}, + HashingAlgorithm::$hash_item + ); + }; + (SignatureScheme::$scheme_item:ident, $scheme_type:ty, HashingAlgorithm::$hash_item:ident) => { + assert_signing_scheme!( + SignatureScheme::$scheme_item{scheme: <$scheme_type>::new(HashingAlgorithm::$hash_item)}, + HashingAlgorithm::$hash_item + ); + }; + (SignatureScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident) => { + assert_signing_scheme!( + SignatureScheme::$scheme_item{scheme: HashScheme::new(HashingAlgorithm::$hash_item)}, + HashingAlgorithm::$hash_item + ); + }; + ($item_expr:expr, HashingAlgorithm::$hash_item:ident) => { + let item = $item_expr; + let actual = item.signing_scheme().unwrap_or_else(|_| { + panic!( + "A valid {} that contains a scheme should not return an error when calling the `signing_scheme` method.", + std::any::type_name::() + ); + }); + let expected = HashingAlgorithm::$hash_item; + assert_eq!(expected, actual); + } } -fn validate_tss_ecdaa_scheme( - left: &TPMS_SCHEME_ECDAA, - right: &TPMS_SCHEME_ECDAA, - union_field_name: &str, -) { - assert_eq!( - left.hashAlg, right.hashAlg, - "{} in details, hashAlg did not match", - union_field_name - ); - assert_eq!( - left.count, right.count, - "{} in details, count did not match", - union_field_name +#[test] +fn test_signing_scheme_method() { + assert_signing_scheme!(SignatureScheme::RsaSsa, HashingAlgorithm::Sha1); + assert_signing_scheme!(SignatureScheme::RsaPss, HashingAlgorithm::Sha256); + assert_signing_scheme!(SignatureScheme::EcDsa, HashingAlgorithm::Sha512); + assert_signing_scheme!(SignatureScheme::Sm2, HashingAlgorithm::Sha3_256); + assert_signing_scheme!(SignatureScheme::EcSchnorr, HashingAlgorithm::Sha3_384); + assert_signing_scheme!( + SignatureScheme::EcDaa, + EcDaaScheme, + HashingAlgorithm::Sha3_512, + 1u16 ); + assert_signing_scheme!(SignatureScheme::Hmac, HmacScheme, HashingAlgorithm::Sha1); } -fn validate_tss_hmac_scheme( - left: &TPMS_SCHEME_HMAC, - right: &TPMS_SCHEME_HMAC, - union_field_name: &str, -) { - assert_eq!( - left.hashAlg, right.hashAlg, - "{} in details, hashAlg did not match", - union_field_name - ); +macro_rules! assert_signing_scheme_error { + (SignatureScheme::$scheme_item:ident, WrapperErrorKind::$error_kind:ident) => { + if let Err(actual) = SignatureScheme::$scheme_item.signing_scheme() { + let expected = Error::WrapperError(WrapperErrorKind::$error_kind); + assert_eq!(expected, actual); + } else { + panic!( + "Calling `signing_scheme` method on {} object did not produce an error.", + std::stringify!(SignatureScheme::$scheme_item) + ); + } + }; } -macro_rules! test_valid_conversions_generic { - (SignatureScheme::$item:ident, $union_field_name:ident, $tss_details_field_validator:expr, $native_scheme_field:ident, $native_scheme:expr) => { - let tss_actual: TPMT_SIG_SCHEME = SignatureScheme::$item { $native_scheme_field: $native_scheme } - .try_into() - .expect(&format!("Failed to convert {} signature scheem into TSS type", stringify!($item))); - - - let tss_expected = TPMT_SIG_SCHEME { - scheme: SignatureSchemeAlgorithm::$item.into(), - details: TPMU_SIG_SCHEME { - $union_field_name: $native_scheme.into(), - }, - }; +#[test] +fn test_signing_scheme_method_with_invalid_input() { + assert_signing_scheme_error!(SignatureScheme::Null, WrapperErrorKind::InvalidParam); +} - assert_eq!( - tss_actual.scheme, tss_expected.scheme, - "scheme for Actual converted value did not match expected in TSS types for SignatureScheme {}", stringify!($item), +macro_rules! assert_set_signing_scheme { + (SignatureScheme::$scheme_item:ident, $scheme_type:ty, HashingAlgorithm::$hash_item:ident, $count_expr:expr) => { + assert_set_signing_scheme!( + SignatureScheme::$scheme_item{scheme: <$scheme_type>::new(HashingAlgorithm::Sha256, $count_expr)}, + HashingAlgorithm::$hash_item ); - - $tss_details_field_validator( - &unsafe { tss_actual.details.$union_field_name }, - &unsafe { tss_expected.details.$union_field_name }, - stringify!($union_field_name), + }; + (SignatureScheme::$scheme_item:ident, $scheme_type:ty, HashingAlgorithm::$hash_item:ident) => { + assert_set_signing_scheme!( + SignatureScheme::$scheme_item{scheme: <$scheme_type>::new(HashingAlgorithm::Sha256)}, + HashingAlgorithm::$hash_item ); - - let native_expected = SignatureScheme::$item { $native_scheme_field: $native_scheme }; - - let native_actual = SignatureScheme::try_from(tss_expected) - .expect(&format!("Failed to convert TSS type into {}", stringify!($item))); - - assert_eq!( - native_actual, native_expected, - "The actual SignatureScheme did not match expected", + }; + (SignatureScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident) => { + assert_set_signing_scheme!( + SignatureScheme::$scheme_item{scheme: HashScheme::new(HashingAlgorithm::Sha256)}, + HashingAlgorithm::$hash_item ); }; - // For a selector that has no data - (SignatureScheme::$item:ident) => { - let tss_actual: TPMT_SIG_SCHEME = SignatureScheme::$item - .try_into() - .expect(&format!("Failed to convert {} signature scheem into TSS type", stringify!($item))); - - let tss_expected = TPMT_SIG_SCHEME { - scheme: SignatureSchemeAlgorithm::$item.into(), - details: Default::default(), - }; - + ($item_expr:expr, HashingAlgorithm::$hash_item:ident) => { + let mut item = $item_expr; + item.set_signing_scheme(HashingAlgorithm::$hash_item).unwrap_or_else(|_| { + panic!( + "Should be possible to call `set_signing_scheme` method on any {} that is not the Null scheme.", + std::any::type_name::() + ); + }); + let actual = item.signing_scheme().unwrap_or_else(|_| { + panic!( + "A valid {} that contains a scheme should not return an error when calling the `signing_scheme` method.", + std::any::type_name::() + ); + }); + let expected = HashingAlgorithm::$hash_item; assert_eq!( - tss_actual.scheme, tss_expected.scheme, - "scheme for Actual converted value did not match expected in TSS types for SignatureScheme {}", stringify!($item), + expected, + actual, + "Signing scheme mismatch after using `set_signing_scheme` method for {}.", + std::stringify!($item_expr) ); + } +} - let native_expected = SignatureScheme::$item; - let native_actual = SignatureScheme::try_from(tss_expected) - .expect(&format!("Failed to convert TSS type into {}", stringify!($item))); - - assert_eq!( - native_actual, native_expected, - "The actual SignatureScheme did not match expected", - ); - }; +#[test] +fn test_set_signing_scheme_method() { + assert_set_signing_scheme!(SignatureScheme::RsaSsa, HashingAlgorithm::Sha1); + assert_set_signing_scheme!(SignatureScheme::RsaPss, HashingAlgorithm::Sha256); + assert_set_signing_scheme!(SignatureScheme::EcDsa, HashingAlgorithm::Sha512); + assert_set_signing_scheme!(SignatureScheme::Sm2, HashingAlgorithm::Sha3_256); + assert_set_signing_scheme!(SignatureScheme::EcSchnorr, HashingAlgorithm::Sha3_384); + assert_set_signing_scheme!( + SignatureScheme::EcDaa, + EcDaaScheme, + HashingAlgorithm::Sha3_512, + 1u16 + ); + assert_set_signing_scheme!(SignatureScheme::Hmac, HmacScheme, HashingAlgorithm::Sha1); } -macro_rules! test_valid_conversions { - (SignatureScheme::EcDaa, $union_field_name:ident) => { - test_valid_conversions_generic!( - SignatureScheme::EcDaa, - $union_field_name, - validate_tss_ecdaa_scheme, - ecdaa_scheme, - EcDaaScheme::new(HashingAlgorithm::Sha256, 1) - ); - }; - (SignatureScheme::Hmac, $union_field_name:ident) => { - test_valid_conversions_generic!( - SignatureScheme::Hmac, - $union_field_name, - validate_tss_hmac_scheme, - hmac_scheme, - HmacScheme::new(HashingAlgorithm::Sha256) - ); - }; - (SignatureScheme::$item:ident, $union_field_name:ident) => { - test_valid_conversions_generic!( - SignatureScheme::$item, - $union_field_name, - validate_tss_hash_scheme, - hash_scheme, - HashScheme::new(HashingAlgorithm::Sha256) - ); - }; - (SignatureScheme::Null) => { - test_valid_conversions_generic!(SignatureScheme::Null); +macro_rules! assert_set_signing_scheme_error { + (SignatureScheme::$scheme_item:ident, WrapperErrorKind::$error_kind:ident) => { + if let Err(actual) = + SignatureScheme::$scheme_item.set_signing_scheme(HashingAlgorithm::Sha256) + { + let expected = Error::WrapperError(WrapperErrorKind::$error_kind); + assert_eq!(expected, actual); + } else { + panic!( + "Calling `signing_scheme` method on {} object did not produce an error.", + std::stringify!(SignatureScheme::$scheme_item) + ); + } }; } #[test] -fn test_conversions() { - test_valid_conversions!(SignatureScheme::RsaSsa, rsassa); - test_valid_conversions!(SignatureScheme::RsaPss, rsapss); - test_valid_conversions!(SignatureScheme::EcDsa, ecdsa); - test_valid_conversions!(SignatureScheme::Sm2, sm2); - test_valid_conversions!(SignatureScheme::EcSchnorr, ecschnorr); - test_valid_conversions!(SignatureScheme::EcDaa, ecdaa); - test_valid_conversions!(SignatureScheme::Hmac, hmac); - test_valid_conversions!(SignatureScheme::Null); +fn test_set_signing_scheme_method_with_invalid_input() { + assert_set_signing_scheme_error!(SignatureScheme::Null, WrapperErrorKind::InvalidParam); } -#[test] -fn test_valid_any_sig() { - let mut signature_scheme = SignatureScheme::RsaPss { - hash_scheme: HashScheme::new(HashingAlgorithm::Sha256), +macro_rules! test_conversions { + (SignatureScheme::$scheme_item:ident, $scheme_type:ty, HashingAlgorithm::$hash_item:ident, $count_expr:expr, $details:ident) => { + test_conversions!( + SignatureScheme::$scheme_item{scheme: <$scheme_type>::new(HashingAlgorithm::$hash_item, $count_expr)}, + TPMT_SIG_SCHEME { + scheme: SignatureSchemeAlgorithm::$scheme_item.into(), + details: TPMU_SIG_SCHEME { + $details: <$scheme_type>::new(HashingAlgorithm::$hash_item, $count_expr).into() + } + } + ); }; - assert_eq!( - HashingAlgorithm::Sha256, - signature_scheme - .signing_scheme() - .expect("Failed to get signing scheme digest"), - "The signing scheme method did not return the correct value" - ); - - signature_scheme - .set_signing_scheme(HashingAlgorithm::Sha384) - .expect("Failed to change signing scheme digest"); - - assert_eq!( - HashingAlgorithm::Sha384, - signature_scheme - .signing_scheme() - .expect("Failed to get signing key digest"), - "The signing scheme method did not return the correct value after change." - ); + (SignatureScheme::$scheme_item:ident, HashingAlgorithm::$hash_item:ident, $details:ident) => { + test_conversions!( + SignatureScheme::$scheme_item{ scheme: HashScheme::new(HashingAlgorithm::$hash_item) }, + TPMT_SIG_SCHEME { + scheme: SignatureSchemeAlgorithm::$scheme_item.into(), + details: TPMU_SIG_SCHEME { + $details: HashScheme::new(HashingAlgorithm::$hash_item).into() + } + } + ); + }; + ($native:expr, $tss:expr) => { + let expected_native = $native; + let expected_tss = $tss; + + let actual_native = SignatureScheme::try_from(expected_tss) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a `TPMT_SIG_SCHEME` with valid values into a `{}`.", + std::any::type_name::(), + ); + }); + assert_eq!(expected_native, actual_native); + let actual_tss: TPMT_SIG_SCHEME = expected_native.into(); + crate::common::ensure_tpmt_sig_scheme_equality(&expected_tss, &actual_tss); + } } #[test] -fn test_invalid_any_sig() { - let mut signature_scheme = SignatureScheme::Null; - assert_eq!( - Err(Error::WrapperError(WrapperErrorKind::InvalidParam)), - signature_scheme.signing_scheme(), - "Trying to get signing scheme digest from a non signing SignatureScheme did not produce the expected error", +fn test_valid_conversions() { + test_conversions!(SignatureScheme::RsaSsa, HashingAlgorithm::Sha1, rsassa); + test_conversions!(SignatureScheme::RsaPss, HashingAlgorithm::Sha256, rsapss); + test_conversions!(SignatureScheme::EcDsa, HashingAlgorithm::Sha512, ecdsa); + test_conversions!(SignatureScheme::Sm2, HashingAlgorithm::Sha3_256, sm2); + test_conversions!( + SignatureScheme::EcSchnorr, + HashingAlgorithm::Sha3_384, + ecschnorr + ); + test_conversions!( + SignatureScheme::EcDaa, + EcDaaScheme, + HashingAlgorithm::Sha3_512, + 1u16, + ecdaa ); - - assert_eq!( - Err(Error::WrapperError(WrapperErrorKind::InvalidParam)), - signature_scheme.set_signing_scheme(HashingAlgorithm::Sha256), - "Trying to set signing scheme digest on a non signing SignatureScheme did not produce the expected error", - ) }