From bf24797423c445c3face37adeaece34ddec77b62 Mon Sep 17 00:00:00 2001 From: Jesper Brynolf Date: Wed, 25 Sep 2024 20:30:10 +0200 Subject: [PATCH] Fixes issue wrong max size in some sized buffer types. Some of the sized buffers had their buffer sizes set as numbers. Even though this in some cases were the correct numbers they were a little hard to determine if they actually followed the size specified in the standard. So this PR fixes #548 in the main branch by using the the calculations specified in the standard for the buffer sizes. Signed-off-by: Jesper Brynolf --- tss-esapi/src/structures/buffers.rs | 106 ++++++++++++------ tss-esapi/src/structures/buffers/private.rs | 5 +- tss-esapi/src/structures/buffers/public.rs | 4 +- tss-esapi/src/structures/buffers/sensitive.rs | 4 +- .../structures/buffers/sensitive_create.rs | 4 +- tss-esapi/src/structures/ecc/point.rs | 11 +- tss-esapi/src/structures/nv/storage/public.rs | 8 +- tss-esapi/src/traits.rs | 2 +- .../buffers_tests/attest_buffer_tests.rs | 12 ++ .../buffers_tests/auth_tests.rs | 92 ++++++++------- .../buffers_tests/data_tests.rs | 90 ++++++++------- .../buffers_tests/digest_tests.rs | 86 +++++++------- .../buffers_tests/ecc_parameters_tests.rs | 15 +++ .../buffers_tests/encrypted_secret_test.rs | 15 +++ .../buffers_tests/id_object_tests.rs | 14 +++ .../buffers_tests/max_buffer_tests.rs | 105 +++++++++-------- .../structures_tests/buffers_tests/mod.rs | 3 + .../buffers_tests/nonce_tests.rs | 11 ++ .../structures_tests/buffers_tests/private.rs | 13 ++- 19 files changed, 377 insertions(+), 223 deletions(-) create mode 100644 tss-esapi/tests/integration_tests/structures_tests/buffers_tests/ecc_parameters_tests.rs create mode 100644 tss-esapi/tests/integration_tests/structures_tests/buffers_tests/encrypted_secret_test.rs create mode 100644 tss-esapi/tests/integration_tests/structures_tests/buffers_tests/id_object_tests.rs diff --git a/tss-esapi/src/structures/buffers.rs b/tss-esapi/src/structures/buffers.rs index 2ffbb915..52f96f88 100644 --- a/tss-esapi/src/structures/buffers.rs +++ b/tss-esapi/src/structures/buffers.rs @@ -103,15 +103,30 @@ pub mod sensitive; pub mod sensitive_create; pub mod auth { - buffer_type!(Auth, 64, TPM2B_AUTH); + // Same size as TPM2B_DIGEST according to the specification. + use crate::tss2_esys::TPMU_HA; + use std::mem::size_of; + const TPM2B_AUTH_BUFFER_SIZE: usize = size_of::(); + buffer_type!(Auth, TPM2B_AUTH_BUFFER_SIZE, TPM2B_AUTH); } pub mod data { - buffer_type!(Data, 64, TPM2B_DATA); + // This should, according to the specification, be + // size_of::() but due to a bug in tpm2-tss + // (https://github.com/tpm2-software/tpm2-tss/issues/2888) + // it is the size of TPMU_HA + use crate::tss2_esys::TPMU_HA; + use std::mem::size_of; + const TPM2B_DATA_BUFFER_SIZE: usize = size_of::(); + buffer_type!(Data, TPM2B_DATA_BUFFER_SIZE, TPM2B_DATA); } pub mod digest { - buffer_type!(Digest, 64, TPM2B_DIGEST); + use crate::tss2_esys::TPMU_HA; + use std::mem::size_of; + const TPM2B_DIGEST_BUFFER_SIZE: usize = size_of::(); + + buffer_type!(Digest, TPM2B_DIGEST_BUFFER_SIZE, TPM2B_DIGEST); // Some implementations to get from Digest to [u8; N] for common values of N (sha* primarily) // This is used to work around the fact that Rust does not allow custom functions for general values of N in [T; N], @@ -208,80 +223,101 @@ pub mod digest { } pub mod ecc_parameter { + use crate::tss2_esys::TPM2_MAX_ECC_KEY_BYTES; + const TPM2B_ECC_PARAMETER_BUFFER_SIZE: usize = TPM2_MAX_ECC_KEY_BYTES as usize; buffer_type!( EccParameter, - crate::tss2_esys::TPM2_MAX_ECC_KEY_BYTES as usize, + TPM2B_ECC_PARAMETER_BUFFER_SIZE, TPM2B_ECC_PARAMETER ); } pub mod encrypted_secret { - named_field_buffer_type!(EncryptedSecret, 256, TPM2B_ENCRYPTED_SECRET, secret); + use crate::tss2_esys::TPMU_ENCRYPTED_SECRET; + use std::mem::size_of; + const TPM2B_ENCRYPTED_SECRET_BUFFER_SIZE: usize = size_of::(); + named_field_buffer_type!( + EncryptedSecret, + TPM2B_ENCRYPTED_SECRET_BUFFER_SIZE, + TPM2B_ENCRYPTED_SECRET, + secret + ); } pub mod id_object { - named_field_buffer_type!(IdObject, 256, TPM2B_ID_OBJECT, credential); + use crate::tss2_esys::TPMS_ID_OBJECT; + use std::mem::size_of; + const TPM2B_ID_OBJECT_BUFFER_SIZE: usize = size_of::(); + named_field_buffer_type!( + IdObject, + TPM2B_ID_OBJECT_BUFFER_SIZE, + TPM2B_ID_OBJECT, + credential + ); } pub mod initial_value { - buffer_type!( - InitialValue, - crate::tss2_esys::TPM2_MAX_SYM_BLOCK_SIZE as usize, - TPM2B_IV - ); + use crate::tss2_esys::TPM2_MAX_SYM_BLOCK_SIZE; + const TPM2B_IV_BUFFER_SIZE: usize = TPM2_MAX_SYM_BLOCK_SIZE as usize; + buffer_type!(InitialValue, TPM2B_IV_BUFFER_SIZE, TPM2B_IV); } pub mod max_buffer { use crate::tss2_esys::TPM2_MAX_DIGEST_BUFFER; - buffer_type!(MaxBuffer, TPM2_MAX_DIGEST_BUFFER as usize, TPM2B_MAX_BUFFER); + const TPM2B_MAX_BUFFER_BUFFER_SIZE: usize = TPM2_MAX_DIGEST_BUFFER as usize; + buffer_type!(MaxBuffer, TPM2B_MAX_BUFFER_BUFFER_SIZE, TPM2B_MAX_BUFFER); } pub mod max_nv_buffer { use crate::tss2_esys::TPM2_MAX_NV_BUFFER_SIZE; + const TPM2B_MAX_NV_BUFFER_BUFFER_SIZE: usize = TPM2_MAX_NV_BUFFER_SIZE as usize; buffer_type!( MaxNvBuffer, - TPM2_MAX_NV_BUFFER_SIZE as usize, + TPM2B_MAX_NV_BUFFER_BUFFER_SIZE, TPM2B_MAX_NV_BUFFER ); } pub mod nonce { - buffer_type!(Nonce, 64, TPM2B_NONCE); + // Same size as TPM2B_DIGEST according to the specification. + use crate::tss2_esys::TPMU_HA; + use std::mem::size_of; + const TPM2B_NONCE_BUFFER_SIZE: usize = size_of::(); + + buffer_type!(Nonce, TPM2B_NONCE_BUFFER_SIZE, TPM2B_NONCE); } pub mod private_key_rsa { use crate::tss2_esys::TPM2_MAX_RSA_KEY_BYTES; + const TPM2B_PRIVATE_KEY_RSA_BUFFER_SIZE: usize = (TPM2_MAX_RSA_KEY_BYTES as usize) * 5 / 2; - // The maximum size is given in the spec as: - // "RSA_PRIVATE_SIZE is a vendor specific value that can be (MAX_RSA_KEY_BYTES / 2) or - // ((MAX_RSA_KEY_BYTES * 5) ./ 2. The larger size would only apply to keys that have fixedTPM parents. - // The larger size was added in revision 01.53." - // The TSS stack we use only accepts the smaller of the two sizes described above (for now). buffer_type!( PrivateKeyRsa, - (TPM2_MAX_RSA_KEY_BYTES / 2) as usize, + TPM2B_PRIVATE_KEY_RSA_BUFFER_SIZE, TPM2B_PRIVATE_KEY_RSA ); } pub mod private_vendor_specific { use crate::tss2_esys::TPM2_PRIVATE_VENDOR_SPECIFIC_BYTES; - + const TPM2B_PRIVATE_VENDOR_SPECIFIC_BUFFER_SIZE: usize = + TPM2_PRIVATE_VENDOR_SPECIFIC_BYTES as usize; // The spec states the maximum size as: // "The value for PRIVATE_VENDOR_SPECIFIC_BYTES is determined by the vendor." // Not very helpful, but the TSS exposes a generic value that we can use. buffer_type!( PrivateVendorSpecific, - TPM2_PRIVATE_VENDOR_SPECIFIC_BYTES as usize, + TPM2B_PRIVATE_VENDOR_SPECIFIC_BUFFER_SIZE, TPM2B_PRIVATE_VENDOR_SPECIFIC ); } pub mod public_key_rsa { use crate::{interface_types::key_bits::RsaKeyBits, tss2_esys::TPM2_MAX_RSA_KEY_BYTES}; + const TPM2B_PUBLIC_KEY_RSA_BUFFER_SIZE: usize = TPM2_MAX_RSA_KEY_BYTES as usize; buffer_type!( PublicKeyRsa, - TPM2_MAX_RSA_KEY_BYTES as usize, + TPM2B_PUBLIC_KEY_RSA_BUFFER_SIZE, TPM2B_PUBLIC_KEY_RSA ); @@ -359,45 +395,47 @@ pub mod sensitive_data { // versions of tpm2-tss supported by the crate so the fall back is to // calculate the max size by removing the size of the size parameter(UINT16) // from the total size of the buffer type. + use std::mem::size_of; cfg_if::cfg_if! { if #[cfg(has_tpmu_sensitive_create)] { use crate::tss2_esys::TPMU_SENSITIVE_CREATE; - #[allow(unused_qualifications)] - const TPMU_SENSITIVE_CREATE_MEM_SIZE: usize = std::mem::size_of::(); + const TPM2B_SENSITIVE_DATA_BUFFER_SIZE: usize = size_of::(); } else { use crate::tss2_esys::UINT16; - #[allow(unused_qualifications)] - const TPMU_SENSITIVE_CREATE_MEM_SIZE: usize = std::mem::size_of::() - std::mem::size_of::(); + const TPM2B_SENSITIVE_DATA_BUFFER_SIZE: usize = size_of::() - size_of::(); } } buffer_type!( SensitiveData, - TPMU_SENSITIVE_CREATE_MEM_SIZE, + TPM2B_SENSITIVE_DATA_BUFFER_SIZE, TPM2B_SENSITIVE_DATA ); } pub mod symmetric_key { use crate::tss2_esys::TPM2_MAX_SYM_KEY_BYTES; - + const TPM2B_SYM_KEY_BUFFER_SIZE: usize = TPM2_MAX_SYM_KEY_BYTES as usize; // The spec states the maximum size as: // "MAX_SYM_KEY_BYTES will be the larger of the largest symmetric key supported by the TPM and the // largest digest produced by any hashing algorithm implemented on the TPM" - buffer_type!(SymmetricKey, TPM2_MAX_SYM_KEY_BYTES as usize, TPM2B_SYM_KEY); + buffer_type!(SymmetricKey, TPM2B_SYM_KEY_BUFFER_SIZE, TPM2B_SYM_KEY); } pub mod timeout { - buffer_type!(Timeout, 8, TPM2B_TIMEOUT); + use crate::tss2_esys::UINT64; + use std::mem::size_of; + const TPM2B_TIMEOUT_BUFFER_SIZE: usize = size_of::(); + buffer_type!(Timeout, TPM2B_TIMEOUT_BUFFER_SIZE, TPM2B_TIMEOUT); } pub mod tpm_context_data { use crate::tss2_esys::TPMS_CONTEXT_DATA; + use std::mem::size_of; - #[allow(unused_qualifications)] - const TPMS_CONTEXT_DATA_MEM_SIZE: usize = std::mem::size_of::(); + const TPM2B_CONTEXT_DATA_BUFFER_SIZE: usize = size_of::(); buffer_type!( TpmContextData, - TPMS_CONTEXT_DATA_MEM_SIZE, + TPM2B_CONTEXT_DATA_BUFFER_SIZE, TPM2B_CONTEXT_DATA ); } diff --git a/tss-esapi/src/structures/buffers/private.rs b/tss-esapi/src/structures/buffers/private.rs index 9c6611b7..ef610854 100644 --- a/tss-esapi/src/structures/buffers/private.rs +++ b/tss-esapi/src/structures/buffers/private.rs @@ -2,9 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 use crate::traits::impl_mu_standard; +use std::mem::size_of; use tss_esapi_sys::_PRIVATE; -buffer_type!(Private, ::std::mem::size_of::<_PRIVATE>(), TPM2B_PRIVATE); +const TPM2B_PRIVATE_BUFFER_SIZE: usize = size_of::<_PRIVATE>(); + +buffer_type!(Private, TPM2B_PRIVATE_BUFFER_SIZE, TPM2B_PRIVATE); impl_mu_standard!(Private, TPM2B_PRIVATE); diff --git a/tss-esapi/src/structures/buffers/public.rs b/tss-esapi/src/structures/buffers/public.rs index 5f2ccc25..fc11c27e 100644 --- a/tss-esapi/src/structures/buffers/public.rs +++ b/tss-esapi/src/structures/buffers/public.rs @@ -10,6 +10,7 @@ use crate::{ use log::error; use std::{ convert::{TryFrom, TryInto}, + mem::size_of, ops::Deref, }; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -24,8 +25,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub struct PublicBuffer(Vec); impl PublicBuffer { - #[allow(unused_qualifications)] - pub const MAX_SIZE: usize = std::mem::size_of::(); + pub const MAX_SIZE: usize = size_of::(); pub fn value(&self) -> &[u8] { &self.0 diff --git a/tss-esapi/src/structures/buffers/sensitive.rs b/tss-esapi/src/structures/buffers/sensitive.rs index a8f3eb38..9aa0781a 100644 --- a/tss-esapi/src/structures/buffers/sensitive.rs +++ b/tss-esapi/src/structures/buffers/sensitive.rs @@ -9,6 +9,7 @@ use crate::{ use log::error; use std::{ convert::{TryFrom, TryInto}, + mem::size_of, ops::Deref, }; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -23,8 +24,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub struct SensitiveBuffer(Vec); impl SensitiveBuffer { - #[allow(unused_qualifications)] - pub const MAX_SIZE: usize = std::mem::size_of::(); + pub const MAX_SIZE: usize = size_of::(); pub fn value(&self) -> &[u8] { &self.0 diff --git a/tss-esapi/src/structures/buffers/sensitive_create.rs b/tss-esapi/src/structures/buffers/sensitive_create.rs index 96a9f6f0..850d499d 100644 --- a/tss-esapi/src/structures/buffers/sensitive_create.rs +++ b/tss-esapi/src/structures/buffers/sensitive_create.rs @@ -9,6 +9,7 @@ use crate::{ use log::error; use std::{ convert::{TryFrom, TryInto}, + mem::size_of, ops::Deref, }; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -23,8 +24,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub struct SensitiveCreateBuffer(Vec); impl SensitiveCreateBuffer { - #[allow(unused_qualifications)] - pub const MAX_SIZE: usize = std::mem::size_of::(); + pub const MAX_SIZE: usize = size_of::(); pub const MIN_SIZE: usize = 4; /// Returns the content of the buffer. diff --git a/tss-esapi/src/structures/ecc/point.rs b/tss-esapi/src/structures/ecc/point.rs index 2d83b9c7..c775f534 100644 --- a/tss-esapi/src/structures/ecc/point.rs +++ b/tss-esapi/src/structures/ecc/point.rs @@ -3,7 +3,10 @@ use tss_esapi_sys::TPM2B_ECC_POINT; // Copyright 2021 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use crate::{structures::EccParameter, tss2_esys::TPMS_ECC_POINT, Error, Result}; -use std::convert::{TryFrom, TryInto}; +use std::{ + convert::{TryFrom, TryInto}, + mem::size_of, +}; /// Structure holding ecc point information /// @@ -49,11 +52,7 @@ impl From for TPMS_ECC_POINT { impl From for TPM2B_ECC_POINT { fn from(ecc_point: EccPoint) -> Self { - #[allow(unused_qualifications)] - let size = std::mem::size_of::() - + ecc_point.x().len() - + std::mem::size_of::() - + ecc_point.y().len(); + let size = size_of::() + ecc_point.x().len() + size_of::() + ecc_point.y().len(); TPM2B_ECC_POINT { size: size as u16, point: ecc_point.into(), diff --git a/tss-esapi/src/structures/nv/storage/public.rs b/tss-esapi/src/structures/nv/storage/public.rs index b4d674ef..775e0dfc 100644 --- a/tss-esapi/src/structures/nv/storage/public.rs +++ b/tss-esapi/src/structures/nv/storage/public.rs @@ -10,7 +10,10 @@ use crate::{ Error, Result, WrapperErrorKind, }; use log::error; -use std::convert::{TryFrom, TryInto}; +use std::{ + convert::{TryFrom, TryInto}, + mem::size_of, +}; /// Representation of the public parameters of a non-volatile /// space allocation. @@ -27,8 +30,7 @@ pub struct NvPublic { } impl NvPublic { - #[allow(unused_qualifications)] - const MAX_SIZE: usize = std::mem::size_of::(); + const MAX_SIZE: usize = size_of::(); pub fn nv_index(&self) -> NvIndexTpmHandle { self.nv_index diff --git a/tss-esapi/src/traits.rs b/tss-esapi/src/traits.rs index 98ef7c57..0d8febae 100644 --- a/tss-esapi/src/traits.rs +++ b/tss-esapi/src/traits.rs @@ -49,7 +49,7 @@ macro_rules! impl_marshall_trait { ($native_type:ident, $tss_type:ident, $tss_mu_type:ident, $convert_expression:stmt, $( $ref_sign:tt )?) => { paste::item! { impl $crate::traits::Marshall for $native_type { - const BUFFER_SIZE: usize = std::mem::size_of::<$tss_type>(); + const BUFFER_SIZE: usize = ::std::mem::size_of::<$tss_type>(); fn marshall_offset( &self, diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/attest_buffer_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/attest_buffer_tests.rs index c98340b4..469828f0 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/attest_buffer_tests.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/attest_buffer_tests.rs @@ -51,3 +51,15 @@ fn test_default() { assert_eq!(expected, actual); } } + +#[test] +fn test_max_sized_attest_buffer_conversions() { + let expected_attestation_data = [0xffu8; AttestBuffer::MAX_SIZE]; + let native = AttestBuffer::try_from(expected_attestation_data.as_slice().to_vec()).expect( + "It should be possible to convert an array of MAX size into a AttestBuffer object.", + ); + let tss = TPM2B_ATTEST::from(native); + assert_eq!(AttestBuffer::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_attestation_data, tss.attestationData); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/auth_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/auth_tests.rs index 5ab1ce0b..ba8ae466 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/auth_tests.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/auth_tests.rs @@ -8,51 +8,59 @@ use tss_esapi::tss2_esys::TPM2B_AUTH; // in it being just a type alias for TPM2B_DIGEST // in the rust code. So the same size restrictions that // TPM2B_DIGEST have will apply here as well. -mod test_auth { - use super::*; - #[test] - fn test_max_sized_data() { - let _ = Auth::try_from([0xff; 64].to_vec()).unwrap(); - } +#[test] +fn test_max_sized_data() { + let _ = Auth::try_from([0xff; 64].to_vec()).unwrap(); +} - #[test] - fn test_to_large_data() { - // Removed: - // - test_handle_auth::test_set_large_handle - // - test_create::test_long_auth_create - // - test_create_primary::test_long_auth_create_primary - // from the context tests and put here instead. +#[test] +fn test_to_large_data() { + // Removed: + // - test_handle_auth::test_set_large_handle + // - test_create::test_long_auth_create + // - test_create_primary::test_long_auth_create_primary + // from the context tests and put here instead. - let _ = Auth::try_from([0xff; 100].to_vec()).unwrap_err(); - } + let _ = Auth::try_from([0xff; 100].to_vec()).unwrap_err(); +} - #[test] - fn test_default() { - { - let auth: Auth = Default::default(); - let expected: TPM2B_AUTH = Default::default(); - let actual = TPM2B_AUTH::from(auth); - assert_eq!(expected.size, actual.size); - assert_eq!( - expected.buffer.len(), - actual.buffer.len(), - "Buffers don't have the same length" - ); - assert!( - expected - .buffer - .iter() - .zip(actual.buffer.iter()) - .all(|(a, b)| a == b), - "Buffers are not equal" - ); - } - { - let tss_auth: TPM2B_AUTH = Default::default(); - let expected: Auth = Default::default(); - let actual = Auth::try_from(tss_auth).unwrap(); - assert_eq!(expected, actual); - } +#[test] +fn test_default() { + { + let auth: Auth = Default::default(); + let expected: TPM2B_AUTH = Default::default(); + let actual = TPM2B_AUTH::from(auth); + assert_eq!(expected.size, actual.size); + assert_eq!( + expected.buffer.len(), + actual.buffer.len(), + "Buffers don't have the same length" + ); + assert!( + expected + .buffer + .iter() + .zip(actual.buffer.iter()) + .all(|(a, b)| a == b), + "Buffers are not equal" + ); } + { + let tss_auth: TPM2B_AUTH = Default::default(); + let expected: Auth = Default::default(); + let actual = Auth::try_from(tss_auth).unwrap(); + assert_eq!(expected, actual); + } +} + +#[test] +fn test_max_sized_auth_conversions() { + let expected_buffer = [0xffu8; Auth::MAX_SIZE]; + let native = Auth::try_from(expected_buffer.as_slice().to_vec()) + .expect("It should be possible to convert an array of MAX size into a Auth object."); + let tss = TPM2B_AUTH::from(native); + assert_eq!(Auth::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_buffer, tss.buffer); } diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/data_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/data_tests.rs index 7c103e47..3869d4cc 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/data_tests.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/data_tests.rs @@ -4,50 +4,58 @@ use std::convert::TryFrom; use tss_esapi::structures::Data; use tss_esapi::tss2_esys::TPM2B_DATA; // The TPM2B_DATA has a size of 64 bytes -mod test_data { - use super::*; - #[test] - fn test_max_sized_data() { - let _ = Data::try_from([0xff; 64].to_vec()).unwrap(); - } +#[test] +fn test_max_sized_data() { + let _ = Data::try_from([0xff; 64].to_vec()).unwrap(); +} - #[test] - fn test_to_large_data() { - // Removed: - // - test_create::test_long_outside_info_create - // - test_create_primary::test_long_outside_info_create_primary - // from the context tests and put here instead. +#[test] +fn test_to_large_data() { + // Removed: + // - test_create::test_long_outside_info_create + // - test_create_primary::test_long_outside_info_create_primary + // from the context tests and put here instead. - let _ = Data::try_from([0xff; 100].to_vec()).unwrap_err(); - } + let _ = Data::try_from([0xff; 100].to_vec()).unwrap_err(); +} - #[test] - fn test_default() { - { - let data: Data = Default::default(); - let expected: TPM2B_DATA = Default::default(); - let actual = TPM2B_DATA::from(data); - assert_eq!(expected.size, actual.size); - assert_eq!( - expected.buffer.len(), - actual.buffer.len(), - "Buffers don't have the same length" - ); - assert!( - expected - .buffer - .iter() - .zip(actual.buffer.iter()) - .all(|(a, b)| a == b), - "Buffers are not equal" - ); - } - { - let tss_data: TPM2B_DATA = Default::default(); - let expected: Data = Default::default(); - let actual = Data::try_from(tss_data).unwrap(); - assert_eq!(expected, actual); - } +#[test] +fn test_default() { + { + let data: Data = Default::default(); + let expected: TPM2B_DATA = Default::default(); + let actual = TPM2B_DATA::from(data); + assert_eq!(expected.size, actual.size); + assert_eq!( + expected.buffer.len(), + actual.buffer.len(), + "Buffers don't have the same length" + ); + assert!( + expected + .buffer + .iter() + .zip(actual.buffer.iter()) + .all(|(a, b)| a == b), + "Buffers are not equal" + ); } + { + let tss_data: TPM2B_DATA = Default::default(); + let expected: Data = Default::default(); + let actual = Data::try_from(tss_data).unwrap(); + assert_eq!(expected, actual); + } +} + +#[test] +fn test_max_sized_data_conversions() { + let expected_buffer = [0xffu8; Data::MAX_SIZE]; + let native = Data::try_from(expected_buffer.as_slice().to_vec()) + .expect("It should be possible to convert an array of MAX size into a Data object."); + let tss = TPM2B_DATA::from(native); + assert_eq!(Data::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_buffer, tss.buffer); } diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/digest_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/digest_tests.rs index 55eb5461..8080cb34 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/digest_tests.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/digest_tests.rs @@ -1,46 +1,54 @@ // Copyright 2020 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use std::convert::{TryFrom, TryInto}; -use tss_esapi::structures::Digest; +use tss_esapi::{structures::Digest, tss2_esys::TPM2B_DIGEST}; // Digest has some custom functions for conversion to [u8; N] for common values of N -mod test_digests { - use super::*; - #[test] - fn test_correctly_sized_digests() { - // N = 20 - let sha1_ex = Digest::try_from((1..21).collect::>()).unwrap(); - let sha1: [u8; 20] = sha1_ex.try_into().unwrap(); - assert_eq!(sha1.to_vec(), (1..21).collect::>()); - // N = 32 - let sha256_ex = Digest::try_from((1..33).collect::>()).unwrap(); - let sha256: [u8; 32] = sha256_ex.try_into().unwrap(); - assert_eq!(sha256.to_vec(), (1..33).collect::>()); - // N = 48 - let sha384_ex = Digest::try_from((1..49).collect::>()).unwrap(); - let sha384: [u8; 48] = sha384_ex.try_into().unwrap(); - assert_eq!(sha384.to_vec(), (1..49).collect::>()); - // N = 64 - let sha512_ex = Digest::try_from((1..65).collect::>()).unwrap(); - let sha512: [u8; 64] = sha512_ex.try_into().unwrap(); - assert_eq!(sha512.to_vec(), (1..65).collect::>()); - } +#[test] +fn test_correctly_sized_digests() { + // N = 20 + let sha1_ex = Digest::try_from((1..21).collect::>()).unwrap(); + let sha1: [u8; 20] = sha1_ex.try_into().unwrap(); + assert_eq!(sha1.to_vec(), (1..21).collect::>()); + // N = 32 + let sha256_ex = Digest::try_from((1..33).collect::>()).unwrap(); + let sha256: [u8; 32] = sha256_ex.try_into().unwrap(); + assert_eq!(sha256.to_vec(), (1..33).collect::>()); + // N = 48 + let sha384_ex = Digest::try_from((1..49).collect::>()).unwrap(); + let sha384: [u8; 48] = sha384_ex.try_into().unwrap(); + assert_eq!(sha384.to_vec(), (1..49).collect::>()); + // N = 64 + let sha512_ex = Digest::try_from((1..65).collect::>()).unwrap(); + let sha512: [u8; 64] = sha512_ex.try_into().unwrap(); + assert_eq!(sha512.to_vec(), (1..65).collect::>()); +} + +#[test] +fn test_incorrectly_sized_digests() { + // This test uses .err().unwrap() to get around the fact that [u8; N] is only + // Debug if N is LengthAtMost32, since .unwrap_err() requires T ([u8; N]): Debug + // N = 20 + let example = Digest::try_from([0xff; 10].to_vec()).unwrap(); + TryInto::<[u8; 20]>::try_into(example).err().unwrap(); + // N = 32 + let example = Digest::try_from([0xff; 10].to_vec()).unwrap(); + TryInto::<[u8; 32]>::try_into(example).err().unwrap(); + // N = 48 + let example = Digest::try_from([0xff; 10].to_vec()).unwrap(); + TryInto::<[u8; 48]>::try_into(example).err().unwrap(); + // N = 64 + let example = Digest::try_from([0xff; 10].to_vec()).unwrap(); + TryInto::<[u8; 64]>::try_into(example).err().unwrap(); +} - #[test] - fn test_incorrectly_sized_digests() { - // This test uses .err().unwrap() to get around the fact that [u8; N] is only - // Debug if N is LengthAtMost32, since .unwrap_err() requires T ([u8; N]): Debug - // N = 20 - let example = Digest::try_from([0xff; 10].to_vec()).unwrap(); - TryInto::<[u8; 20]>::try_into(example).err().unwrap(); - // N = 32 - let example = Digest::try_from([0xff; 10].to_vec()).unwrap(); - TryInto::<[u8; 32]>::try_into(example).err().unwrap(); - // N = 48 - let example = Digest::try_from([0xff; 10].to_vec()).unwrap(); - TryInto::<[u8; 48]>::try_into(example).err().unwrap(); - // N = 64 - let example = Digest::try_from([0xff; 10].to_vec()).unwrap(); - TryInto::<[u8; 64]>::try_into(example).err().unwrap(); - } +#[test] +fn test_max_sized_digest_conversions() { + let expected_buffer = [0xffu8; Digest::MAX_SIZE]; + let native = Digest::try_from(expected_buffer.as_slice().to_vec()) + .expect("It should be possible to convert an array of MAX size into a Digest object."); + let tss = TPM2B_DIGEST::from(native); + assert_eq!(Digest::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_buffer, tss.buffer); } diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/ecc_parameters_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/ecc_parameters_tests.rs new file mode 100644 index 00000000..817d2706 --- /dev/null +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/ecc_parameters_tests.rs @@ -0,0 +1,15 @@ +// Copyright 2024 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +use std::convert::TryFrom; +use tss_esapi::{structures::EccParameter, tss2_esys::TPM2B_ECC_PARAMETER}; +#[test] +fn test_max_sized_ecc_parameter_conversions() { + let expected_buffer: [u8; 128] = [0xffu8; EccParameter::MAX_SIZE]; + let native = EccParameter::try_from(expected_buffer.as_slice().to_vec()).expect( + "It should be possible to convert an array of MAX size into a EccParameter object.", + ); + let tss = TPM2B_ECC_PARAMETER::from(native); + assert_eq!(EccParameter::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_buffer, tss.buffer); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/encrypted_secret_test.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/encrypted_secret_test.rs new file mode 100644 index 00000000..4d9290b1 --- /dev/null +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/encrypted_secret_test.rs @@ -0,0 +1,15 @@ +// Copyright 2024 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +use std::convert::TryFrom; +use tss_esapi::{structures::EncryptedSecret, tss2_esys::TPM2B_ENCRYPTED_SECRET}; +#[test] +fn test_max_sized_ecc_parameter_conversions() { + let expected_secret = [0xffu8; EncryptedSecret::MAX_SIZE]; + let native = EncryptedSecret::try_from(expected_secret.as_slice().to_vec()).expect( + "It should be possible to convert an array of MAX size into a EncryptedSecret object.", + ); + let tss = TPM2B_ENCRYPTED_SECRET::from(native); + assert_eq!(EncryptedSecret::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_secret, tss.secret); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/id_object_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/id_object_tests.rs new file mode 100644 index 00000000..73541586 --- /dev/null +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/id_object_tests.rs @@ -0,0 +1,14 @@ +// Copyright 2024 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +use std::convert::TryFrom; +use tss_esapi::{structures::IdObject, tss2_esys::TPM2B_ID_OBJECT}; +#[test] +fn test_max_sized_id_object_conversions() { + let expected_credential = [0xffu8; IdObject::MAX_SIZE]; + let native = IdObject::try_from(expected_credential.as_slice().to_vec()) + .expect("It should be possible to convert an array of MAX size into a IdObject object."); + let tss = TPM2B_ID_OBJECT::from(native); + assert_eq!(IdObject::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_credential, tss.credential); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/max_buffer_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/max_buffer_tests.rs index bab2c5f6..c18496a1 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/max_buffer_tests.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/max_buffer_tests.rs @@ -4,60 +4,67 @@ use std::convert::TryFrom; use tss_esapi::structures::MaxBuffer; use tss_esapi::tss2_esys::{TPM2B_MAX_BUFFER, TPM2_MAX_DIGEST_BUFFER}; -mod test_auth { - use super::*; +const ABOVE_MAX: usize = TPM2_MAX_DIGEST_BUFFER as usize + 1; - const ABOVE_MAX: usize = TPM2_MAX_DIGEST_BUFFER as usize + 1; +#[test] +fn test_max_sized_data() { + let _ = MaxBuffer::try_from([0xff; TPM2_MAX_DIGEST_BUFFER as usize].to_vec()).unwrap(); +} - #[test] - fn test_max_sized_data() { - let _ = MaxBuffer::try_from([0xff; TPM2_MAX_DIGEST_BUFFER as usize].to_vec()).unwrap(); - } +#[test] +fn test_to_large_data() { + let _ = MaxBuffer::try_from([0xff; ABOVE_MAX].to_vec()).unwrap_err(); +} - #[test] - fn test_to_large_data() { - let _ = MaxBuffer::try_from([0xff; ABOVE_MAX].to_vec()).unwrap_err(); +#[test] +fn test_default() { + { + let max_buffer: MaxBuffer = Default::default(); + let expected: TPM2B_MAX_BUFFER = Default::default(); + let actual = TPM2B_MAX_BUFFER::from(max_buffer); + assert_eq!(expected.size, actual.size); + assert_eq!( + expected.buffer.len(), + actual.buffer.len(), + "Buffers don't have the same length" + ); + assert!( + expected + .buffer + .iter() + .zip(actual.buffer.iter()) + .all(|(a, b)| a == b), + "Buffers are not equal" + ); } - - #[test] - fn test_default() { - { - let max_buffer: MaxBuffer = Default::default(); - let expected: TPM2B_MAX_BUFFER = Default::default(); - let actual = TPM2B_MAX_BUFFER::from(max_buffer); - assert_eq!(expected.size, actual.size); - assert_eq!( - expected.buffer.len(), - actual.buffer.len(), - "Buffers don't have the same length" - ); - assert!( - expected - .buffer - .iter() - .zip(actual.buffer.iter()) - .all(|(a, b)| a == b), - "Buffers are not equal" - ); - } - { - let tss_max_buffer: TPM2B_MAX_BUFFER = Default::default(); - let expected: MaxBuffer = Default::default(); - let actual = MaxBuffer::try_from(tss_max_buffer).unwrap(); - assert_eq!(expected, actual); - } + { + let tss_max_buffer: TPM2B_MAX_BUFFER = Default::default(); + let expected: MaxBuffer = Default::default(); + let actual = MaxBuffer::try_from(tss_max_buffer).unwrap(); + assert_eq!(expected, actual); } +} - #[test] - fn test_as_ref() { - // The following function accepts the broadest selection of types as its argument - // including MaxBuffer. It also returns the MaxBuffer but in such a way that the - // client is not aware of the true underlying type. - fn accepts_returns_as_ref(data: impl AsRef<[u8]>) -> tss_esapi::Result> { - let data = data.as_ref(); - let max_buffer = MaxBuffer::from_bytes(data)?; - Ok(max_buffer) - } - accepts_returns_as_ref(MaxBuffer::from_bytes(&[1, 2, 3]).unwrap()).unwrap(); +#[test] +fn test_as_ref() { + // The following function accepts the broadest selection of types as its argument + // including MaxBuffer. It also returns the MaxBuffer but in such a way that the + // client is not aware of the true underlying type. + fn accepts_returns_as_ref(data: impl AsRef<[u8]>) -> tss_esapi::Result> { + let data = data.as_ref(); + let max_buffer = MaxBuffer::from_bytes(data)?; + Ok(max_buffer) } + accepts_returns_as_ref(MaxBuffer::from_bytes(&[1, 2, 3]).unwrap()).unwrap(); +} + +#[test] +fn test_max_sized_max_buffer_conversions() { + let expected_buffer = [0xffu8; MaxBuffer::MAX_SIZE]; + let native = MaxBuffer::try_from(expected_buffer.as_slice().to_vec()) + .expect("It should be possible to convert an array of MAX size into a MaxBuffer object."); + let tss = TPM2B_MAX_BUFFER::from(native); + assert_eq!(MaxBuffer::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_buffer, tss.buffer); } diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/mod.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/mod.rs index b43cfb06..99fdd1da 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/mod.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/mod.rs @@ -4,6 +4,9 @@ mod attest_buffer_tests; mod auth_tests; mod data_tests; mod digest_tests; +mod ecc_parameters_tests; +mod encrypted_secret_test; +mod id_object_tests; mod max_buffer_tests; mod nonce_tests; mod private; diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/nonce_tests.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/nonce_tests.rs index 5638fdba..1eb02e66 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/nonce_tests.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/nonce_tests.rs @@ -61,3 +61,14 @@ fn test_default() { assert_eq!(expected, actual); } } + +#[test] +fn test_max_sized_nonce_conversions() { + let expected_buffer = [0xffu8; Nonce::MAX_SIZE]; + let native = Nonce::try_from(expected_buffer.as_slice().to_vec()) + .expect("It should be possible to convert an array of MAX size into a Nonce object."); + let tss = TPM2B_NONCE::from(native); + assert_eq!(Nonce::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_buffer, tss.buffer); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/private.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/private.rs index c58c2147..fa010c83 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/private.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/private.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use std::convert::TryFrom; -use tss_esapi::structures::Private; +use tss_esapi::{structures::Private, tss2_esys::TPM2B_PRIVATE}; #[test] fn marshall_unmarshall() { @@ -25,3 +25,14 @@ fn marshall_unmarshall_offset() { let private = Private::try_from([0xff; 100].to_vec()).unwrap(); crate::common::check_marshall_unmarshall_offset(&private); } + +#[test] +fn test_max_sized_private_conversions() { + let expected_buffer = [0xffu8; Private::MAX_SIZE]; + let native = Private::try_from(expected_buffer.as_slice().to_vec()) + .expect("It should be possible to convert an array of MAX size into a Private object."); + let tss = TPM2B_PRIVATE::from(native); + assert_eq!(Private::MAX_SIZE, tss.size as usize); + // This will be a compiler error if the max size does not match the TSS buffer size. + assert_eq!(expected_buffer, tss.buffer); +}