diff --git a/tss-esapi/src/error/return_code/tpm/format_zero.rs b/tss-esapi/src/error/return_code/tpm/format_zero.rs index d56fdc2e..7ead575d 100644 --- a/tss-esapi/src/error/return_code/tpm/format_zero.rs +++ b/tss-esapi/src/error/return_code/tpm/format_zero.rs @@ -85,7 +85,7 @@ impl std::fmt::Display for TpmFormatZeroResponseCode { match self { TpmFormatZeroResponseCode::Error(e) => e.fmt(f), TpmFormatZeroResponseCode::Warning(e) => e.fmt(f), - TpmFormatZeroResponseCode::VendorSpecific(_) => write!(f, "Vendor specific error"), + TpmFormatZeroResponseCode::VendorSpecific(_) => write!(f, "Vendor specific error."), } } } diff --git a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests.rs b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests.rs new file mode 100644 index 00000000..98dae718 --- /dev/null +++ b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests.rs @@ -0,0 +1,141 @@ +// Copyright 2023 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +mod tpm_format_one_argument_number_tests; +mod tpm_format_one_error_tests; +mod tpm_format_zero_tests; + +use std::{convert::TryFrom, error::Error}; +use tss_esapi::{ + constants::tss::{TPM2_RC_ASYMMETRIC, TPM2_RC_SEQUENCE, TSS2_TPM_RC_LAYER}, + error::{ReturnCode, TpmFormatOneResponseCode, TpmFormatZeroResponseCode, TpmResponseCode}, +}; + +macro_rules! test_valid_conversions { + (TpmResponseCode::$tpm_rc_item:ident, $tss_rc:ident) => { + let expected_tss_rc = TSS2_TPM_RC_LAYER | $tss_rc; + let actual_rc = ReturnCode::try_from(expected_tss_rc).unwrap_or_else(|_| { + panic!( + "Failed to convert {} in the TPM layer to a {}.", + std::stringify!($tss_rc), + std::any::type_name::() + ) + }); + + if let ReturnCode::Tpm(actual_tpm_response_code) = actual_rc { + match actual_tpm_response_code { + TpmResponseCode::$tpm_rc_item(_) => {} + _ => { + panic!( + "{} in the TPM layer did not convert into the expected {}.", + std::stringify!($tss_rc), + std::any::type_name::() + ); + } + } + } else { + panic!( + "The TPM layer did not convert into the expected {}.", + std::any::type_name::() + ); + } + + assert_eq!( + expected_tss_rc, + actual_rc.into(), + "ReturnCode::Tpm did not convert into the expected TSS2_RC value." + ); + }; +} + +#[test] +fn test_valid_tpm_format_zero_response_code() { + test_valid_conversions!(TpmResponseCode::FormatZero, TPM2_RC_SEQUENCE); +} + +#[test] +fn test_valid_tpm_format_one_response_code() { + test_valid_conversions!(TpmResponseCode::FormatOne, TPM2_RC_ASYMMETRIC); +} + +macro_rules! test_display_trait_impl { + ($source_rc:ident, $tss_rc:ident) => { + let value = u16::try_from(TSS2_TPM_RC_LAYER | $tss_rc) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert the valid TSS2 response code {} from the TPM layer into a u16 value.", + std::stringify!($tss_rc)); + }); + + let response_code = TpmResponseCode::try_from(value) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a u16 value representing a valid TSS2 response code {} from the TPM layer into a `{}` object.", + std::stringify!($tss_rc), + std::any::type_name::()); + }); + + + let source_response_code = $source_rc::try_from(value) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a u16 value representing a valid TSS2 response code from the TPM layer into a `{}` object.", + std::any::type_name::<$source_rc>()); + }); + + assert_eq!( + format!("{}", response_code), + format!("{}", source_response_code) + ); + }; +} + +#[test] +fn test_display_trait_implementation() { + test_display_trait_impl!(TpmFormatZeroResponseCode, TPM2_RC_SEQUENCE); + test_display_trait_impl!(TpmFormatOneResponseCode, TPM2_RC_ASYMMETRIC); +} + +macro_rules! test_error_trait_impl { + ($source_rc:ident, $tss_rc:ident) => { + let value = u16::try_from(TSS2_TPM_RC_LAYER | $tss_rc) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert the valid TSS2 response code {} from the TPM layer into a u16 value.", + std::stringify!($tss_rc)); + }); + + let response_code = TpmResponseCode::try_from(value) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a u16 value representing a valid TSS2 response code {} from the TPM layer into a `{}` object.", + std::stringify!($tss_rc), + std::any::type_name::()); + }); + + let actual_source_rc = response_code.source() + .unwrap_or_else(|| { + panic!( + "The `{}` object produced from the valid TSS2 response code {} from the TPM layer should have a source.", + std::any::type_name::(), + std::stringify!($tss_rc)); + }); + + let expected_source_rc = $source_rc::try_from(value) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a u16 value representing a valid TSS2 response code from the TPM layer into a `{}` object.", + std::any::type_name::<$source_rc>()); + }); + + assert_eq!( + format!("{}", actual_source_rc), + format!("{}", expected_source_rc) + ); + }; +} + +#[test] +fn test_error_trait_implementation() { + test_error_trait_impl!(TpmFormatZeroResponseCode, TPM2_RC_SEQUENCE); + test_error_trait_impl!(TpmFormatOneResponseCode, TPM2_RC_ASYMMETRIC); +} diff --git a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/mod.rs b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/mod.rs deleted file mode 100644 index 8691abae..00000000 --- a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2022 Contributors to the Parsec project. -// SPDX-License-Identifier: Apache-2.0 - -mod tpm_format_one_argument_number_tests; -mod tpm_format_one_error_tests; -mod tpm_format_zero_error_tests; -mod tpm_format_zero_vendor_specific_tests; -mod tpm_format_zero_warning_tests; -mod tpm_response_code_tests; diff --git a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_tests.rs b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_tests.rs new file mode 100644 index 00000000..8ab586aa --- /dev/null +++ b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_tests.rs @@ -0,0 +1,184 @@ +// Copyright 2023 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2. + +mod tpm_format_zero_error_tests; +mod tpm_format_zero_warning_tests; + +use bitfield::bitfield; +use std::{convert::TryFrom, error::Error}; +use tss_esapi::{ + constants::tss::{ + TPM2_RC_AUTHSIZE, TPM2_RC_CONTEXT_GAP, TPM2_RC_INITIALIZE, TSS2_TPM_RC_LAYER, + }, + error::{ + ReturnCode, TpmFormatZeroErrorResponseCode, TpmFormatZeroResponseCode, + TpmFormatZeroWarningResponseCode, TpmResponseCode, + }, +}; + +bitfield! { + pub struct VendorSpecificBitHelper(u32); + _, set_is_vendor_specific: 10; +} + +#[test] +fn test_vendor_specific_valid_conversions() { + // Bit 10 In the TPM format zero return code is the bit indicating vendor specific. + // |11|10| 9| 8 | 7| 6| 5| 4| 3| 2| 1| 0| + // | W| V| R|TPM 2.0| | error number | + let mut helper = VendorSpecificBitHelper(TSS2_TPM_RC_LAYER | TPM2_RC_INITIALIZE); + helper.set_is_vendor_specific(true); + let expected_tss_rc = helper.0; + + let actual_rc = ReturnCode::try_from(expected_tss_rc) + .expect("Failed to convert TPM zero error return code value with vendor specific bit set into a ReturnCode."); + + if let ReturnCode::Tpm(TpmResponseCode::FormatZero( + TpmFormatZeroResponseCode::VendorSpecific(actual), + )) = actual_rc + { + assert_eq!( + expected_tss_rc, + actual.into(), + "Converting vendor specific return code did not return the original value." + ); + } else { + panic!("TPM TSS2_RC layer did no convert into ReturnCode::Tpm"); + } + + assert_eq!( + expected_tss_rc, + actual_rc.into(), + "The vendor specific return code did not convert into the expected TSS2_RC in the TPM layer." + ) +} + +#[test] +fn test_vendor_specific_error_trait_implementation() { + // Bit 10 In the TPM format zero return code is the bit indicating vendor specific. + // |11|10| 9| 8 | 7| 6| 5| 4| 3| 2| 1| 0| + // | W| V| R|TPM 2.0| | error number | + let mut helper = VendorSpecificBitHelper(TSS2_TPM_RC_LAYER | TPM2_RC_INITIALIZE); + helper.set_is_vendor_specific(true); + let expected_tss_rc = helper.0; + let expected_tss_rc_error_part = u16::try_from(expected_tss_rc) + .expect("A TSS return code with the vendor specific bit set from the TPM layer should a valid u16 value."); + let vendor_specific_rc = TpmFormatZeroResponseCode::VendorSpecific(expected_tss_rc_error_part); + + assert!( + vendor_specific_rc.source().is_none(), + "`source() method for vendor specific error did not return the expected value." + ); +} + +#[test] +fn test_vendor_specific_display_trait_implementation() { + // Bit 10 In the TPM format zero return code is the bit indicating vendor specific. + // |11|10| 9| 8 | 7| 6| 5| 4| 3| 2| 1| 0| + // | W| V| R|TPM 2.0| | error number | + let mut helper = VendorSpecificBitHelper(TSS2_TPM_RC_LAYER | TPM2_RC_INITIALIZE); + helper.set_is_vendor_specific(true); + let expected_tss_rc = helper.0; + let expected_tss_rc_error_part = u16::try_from(expected_tss_rc) + .expect("A TSS return code with the vendor specific bit set from the TPM layer should a valid u16 value."); + let vendor_specific_rc = TpmFormatZeroResponseCode::VendorSpecific(expected_tss_rc_error_part); + + assert_eq!( + "Vendor specific error.", + format!("{}", vendor_specific_rc), + "The vendor specific return code did not produce the expected error message." + ); +} + +bitfield! { + pub struct ErrorNumberHelper(u32); + u8, error_number, _: 6, 0; +} + +macro_rules! test_display_trait_impl { + ($source_rc:ident, $tss_rc:ident) => { + let value = u16::try_from(TSS2_TPM_RC_LAYER | $tss_rc) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert the valid TSS2 response code {} from the TPM layer into a u16 value.", + std::stringify!($tss_rc)); + }); + + let response_code = TpmFormatZeroResponseCode::try_from(value) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a u16 value representing a valid TSS2 response code {} from the TPM layer into a `{}` object.", + std::stringify!($tss_rc), + std::any::type_name::()); + }); + + let helper = ErrorNumberHelper(TSS2_TPM_RC_LAYER | $tss_rc); + + let source_response_code = $source_rc::try_from(helper.error_number()) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert the bits 0-6 a value representing a valid TSS2 response code {} from the TPM layer into a `{}` object.", + std::stringify!($tss_rc), + std::any::type_name::<$source_rc>()); + }); + + assert_eq!( + format!("{}", response_code), + format!("{}", source_response_code) + ); + }; +} + +#[test] +fn test_error_display_implementation() { + test_display_trait_impl!(TpmFormatZeroWarningResponseCode, TPM2_RC_CONTEXT_GAP); + test_display_trait_impl!(TpmFormatZeroErrorResponseCode, TPM2_RC_AUTHSIZE); +} + +macro_rules! test_error_trait_impl { + ($source_rc:ident, $tss_rc:ident) => { + let value = u16::try_from(TSS2_TPM_RC_LAYER | $tss_rc) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert the valid TSS2 response code {} from the TPM layer into a u16 value.", + std::stringify!($tss_rc)); + }); + + let response_code = TpmFormatZeroResponseCode::try_from(value) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert a u16 value representing a valid TSS2 response code {} from the TPM layer into a `{}` object.", + std::stringify!($tss_rc), + std::any::type_name::()); + }); + + let helper = ErrorNumberHelper(TSS2_TPM_RC_LAYER | $tss_rc); + + let actual_source_rc = response_code.source() + .unwrap_or_else(|| { + panic!( + "The `{}` object produced from the valid TSS2 response code {} from the TPM layer should have a source.", + std::any::type_name::(), + std::stringify!($tss_rc)); + }); + + let expected_source_rc = $source_rc::try_from(helper.error_number()) + .unwrap_or_else(|_| { + panic!( + "It should be possible to convert the bits 0-6 a value representing a valid TSS2 response code {} from the TPM layer into a `{}` object.", + std::stringify!($tss_rc), + std::any::type_name::<$source_rc>()); + }); + + assert_eq!( + format!("{}", actual_source_rc), + format!("{}", expected_source_rc) + ); + }; +} + +#[test] +fn test_error_trait_implementation() { + test_error_trait_impl!(TpmFormatZeroWarningResponseCode, TPM2_RC_CONTEXT_GAP); + test_error_trait_impl!(TpmFormatZeroErrorResponseCode, TPM2_RC_AUTHSIZE); +} diff --git a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_error_tests.rs b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_tests/tpm_format_zero_error_tests.rs similarity index 100% rename from tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_error_tests.rs rename to tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_tests/tpm_format_zero_error_tests.rs diff --git a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_warning_tests.rs b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_tests/tpm_format_zero_warning_tests.rs similarity index 82% rename from tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_warning_tests.rs rename to tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_tests/tpm_format_zero_warning_tests.rs index 397c3cc3..5f069878 100644 --- a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_warning_tests.rs +++ b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_tests/tpm_format_zero_warning_tests.rs @@ -230,3 +230,44 @@ fn test_display_implementation() { TpmFormatZeroWarning::NvUnavailable ); } + +macro_rules! test_error_number_method { + (TpmFormatZeroWarning::$zero_warning:ident) => { + let zero_warning_rc = TpmFormatZeroWarningResponseCode::from(TpmFormatZeroWarning::$zero_warning); + assert_eq!( + TpmFormatZeroWarning::$zero_warning, + zero_warning_rc.error_number(), + "The TpmFormatZeroWarningResponseCode `error_number()` method did not return the expected TpmFormatZeroWarning" + ); + }; +} + +#[test] +fn test_error_number() { + test_error_number_method!(TpmFormatZeroWarning::ContextGap); + test_error_number_method!(TpmFormatZeroWarning::ObjectMemory); + test_error_number_method!(TpmFormatZeroWarning::SessionMemory); + test_error_number_method!(TpmFormatZeroWarning::ObjectHandles); + test_error_number_method!(TpmFormatZeroWarning::Locality); + test_error_number_method!(TpmFormatZeroWarning::Yielded); + test_error_number_method!(TpmFormatZeroWarning::Canceled); + test_error_number_method!(TpmFormatZeroWarning::Testing); + test_error_number_method!(TpmFormatZeroWarning::ReferenceH0); + test_error_number_method!(TpmFormatZeroWarning::ReferenceH1); + test_error_number_method!(TpmFormatZeroWarning::ReferenceH2); + test_error_number_method!(TpmFormatZeroWarning::ReferenceH3); + test_error_number_method!(TpmFormatZeroWarning::ReferenceH4); + test_error_number_method!(TpmFormatZeroWarning::ReferenceH5); + test_error_number_method!(TpmFormatZeroWarning::ReferenceH6); + test_error_number_method!(TpmFormatZeroWarning::ReferenceS0); + test_error_number_method!(TpmFormatZeroWarning::ReferenceS1); + test_error_number_method!(TpmFormatZeroWarning::ReferenceS2); + test_error_number_method!(TpmFormatZeroWarning::ReferenceS3); + test_error_number_method!(TpmFormatZeroWarning::ReferenceS4); + test_error_number_method!(TpmFormatZeroWarning::ReferenceS5); + test_error_number_method!(TpmFormatZeroWarning::ReferenceS6); + test_error_number_method!(TpmFormatZeroWarning::NvRate); + test_error_number_method!(TpmFormatZeroWarning::Lockout); + test_error_number_method!(TpmFormatZeroWarning::Retry); + test_error_number_method!(TpmFormatZeroWarning::NvUnavailable); +} diff --git a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_vendor_specific_tests.rs b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_vendor_specific_tests.rs deleted file mode 100644 index ca7af7b7..00000000 --- a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_format_zero_vendor_specific_tests.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2023 Contributors to the Parsec project. -// SPDX-License-Identifier: Apache-2. -use bitfield::bitfield; -use std::convert::TryFrom; -use tss_esapi::{ - constants::tss::{TPM2_RC_INITIALIZE, TSS2_TPM_RC_LAYER}, - error::{ReturnCode, TpmFormatZeroResponseCode, TpmResponseCode}, -}; - -bitfield! { - pub struct VendorSpecificBitHelper(u32); - _, set_is_vendor_specific: 10; -} - -#[test] -fn test_valid_conversions() { - // Bit 10 In the TPM format zero return code is the bit indicating vendor specific. - // |11|10| 9| 8 | 7| 6| 5| 4| 3| 2| 1| 0| - // | W| V| R|TPM 2.0| | error number | - let mut helper = VendorSpecificBitHelper(TSS2_TPM_RC_LAYER | TPM2_RC_INITIALIZE); - helper.set_is_vendor_specific(true); - let expected_tss_rc = helper.0; - - let actual_rc = ReturnCode::try_from(expected_tss_rc) - .expect("Failed to convert TPM zero error return code value with vendor specific bit set into a Result."); - - if let ReturnCode::Tpm(TpmResponseCode::FormatZero( - TpmFormatZeroResponseCode::VendorSpecific(actual), - )) = actual_rc - { - assert_eq!( - expected_tss_rc, - actual.into(), - "Converting vendor specific return code did not return the original value." - ); - } else { - panic!("TPM TSS2_RC layer did no convert into ReturnCode::Tpm"); - } - - assert_eq!( - expected_tss_rc, - actual_rc.into(), - "The vendor specific return code did not convert into the expected TSS2_RC in the TPM layer." - ) -} diff --git a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_response_code_tests.rs b/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_response_code_tests.rs deleted file mode 100644 index a6d517d1..00000000 --- a/tss-esapi/tests/integration_tests/error_tests/return_code_tests/tpm_tests/tpm_response_code_tests.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2022 Contributors to the Parsec project. -// SPDX-License-Identifier: Apache-2.0 -use std::convert::TryFrom; -use tss_esapi::{ - constants::tss::{TPM2_RC_ASYMMETRIC, TPM2_RC_SEQUENCE, TSS2_TPM_RC_LAYER}, - error::{ReturnCode, TpmResponseCode}, -}; - -#[test] -fn test_valid_tpm_format_zero_response_code() { - let expected_tss_rc = TSS2_TPM_RC_LAYER | TPM2_RC_SEQUENCE; - let actual_rc = ReturnCode::try_from(expected_tss_rc) - .expect("Failed to convert TPM2_RC_SEQUENCE in the TPM layer to a ReturnCode."); - - if let ReturnCode::Tpm(actual_tpm_response_code) = actual_rc { - match actual_tpm_response_code { - TpmResponseCode::FormatZero(_) => {} - _ => { - panic!("TPM2_RC_SEQUENCE in the TPM layer did not convert into the expected TpmResponseCode"); - } - } - } else { - panic!("The TPM layer did not convert into the expected ReturnCode"); - } - - assert_eq!( - expected_tss_rc, - actual_rc.into(), - "ReturnCode::Tpm did not convert into the expected TSS2_RC value" - ); -} - -#[test] -fn test_valid_tpm_format_one_response_code() { - let expected_tss_rc = TSS2_TPM_RC_LAYER | TPM2_RC_ASYMMETRIC; - let actual_rc = ReturnCode::try_from(expected_tss_rc) - .expect("Failed to convert TPM2_RC_ASYMMETRIC in the TPM layer to a ReturnCode."); - - if let ReturnCode::Tpm(actual_tpm_response_code) = actual_rc { - match actual_tpm_response_code { - TpmResponseCode::FormatOne(_) => {} - _ => { - panic!("TPM2_RC_ASYMMETRIC in the TPM layer did not convert into the expected TpmResponseCode"); - } - } - } else { - panic!("The TPM layer did not convert into the expected ReturnCode"); - } - - assert_eq!( - expected_tss_rc, - actual_rc.into(), - "ReturnCode::Tpm did not convert into the expected TSS2_RC value" - ); -}