Skip to content

Commit 014cae7

Browse files
authored
Merge pull request #486 from gomesj/main
ea_commands: add policy_authorize_nv
2 parents aa12b81 + 7a74f8f commit 014cae7

File tree

4 files changed

+254
-59
lines changed

4 files changed

+254
-59
lines changed

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

Lines changed: 137 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
use crate::{
44
attributes::LocalityAttributes,
55
constants::CommandCode,
6-
handles::{AuthHandle, ObjectHandle, SessionHandle},
7-
interface_types::{session_handles::PolicySession, YesNo},
6+
handles::{AuthHandle, NvIndexHandle, ObjectHandle, SessionHandle},
7+
interface_types::{resource_handles::NvAuth, session_handles::PolicySession, YesNo},
88
structures::{
99
AuthTicket, Digest, DigestList, Name, Nonce, PcrSelectionList, Signature, Timeout,
1010
VerifiedTicket,
1111
},
1212
tss2_esys::{
13-
Esys_PolicyAuthValue, Esys_PolicyAuthorize, Esys_PolicyCommandCode, Esys_PolicyCpHash,
14-
Esys_PolicyDuplicationSelect, Esys_PolicyGetDigest, Esys_PolicyLocality,
13+
Esys_PolicyAuthValue, Esys_PolicyAuthorize, Esys_PolicyAuthorizeNV, Esys_PolicyCommandCode,
14+
Esys_PolicyCpHash, Esys_PolicyDuplicationSelect, Esys_PolicyGetDigest, Esys_PolicyLocality,
1515
Esys_PolicyNameHash, Esys_PolicyNvWritten, Esys_PolicyOR, Esys_PolicyPCR,
1616
Esys_PolicyPassword, Esys_PolicyPhysicalPresence, Esys_PolicySecret, Esys_PolicySigned,
1717
Esys_PolicyTemplate,
@@ -593,5 +593,137 @@ impl Context {
593593
},
594594
)
595595
}
596-
// Missing function: PolicyAuthorizeNV
596+
597+
/// Cause conditional gating of a policy based on an authorized policy
598+
/// stored in non-volatile memory.
599+
///
600+
/// # Arguments
601+
/// * `policy_session` - The [policy session][PolicySession] being extended.
602+
/// * `auth_handle` - Handle indicating the source of authorization value.
603+
/// * `nv_index_handle` - The [NvIndexHandle] associated with NV memory
604+
/// where the policy is stored.
605+
///
606+
/// # Example
607+
/// ```rust
608+
/// # use std::convert::TryFrom;
609+
/// # use tss_esapi::attributes::{NvIndexAttributes, SessionAttributes};
610+
/// # use tss_esapi::constants::SessionType;
611+
/// # use tss_esapi::handles::NvIndexTpmHandle;
612+
/// # use tss_esapi::interface_types::{
613+
/// # algorithm::HashingAlgorithm,
614+
/// # resource_handles::{NvAuth, Provision},
615+
/// # session_handles::PolicySession,
616+
/// # };
617+
/// # use tss_esapi::structures::{NvPublic, SymmetricDefinition};
618+
/// # use tss_esapi::{Context, TctiNameConf};
619+
/// #
620+
/// # let mut context = // ...
621+
/// # Context::new(
622+
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
623+
/// # ).expect("Failed to create Context");
624+
/// #
625+
/// # // Set owner session for NV space definition
626+
/// # let owner_auth_session = context
627+
/// # .start_auth_session(
628+
/// # None,
629+
/// # None,
630+
/// # None,
631+
/// # SessionType::Hmac,
632+
/// # SymmetricDefinition::AES_256_CFB,
633+
/// # tss_esapi::interface_types::algorithm::HashingAlgorithm::Sha256,
634+
/// # )
635+
/// # .expect("Failed to create session")
636+
/// # .expect("Received invalid handle");
637+
/// # let (session_attributes, session_attributes_mask) = SessionAttributes::builder()
638+
/// # .with_decrypt(true)
639+
/// # .with_encrypt(true)
640+
/// # .build();
641+
/// # context.tr_sess_set_attributes(owner_auth_session, session_attributes, session_attributes_mask)
642+
/// # .expect("Failed to set attributes on session");
643+
/// # context.set_sessions((Some(owner_auth_session), None, None));
644+
/// #
645+
/// # let trial_session = context
646+
/// # .start_auth_session(
647+
/// # None,
648+
/// # None,
649+
/// # None,
650+
/// # SessionType::Trial,
651+
/// # SymmetricDefinition::AES_256_CFB,
652+
/// # HashingAlgorithm::Sha256,
653+
/// # )
654+
/// # .expect("Start auth session failed")
655+
/// # .expect("Start auth session returned a NONE handle");
656+
/// #
657+
/// # let (policy_auth_session_attributes, policy_auth_session_attributes_mask) =
658+
/// # SessionAttributes::builder()
659+
/// # .with_decrypt(true)
660+
/// # .with_encrypt(true)
661+
/// # .build();
662+
/// # context
663+
/// # .tr_sess_set_attributes(
664+
/// # trial_session,
665+
/// # policy_auth_session_attributes,
666+
/// # policy_auth_session_attributes_mask,
667+
/// # )
668+
/// # .expect("tr_sess_set_attributes call failed");
669+
/// #
670+
/// # let policy_session = PolicySession::try_from(trial_session)
671+
/// # .expect("Failed to convert auth session into policy session");
672+
/// #
673+
/// # let nv_index = NvIndexTpmHandle::new(0x01500600)
674+
/// # .expect("Failed to create NV index tpm handle");
675+
/// #
676+
/// # // Create NV index attributes
677+
/// # let owner_nv_index_attributes = NvIndexAttributes::builder()
678+
/// # .with_owner_write(true)
679+
/// # .with_owner_read(true)
680+
/// # .build()
681+
/// # .expect("Failed to create owner nv index attributes");
682+
/// #
683+
/// # // Create owner nv public.
684+
/// # let owner_nv_public = NvPublic::builder()
685+
/// # .with_nv_index(nv_index)
686+
/// # .with_index_name_algorithm(HashingAlgorithm::Sha256)
687+
/// # .with_index_attributes(owner_nv_index_attributes)
688+
/// # .with_data_area_size(32)
689+
/// # .build()
690+
/// # .expect("Failed to build NvPublic for owner");
691+
/// #
692+
/// let nv_index_handle = context
693+
/// .nv_define_space(Provision::Owner, None, owner_nv_public)
694+
/// .expect("Call to nv_define_space failed");
695+
///
696+
/// context.policy_authorize_nv(
697+
/// policy_session,
698+
/// NvAuth::Owner,
699+
/// nv_index_handle,
700+
/// ).expect("failed to extend policy with policy_authorize_nv");;
701+
/// #
702+
/// # context
703+
/// # .nv_undefine_space(Provision::Owner, nv_index_handle)
704+
/// # .expect("Call to nv_undefine_space failed");
705+
/// ```
706+
pub fn policy_authorize_nv(
707+
&mut self,
708+
policy_session: PolicySession,
709+
auth_handle: NvAuth,
710+
nv_index_handle: NvIndexHandle,
711+
) -> Result<()> {
712+
ReturnCode::ensure_success(
713+
unsafe {
714+
Esys_PolicyAuthorizeNV(
715+
self.mut_context(),
716+
AuthHandle::from(auth_handle).into(),
717+
nv_index_handle.into(),
718+
SessionHandle::from(policy_session).into(),
719+
self.optional_session_1(),
720+
self.optional_session_2(),
721+
self.optional_session_3(),
722+
)
723+
},
724+
|ret| {
725+
error!("Error when computing policy authorize NV: {:#010X}", ret);
726+
},
727+
)
728+
}
597729
}

