Skip to content

Commit 4adbebe

Browse files
author
Nathan Rossi
committed
Add definition for NV_Extend
Add a implementation for NV_Extend, which is used with a NV Index defined with the NvIndexType::Extend to provide a PCR equivalent that uses NV memory. The hashing algorithm used is defined by the index name algorithm. An example and test are included for this function, setting up the NV index with the required type and typical attributes and performing an extend of the index and confirming the resulting hash value. Signed-off-by: Nathan Rossi <[email protected]>
1 parent a33e447 commit 4adbebe

File tree

1 file changed

+120
-3
lines changed

1 file changed

+120
-3
lines changed

tss-esapi/src/context/tpm_commands/non_volatile_storage.rs

Lines changed: 120 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use crate::{
66
interface_types::reserved_handles::{NvAuth, Provision},
77
structures::{Auth, MaxNvBuffer, Name, NvPublic},
88
tss2_esys::{
9-
Esys_NV_DefineSpace, Esys_NV_Increment, Esys_NV_Read, Esys_NV_ReadPublic,
10-
Esys_NV_UndefineSpace, Esys_NV_UndefineSpaceSpecial, Esys_NV_Write,
9+
Esys_NV_DefineSpace, Esys_NV_Extend, Esys_NV_Increment, Esys_NV_Read,
10+
Esys_NV_ReadPublic, Esys_NV_UndefineSpace, Esys_NV_UndefineSpaceSpecial,
11+
Esys_NV_Write,
1112
},
1213
Context, Result, ReturnCode,
1314
};
@@ -698,7 +699,123 @@ impl Context {
698699
)
699700
}
700701

701-
// Missing function: NV_Extend
702+
/// Extends data to the NV memory associated with a nv index.
703+
///
704+
/// # Details
705+
/// This method is used to extend a value to
706+
/// the nv memory in the TPM.
707+
///
708+
/// Please beware that this method requires an authorization
709+
/// session handle to be present.
710+
///
711+
/// # Arguments
712+
/// * `auth_handle` - Handle indicating the source of authorization value.
713+
/// * `nv_index_handle` - The [NvIndexHandle] associated with NV memory
714+
/// which will be extended by data hashed with the previous data.
715+
/// * `data` - The data, in the form of a [MaxNvBuffer], that is to be written.
716+
///
717+
/// # Example
718+
/// ```rust
719+
/// # use tss_esapi::{
720+
/// # Context, TctiNameConf, attributes::{SessionAttributes, NvIndexAttributes},
721+
/// # handles::NvIndexTpmHandle, interface_types::algorithm::HashingAlgorithm,
722+
/// # structures::{SymmetricDefinition, NvPublic},
723+
/// # constants::SessionType, constants::nv_index_type::NvIndexType,
724+
/// # };
725+
/// use tss_esapi::{
726+
/// interface_types::reserved_handles::{Provision, NvAuth}, structures::MaxNvBuffer,
727+
/// };
728+
///
729+
/// # // Create context
730+
/// # let mut context =
731+
/// # Context::new(
732+
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
733+
/// # ).expect("Failed to create Context");
734+
/// #
735+
/// # let session = context
736+
/// # .start_auth_session(
737+
/// # None,
738+
/// # None,
739+
/// # None,
740+
/// # SessionType::Hmac,
741+
/// # SymmetricDefinition::AES_256_CFB,
742+
/// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
743+
/// # )
744+
/// # .expect("Failed to create session")
745+
/// # .expect("Received invalid handle");
746+
/// # let (session_attributes, session_attributes_mask) = SessionAttributes::builder()
747+
/// # .with_decrypt(true)
748+
/// # .with_encrypt(true)
749+
/// # .build();
750+
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
751+
/// # .expect("Failed to set attributes on session");
752+
/// # context.set_sessions((Some(session), None, None));
753+
/// #
754+
/// # let nv_index = NvIndexTpmHandle::new(0x01500028)
755+
/// # .expect("Failed to create NV index tpm handle");
756+
/// #
757+
/// // Create NV index attributes
758+
/// let owner_nv_index_attributes = NvIndexAttributes::builder()
759+
/// .with_owner_write(true)
760+
/// .with_owner_read(true)
761+
/// .with_orderly(true)
762+
/// .with_nv_index_type(NvIndexType::Extend)
763+
/// .build()
764+
/// .expect("Failed to create owner nv index attributes");
765+
///
766+
/// // Create owner nv public.
767+
/// let owner_nv_public = NvPublic::builder()
768+
/// .with_nv_index(nv_index)
769+
/// .with_index_name_algorithm(HashingAlgorithm::Sha256)
770+
/// .with_index_attributes(owner_nv_index_attributes)
771+
/// .with_data_area_size(32)
772+
/// .build()
773+
/// .expect("Failed to build NvPublic for owner");
774+
///
775+
/// let nv_index_handle = context
776+
/// .nv_define_space(Provision::Owner, None, owner_nv_public.clone())
777+
/// .expect("Call to nv_define_space failed");
778+
///
779+
/// let data = MaxNvBuffer::try_from(vec![0x0]).unwrap();
780+
/// let result = context.nv_extend(NvAuth::Owner, nv_index_handle, data);
781+
///
782+
/// # let nv_read_result = context
783+
/// # .nv_read(NvAuth::Owner, nv_index_handle, 32, 0);
784+
/// # let read_data = nv_read_result.expect("Call to nv_read failed");
785+
/// # // expected value is sha256([0; 32] + [0; 1])
786+
/// # assert_eq!([
787+
/// # 0x7f, 0x9c, 0x9e, 0x31, 0xac, 0x82, 0x56, 0xca,
788+
/// # 0x2f, 0x25, 0x85, 0x83, 0xdf, 0x26, 0x2d, 0xbc,
789+
/// # 0x7d, 0x6f, 0x68, 0xf2, 0xa0, 0x30, 0x43, 0xd5,
790+
/// # 0xc9, 0x9a, 0x4a, 0xe5, 0xa7, 0x39, 0x6c, 0xe9],
791+
/// # read_data.as_ref());
792+
/// #
793+
/// # context
794+
/// # .nv_undefine_space(Provision::Owner, nv_index_handle)
795+
/// # .expect("Call to nv_undefine_space failed");
796+
/// ```
797+
pub fn nv_extend(
798+
&mut self,
799+
auth_handle: NvAuth,
800+
nv_index_handle: NvIndexHandle,
801+
data: MaxNvBuffer,
802+
) -> Result<()> {
803+
ReturnCode::ensure_success(
804+
unsafe {
805+
Esys_NV_Extend(
806+
self.mut_context(),
807+
AuthHandle::from(auth_handle).into(),
808+
nv_index_handle.into(),
809+
self.required_session_1()?,
810+
self.optional_session_2(),
811+
self.optional_session_3(),
812+
&data.into(),
813+
)
814+
},
815+
|ret| error!("Error when extending NV: {:#010X}", ret),
816+
)
817+
}
818+
702819
// Missing function: NV_SetBits
703820
// Missing function: NV_WriteLock
704821
// Missing function: NV_GlobalWriteLock

0 commit comments

Comments
 (0)