Skip to content

Commit cff43aa

Browse files
authored
Merge pull request #476 from Superhepper/null-hash-ticket
Fixes problem with sign requiring a HashcheckTicket.
2 parents 3fa7ae2 + 13f06e0 commit cff43aa

File tree

5 files changed

+81
-66
lines changed

5 files changed

+81
-66
lines changed

tss-esapi/src/abstraction/transient/mod.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
//! client.
99
use crate::{
1010
attributes::{ObjectAttributesBuilder, SessionAttributesBuilder},
11-
constants::{tss::*, SessionType, TpmFormatZeroError},
11+
constants::{SessionType, TpmFormatZeroError},
1212
error::{TpmFormatZeroResponseCode, TpmResponseCode},
1313
handles::{KeyHandle, SessionHandle},
1414
interface_types::{
@@ -23,7 +23,6 @@ use crate::{
2323
RsaScheme, Signature, SignatureScheme, SymmetricDefinitionObject, VerifiedTicket,
2424
},
2525
tcti_ldr::TctiNameConf,
26-
tss2_esys::*,
2726
utils::{create_restricted_decryption_rsa_public, PublicKey, TpmsContext},
2827
Context, Error, Result, ReturnCode, WrapperErrorKind as ErrorKind,
2928
};
@@ -287,20 +286,10 @@ impl TransientKeyContext {
287286
) -> Result<Signature> {
288287
let key_handle = self.load_key(key_params, key_material, key_auth)?;
289288

290-
let validation = TPMT_TK_HASHCHECK {
291-
tag: TPM2_ST_HASHCHECK,
292-
hierarchy: TPM2_RH_NULL,
293-
digest: Default::default(),
294-
};
295289
self.set_session_attrs()?;
296290
let signature = self
297291
.context
298-
.sign(
299-
key_handle,
300-
digest,
301-
SignatureScheme::Null,
302-
validation.try_into()?,
303-
)
292+
.sign(key_handle, digest, SignatureScheme::Null, None)
304293
.or_else(|e| {
305294
self.context.flush_context(key_handle.into())?;
306295
Err(e)

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

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,66 @@ impl Context {
4040
}
4141

4242
/// Sign a digest with a key present in the TPM and return the signature.
43+
///
44+
/// # Details
45+
/// For signatures using a restricted key, a hashcheck must be provided. For unrestricted keys, this may be None.
46+
///
47+
/// # Parameters
48+
/// `key_handle` - Handle to the key be used for signing.
49+
/// `digest` - The digest that is going to be signed.
50+
/// `scheme` - The scheme to use if the scheme for the key referenced by the key handle is null.
51+
/// `validation` - An optional [HashcheckTicket] that proof that the digest was created by the TPM.
52+
/// N.B. None will be treated as a "Null ticket".
53+
/// # Example
54+
///
55+
/// ```rust
56+
/// # use tss_esapi::{Context, TctiNameConf,
57+
/// # interface_types::{
58+
/// # algorithm::{HashingAlgorithm, RsaSchemeAlgorithm},
59+
/// # key_bits::RsaKeyBits,
60+
/// # resource_handles::Hierarchy,
61+
/// # },
62+
/// # structures::{RsaScheme, RsaExponent},
63+
/// # utils::create_unrestricted_signing_rsa_public
64+
/// # };
65+
/// use tss_esapi::structures::SignatureScheme;
66+
/// # let mut context =
67+
/// # Context::new(
68+
/// # TctiNameConf::from_environment_variable().expect("Failed to get TCTI"),
69+
/// # ).expect("Failed to create Context");
70+
/// # let signing_key_pub = create_unrestricted_signing_rsa_public(
71+
/// # RsaScheme::create(RsaSchemeAlgorithm::RsaSsa, Some(HashingAlgorithm::Sha256))
72+
/// # .expect("Failed to create RSA scheme"),
73+
/// # RsaKeyBits::Rsa2048,
74+
/// # RsaExponent::default(),
75+
/// # )
76+
/// # .expect("Failed to create an unrestricted signing rsa public structure");
77+
/// # let unrestricted_signing_key_handle = context
78+
/// # .execute_with_nullauth_session(|ctx| {
79+
/// # ctx.create_primary(Hierarchy::Owner, signing_key_pub, None, None, None, None)
80+
/// # })
81+
/// # .unwrap()
82+
/// # .key_handle;
83+
/// # let digest = context.get_random(32).unwrap();
84+
/// let signature = context.execute_with_nullauth_session(|ctx| {
85+
/// ctx.sign(
86+
/// unrestricted_signing_key_handle,
87+
/// digest,
88+
/// SignatureScheme::Null,
89+
/// None,
90+
/// )
91+
/// })
92+
/// .expect("Failed to sign digest");
93+
/// ```
4394
pub fn sign(
4495
&mut self,
4596
key_handle: KeyHandle,
4697
digest: Digest,
4798
scheme: SignatureScheme,
48-
validation: HashcheckTicket,
99+
validation: impl Into<Option<HashcheckTicket>>,
49100
) -> Result<Signature> {
50101
let mut signature_ptr = null_mut();
102+
let validation_ticket = validation.into().unwrap_or_default().try_into()?;
51103
ReturnCode::ensure_success(
52104
unsafe {
53105
Esys_Sign(
@@ -58,7 +110,7 @@ impl Context {
58110
self.optional_session_3(),
59111
&digest.into(),
60112
&scheme.into(),
61-
&validation.try_into()?,
113+
&validation_ticket,
62114
&mut signature_ptr,
63115
)
64116
},

tss-esapi/src/structures/tickets.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use crate::{
1111
};
1212

1313
use log::error;
14-
use std::convert::{TryFrom, TryInto};
14+
use std::{
15+
convert::{TryFrom, TryInto},
16+
default::Default,
17+
};
1518

1619
/// Macro used for implementing try_from
1720
/// TssTicketType -> TicketType
@@ -124,6 +127,17 @@ pub struct HashcheckTicket {
124127
digest: Vec<u8>,
125128
}
126129

130+
impl Default for HashcheckTicket {
131+
/// The default for the Hashcheck ticket is the Null ticket.
132+
fn default() -> Self {
133+
Self {
134+
tag: StructureTag::Hashcheck,
135+
hierarchy: Hierarchy::Null,
136+
digest: Vec::<u8>::new(),
137+
}
138+
}
139+
}
140+
127141
impl Ticket for HashcheckTicket {
128142
/// The tag of the verified ticket.
129143
const POSSIBLE_TAGS: &'static [StructureTag] = &[StructureTag::Hashcheck];

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

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,11 @@ mod test_policy_name_hash {
527527

528528
mod test_policy_authorize {
529529
use crate::common::{create_ctx_with_session, get_pcr_policy_digest, signing_key_pub};
530-
use std::convert::{TryFrom, TryInto};
530+
use std::convert::TryFrom;
531531
use tss_esapi::{
532-
constants::tss::{TPM2_RH_NULL, TPM2_ST_HASHCHECK},
533532
interface_types::{algorithm::HashingAlgorithm, resource_handles::Hierarchy},
534533
structures::{Auth, MaxBuffer, Nonce, SignatureScheme},
535-
tss2_esys::{TPM2B_NONCE, TPMT_TK_HASHCHECK},
534+
tss2_esys::TPM2B_NONCE,
536535
};
537536
#[test]
538537
fn test_policy_authorize() {
@@ -566,19 +565,9 @@ mod test_policy_authorize {
566565
.unwrap()
567566
.0;
568567

569-
let validation = TPMT_TK_HASHCHECK {
570-
tag: TPM2_ST_HASHCHECK,
571-
hierarchy: TPM2_RH_NULL,
572-
digest: Default::default(),
573-
};
574568
// A signature over just the policy_digest, since the policy_ref is empty
575569
let signature = context
576-
.sign(
577-
key_handle,
578-
ahash.clone(),
579-
SignatureScheme::Null,
580-
validation.try_into().unwrap(),
581-
)
570+
.sign(key_handle, ahash.clone(), SignatureScheme::Null, None)
582571
.unwrap();
583572
let tkt = context
584573
.verify_signature(key_handle, ahash, signature)

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

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
// SPDX-License-Identifier: Apache-2.0
33
mod test_verify_signature {
44
use crate::common::{create_ctx_with_session, signing_key_pub, HASH};
5-
use std::convert::{TryFrom, TryInto};
5+
use std::convert::TryFrom;
66
use tss_esapi::{
7-
constants::tss::{TPM2_RH_NULL, TPM2_ST_HASHCHECK},
87
interface_types::{algorithm::HashingAlgorithm, resource_handles::Hierarchy},
98
structures::{Auth, Digest, PublicKeyRsa, RsaSignature, Signature, SignatureScheme},
10-
tss2_esys::TPMT_TK_HASHCHECK,
119
};
1210

1311
#[test]
@@ -28,17 +26,12 @@ mod test_verify_signature {
2826
.unwrap()
2927
.key_handle;
3028

31-
let validation = TPMT_TK_HASHCHECK {
32-
tag: TPM2_ST_HASHCHECK,
33-
hierarchy: TPM2_RH_NULL,
34-
digest: Default::default(),
35-
};
3629
let signature = context
3730
.sign(
3831
key_handle,
3932
Digest::try_from(HASH[..32].to_vec()).unwrap(),
4033
SignatureScheme::Null,
41-
validation.try_into().unwrap(),
34+
None,
4235
)
4336
.unwrap();
4437

@@ -69,17 +62,12 @@ mod test_verify_signature {
6962
.unwrap()
7063
.key_handle;
7164

72-
let validation = TPMT_TK_HASHCHECK {
73-
tag: TPM2_ST_HASHCHECK,
74-
hierarchy: TPM2_RH_NULL,
75-
digest: Default::default(),
76-
};
7765
let mut signature = context
7866
.sign(
7967
key_handle,
8068
Digest::try_from(HASH[..32].to_vec()).unwrap(),
8169
SignatureScheme::Null,
82-
validation.try_into().unwrap(),
70+
None,
8371
)
8472
.unwrap();
8573

@@ -176,12 +164,10 @@ mod test_verify_signature {
176164

177165
mod test_sign {
178166
use crate::common::{create_ctx_with_session, signing_key_pub, HASH};
179-
use std::convert::{TryFrom, TryInto};
167+
use std::convert::TryFrom;
180168
use tss_esapi::{
181-
constants::tss::{TPM2_RH_NULL, TPM2_ST_HASHCHECK},
182169
interface_types::resource_handles::Hierarchy,
183170
structures::{Auth, Digest, SignatureScheme},
184-
tss2_esys::TPMT_TK_HASHCHECK,
185171
};
186172

187173
#[test]
@@ -202,17 +188,12 @@ mod test_sign {
202188
.unwrap()
203189
.key_handle;
204190

205-
let validation = TPMT_TK_HASHCHECK {
206-
tag: TPM2_ST_HASHCHECK,
207-
hierarchy: TPM2_RH_NULL,
208-
digest: Default::default(),
209-
};
210191
context
211192
.sign(
212193
key_handle,
213194
Digest::try_from(HASH[..32].to_vec()).unwrap(),
214195
SignatureScheme::Null,
215-
validation.try_into().unwrap(),
196+
None,
216197
)
217198
.unwrap();
218199
}
@@ -235,17 +216,12 @@ mod test_sign {
235216
.unwrap()
236217
.key_handle;
237218

238-
let validation = TPMT_TK_HASHCHECK {
239-
tag: TPM2_ST_HASHCHECK,
240-
hierarchy: TPM2_RH_NULL,
241-
digest: Default::default(),
242-
};
243219
context
244220
.sign(
245221
key_handle,
246222
Digest::try_from(Vec::<u8>::new()).unwrap(),
247223
SignatureScheme::Null,
248-
validation.try_into().unwrap(),
224+
None,
249225
)
250226
.unwrap_err();
251227
}
@@ -268,17 +244,12 @@ mod test_sign {
268244
.unwrap()
269245
.key_handle;
270246

271-
let validation = TPMT_TK_HASHCHECK {
272-
tag: TPM2_ST_HASHCHECK,
273-
hierarchy: TPM2_RH_NULL,
274-
digest: Default::default(),
275-
};
276247
context
277248
.sign(
278249
key_handle,
279250
Digest::try_from([0xbb; 40].to_vec()).unwrap(),
280251
SignatureScheme::Null,
281-
validation.try_into().unwrap(),
252+
None,
282253
)
283254
.unwrap_err();
284255
}

0 commit comments

Comments
 (0)