tss-esapi/tests/integration_tests/abstraction_tests/nv_tests.rs

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
// Copyright 2020 Contributors to the Parsec project.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::{
5-
convert::TryFrom,
6-
io::{ErrorKind, Seek, SeekFrom, Write},
7-
};
4+
use std::io::{ErrorKind, Seek, SeekFrom, Write};
85
use tss_esapi::{
96
abstraction::nv,
107
attributes::NvIndexAttributesBuilder,
@@ -13,52 +10,10 @@ use tss_esapi::{
1310
algorithm::HashingAlgorithm,
1411
resource_handles::{NvAuth, Provision},
1512
},
16-
structures::{MaxNvBuffer, NvPublicBuilder},
17-
Context,
13+
structures::NvPublicBuilder,
1814
};
1915

20-
use crate::common::create_ctx_with_session;
21-
22-
fn write_nv_index(context: &mut Context, nv_index: NvIndexTpmHandle) -> NvIndexHandle {
23-
// Create owner nv public.
24-
let owner_nv_index_attributes = NvIndexAttributesBuilder::new()
25-
.with_owner_write(true)
26-
.with_owner_read(true)
27-
.with_pp_read(true)
28-
.with_owner_read(true)
29-
.build()
30-
.expect("Failed to create owner nv index attributes");
31-
32-
let owner_nv_public = NvPublicBuilder::new()
33-
.with_nv_index(nv_index)
34-
.with_index_name_algorithm(HashingAlgorithm::Sha256)
35-
.with_index_attributes(owner_nv_index_attributes)
36-
.with_data_area_size(1540)
37-
.build()
38-
.unwrap();
39-
40-
let owner_nv_index_handle = context
41-
.nv_define_space(Provision::Owner, None, owner_nv_public)
42-
.unwrap();
43-
44-
let value = [1, 2, 3, 4, 5, 6, 7];
45-
let expected_data = MaxNvBuffer::try_from(value.to_vec()).unwrap();
46-
47-
// Write the data using Owner authorization
48-
context
49-
.nv_write(
50-
NvAuth::Owner,
51-
owner_nv_index_handle,
52-
expected_data.clone(),
53-
0,
54-
)
55-
.unwrap();
56-
context
57-
.nv_write(NvAuth::Owner, owner_nv_index_handle, expected_data, 1024)
58-
.unwrap();
59-
60-
owner_nv_index_handle
61-
}
16+
use crate::common::{create_ctx_with_session, write_nv_index};
6217

6318
#[test]
6419
fn list() {

tss-esapi/tests/integration_tests/common/mod.rs

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,24 @@ use std::{
1010
use tss_esapi::{
1111
abstraction::{cipher::Cipher, pcr::PcrData},
1212
attributes::ObjectAttributes,
13-
attributes::{ObjectAttributesBuilder, SessionAttributesBuilder},
13+
attributes::{NvIndexAttributesBuilder, ObjectAttributesBuilder, SessionAttributesBuilder},
1414
constants::SessionType,
15+
handles::{NvIndexHandle, NvIndexTpmHandle},
1516
interface_types::{
1617
algorithm::SymmetricMode,
1718
algorithm::{HashingAlgorithm, PublicAlgorithm, RsaSchemeAlgorithm},
1819
key_bits::RsaKeyBits,
1920
key_bits::{AesKeyBits, Sm4KeyBits},
20-
resource_handles::Hierarchy,
21+
resource_handles::{Hierarchy, NvAuth, Provision},
2122
session_handles::PolicySession,
2223
},
2324
structures::{
2425
Digest, EccParameter, EccPoint, EccScheme, EccSignature, HashAgile, HashScheme, HmacScheme,
25-
KeyDerivationFunctionScheme, KeyedHashScheme, MaxBuffer, PcrSelectionListBuilder, PcrSlot,
26-
Public, PublicBuilder, PublicEccParameters, PublicKeyRsa, PublicKeyedHashParameters,
27-
PublicRsaParameters, RsaExponent, RsaScheme, RsaSignature, Sensitive, Signature,
28-
SymmetricCipherParameters, SymmetricDefinition, SymmetricDefinitionObject,
26+
KeyDerivationFunctionScheme, KeyedHashScheme, MaxBuffer, MaxNvBuffer, NvPublicBuilder,
27+
PcrSelectionListBuilder, PcrSlot, Public, PublicBuilder, PublicEccParameters, PublicKeyRsa,
28+
PublicKeyedHashParameters, PublicRsaParameters, RsaExponent, RsaScheme, RsaSignature,
29+
Sensitive, Signature, SymmetricCipherParameters, SymmetricDefinition,
30+
SymmetricDefinitionObject,
2931
},
3032
tcti_ldr::TctiNameConf,
3133
utils, Context,
@@ -432,3 +434,44 @@ pub fn create_public_sealed_object() -> Public {
432434
.build()
433435
.expect("Failed to create public structure.")
434436
}
437+
438+
pub fn write_nv_index(context: &mut Context, nv_index: NvIndexTpmHandle) -> NvIndexHandle {
439+
// Create owner nv public.
440+
let owner_nv_index_attributes = NvIndexAttributesBuilder::new()
441+
.with_owner_write(true)
442+
.with_owner_read(true)
443+
.with_pp_read(true)
444+
.with_owner_read(true)
445+
.build()
446+
.expect("Failed to create owner nv index attributes");
447+
448+
let owner_nv_public = NvPublicBuilder::new()
449+
.with_nv_index(nv_index)
450+
.with_index_name_algorithm(HashingAlgorithm::Sha256)
451+
.with_index_attributes(owner_nv_index_attributes)
452+
.with_data_area_size(1540)
453+
.build()
454+
.unwrap();
455+
456+
let owner_nv_index_handle = context
457+
.nv_define_space(Provision::Owner, None, owner_nv_public)
458+
.unwrap();
459+
460+
let value = [1, 2, 3, 4, 5, 6, 7];
461+
let expected_data = MaxNvBuffer::try_from(value.to_vec()).unwrap();
462+
463+
// Write the data using Owner authorization
464+
context
465+
.nv_write(
466+
NvAuth::Owner,
467+
owner_nv_index_handle,
468+
expected_data.clone(),
469+
0,
470+
)
471+
.unwrap();
472+
context
473+
.nv_write(NvAuth::Owner, owner_nv_index_handle, expected_data, 1024)
474+
.unwrap();
475+
476+
owner_nv_index_handle
477+
}

tss-esapi/tests/integration_tests/context_tests/tpm_commands/enhanced_authorization_ea_commands_tests.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,3 +894,68 @@ mod test_policy_template {
894894
assert_eq!(expected_policy_template, policy_digest);
895895
}
896896
}
897+
898+
mod test_policy_authorize_nv {
899+
use crate::common::{create_ctx_with_session, write_nv_index};
900+
use std::convert::TryFrom;
901+
use tss_esapi::{
902+
attributes::SessionAttributesBuilder,
903+
constants::SessionType,
904+
handles::{NvIndexHandle, NvIndexTpmHandle},
905+
interface_types::{
906+
algorithm::HashingAlgorithm,
907+
resource_handles::{NvAuth, Provision},
908+
session_handles::PolicySession,
909+
},
910+
structures::SymmetricDefinition,
911+
};
912+
913+
#[test]
914+
fn test_policy_authorize_nv() {
915+
let mut context = create_ctx_with_session();
916+
let trial_policy_auth_session = context
917+
.start_auth_session(
918+
None,
919+
None,
920+
None,
921+
SessionType::Trial,
922+
SymmetricDefinition::AES_256_CFB,
923+
HashingAlgorithm::Sha256,
924+
)
925+
.expect("Start auth session failed")
926+
.expect("Start auth session returned a NONE handle");
927+
let (trial_policy_auth_session_attributes, trial_policy_auth_session_attributes_mask) =
928+
SessionAttributesBuilder::new()
929+
.with_decrypt(true)
930+
.with_encrypt(true)
931+
.build();
932+
933+
let nv_index = NvIndexTpmHandle::new(0x01500500).unwrap();
934+
let initial_owner_nv_index_handle = write_nv_index(&mut context, nv_index);
935+
936+
context
937+
.tr_sess_set_attributes(
938+
trial_policy_auth_session,
939+
trial_policy_auth_session_attributes,
940+
trial_policy_auth_session_attributes_mask,
941+
)
942+
.expect("tr_sess_set_attributes call failed");
943+
let trial_policy_session = PolicySession::try_from(trial_policy_auth_session)
944+
.expect("Failed to convert auth session into policy session");
945+
// There should be no algorithm prefix error or actual NV content check for a TRIAL session
946+
let policy_result = context.policy_authorize_nv(
947+
trial_policy_session,
948+
NvAuth::Owner,
949+
initial_owner_nv_index_handle,
950+
);
951+
952+
let owner_nv_index_handle = context
953+
.tr_from_tpm_public(nv_index.into())
954+
.map_or_else(|_| initial_owner_nv_index_handle, NvIndexHandle::from);
955+
context
956+
.nv_undefine_space(Provision::Owner, owner_nv_index_handle)
957+
.expect("Call to nv_undefine_space failed");
958+
959+
policy_result.unwrap();
960+
}
961+
}

0 commit comments

Comments
 (0)