Skip to content

Commit 309e699

Browse files
committed
ek, ak abstractions: allow to specficy exact key type
This adds support other keys than RSA2048 and ECC Nist P256. Signed-off-by: Thore Sommer <[email protected]>
1 parent 1e04007 commit 309e699

File tree

7 files changed

+145
-61
lines changed

7 files changed

+145
-61
lines changed

tss-esapi/src/abstraction/ak.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ use crate::{
88
handles::{AuthHandle, KeyHandle, SessionHandle},
99
interface_types::{
1010
algorithm::{
11-
AsymmetricAlgorithm, EccSchemeAlgorithm, HashingAlgorithm, PublicAlgorithm,
11+
AsymmetricAlgorithmSelection, EccSchemeAlgorithm, HashingAlgorithm, PublicAlgorithm,
1212
RsaSchemeAlgorithm, SignatureSchemeAlgorithm,
1313
},
14-
ecc::EccCurve,
15-
key_bits::RsaKeyBits,
1614
session_handles::PolicySession,
1715
},
1816
structures::{
@@ -22,11 +20,10 @@ use crate::{
2220
},
2321
Context, Error, Result, WrapperErrorKind,
2422
};
25-
use log::error;
2623
use std::convert::{TryFrom, TryInto};
2724

2825
fn create_ak_public<IKC: IntoKeyCustomization>(
29-
key_alg: AsymmetricAlgorithm,
26+
key_alg: AsymmetricAlgorithmSelection,
3027
hash_alg: HashingAlgorithm,
3128
sign_alg: SignatureSchemeAlgorithm,
3229
key_customization: IKC,
@@ -50,7 +47,7 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
5047
.build()?;
5148

5249
let key_builder = match key_alg {
53-
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
50+
AsymmetricAlgorithmSelection::Rsa(key_bits) => PublicBuilder::new()
5451
.with_public_algorithm(PublicAlgorithm::Rsa)
5552
.with_name_hashing_algorithm(hash_alg)
5653
.with_object_attributes(obj_attrs)
@@ -60,15 +57,15 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
6057
RsaSchemeAlgorithm::try_from(AlgorithmIdentifier::from(sign_alg))?,
6158
Some(hash_alg),
6259
)?)
63-
.with_key_bits(RsaKeyBits::Rsa2048)
60+
.with_key_bits(key_bits)
6461
.with_exponent(RsaExponent::default())
6562
.with_is_signing_key(obj_attrs.sign_encrypt())
6663
.with_is_decryption_key(obj_attrs.decrypt())
6764
.with_restricted(obj_attrs.restricted())
6865
.build()?,
6966
)
7067
.with_rsa_unique_identifier(PublicKeyRsa::default()),
71-
AsymmetricAlgorithm::Ecc => PublicBuilder::new()
68+
AsymmetricAlgorithmSelection::Ecc(ecc_curve) => PublicBuilder::new()
7269
.with_public_algorithm(PublicAlgorithm::Ecc)
7370
.with_name_hashing_algorithm(hash_alg)
7471
.with_object_attributes(obj_attrs)
@@ -80,14 +77,10 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
8077
Some(hash_alg),
8178
Some(0),
8279
)?)
83-
.with_curve(EccCurve::NistP192)
80+
.with_curve(ecc_curve)
8481
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
8582
.build()?,
8683
),
87-
AsymmetricAlgorithm::Null => {
88-
// TODO: Figure out what to with Null.
89-
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
90-
}
9184
};
9285

9386
let key_builder = if let Some(ref k) = key_customization {
@@ -160,16 +153,11 @@ pub fn create_ak<IKC: IntoKeyCustomization>(
160153
context: &mut Context,
161154
parent: KeyHandle,
162155
hash_alg: HashingAlgorithm,
156+
key_alg: AsymmetricAlgorithmSelection,
163157
sign_alg: SignatureSchemeAlgorithm,
164158
ak_auth_value: Option<Auth>,
165159
key_customization: IKC,
166160
) -> Result<CreateKeyResult> {
167-
let key_alg = AsymmetricAlgorithm::try_from(sign_alg).map_err(|e| {
168-
// sign_alg is either HMAC or Null.
169-
error!("Could not retrieve asymmetric algorithm for provided signature scheme");
170-
e
171-
})?;
172-
173161
let ak_pub = create_ak_public(key_alg, hash_alg, sign_alg, key_customization)?;
174162

175163
let policy_auth_session = context

tss-esapi/src/abstraction/ek.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
attributes::ObjectAttributesBuilder,
77
handles::{KeyHandle, NvIndexTpmHandle, TpmHandle},
88
interface_types::{
9-
algorithm::{AsymmetricAlgorithm, HashingAlgorithm, PublicAlgorithm},
9+
algorithm::{AsymmetricAlgorithmSelection, HashingAlgorithm, PublicAlgorithm},
1010
ecc::EccCurve,
1111
key_bits::RsaKeyBits,
1212
resource_handles::{Hierarchy, NvAuth},
@@ -24,12 +24,20 @@ use std::convert::TryFrom;
2424
const RSA_2048_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c00002;
2525
const ECC_P256_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0000a;
2626

27+
// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
28+
// Section 2.2.1.5 (High Range)
29+
const ECC_P384_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c00016;
30+
const ECC_P521_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c00018;
31+
const ECC_P256_SM2_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0001a;
32+
const RSA_3072_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0001c;
33+
const RSA_4096_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0001e;
34+
2735
/// Get the [`Public`] representing a default Endorsement Key
2836
///
2937
/// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
3038
/// Appendix B.3.3 and B.3.4
3139
pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
32-
alg: AsymmetricAlgorithm,
40+
alg: AsymmetricAlgorithmSelection,
3341
key_customization: IKC,
3442
) -> Result<Public> {
3543
let key_customization = key_customization.into_key_customization();
@@ -65,7 +73,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
6573
];
6674

6775
let key_builder = match alg {
68-
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
76+
AsymmetricAlgorithmSelection::Rsa(key_bits) => PublicBuilder::new()
6977
.with_public_algorithm(PublicAlgorithm::Rsa)
7078
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
7179
.with_object_attributes(obj_attrs)
@@ -74,15 +82,15 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
7482
PublicRsaParametersBuilder::new()
7583
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
7684
.with_scheme(RsaScheme::Null)
77-
.with_key_bits(RsaKeyBits::Rsa2048)
85+
.with_key_bits(key_bits)
7886
.with_exponent(RsaExponent::default())
7987
.with_is_signing_key(obj_attrs.sign_encrypt())
8088
.with_is_decryption_key(obj_attrs.decrypt())
8189
.with_restricted(obj_attrs.decrypt())
8290
.build()?,
8391
)
8492
.with_rsa_unique_identifier(PublicKeyRsa::new_empty_with_size(RsaKeyBits::Rsa2048)),
85-
AsymmetricAlgorithm::Ecc => PublicBuilder::new()
93+
AsymmetricAlgorithmSelection::Ecc(ecc_curve) => PublicBuilder::new()
8694
.with_public_algorithm(PublicAlgorithm::Ecc)
8795
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
8896
.with_object_attributes(obj_attrs)
@@ -91,7 +99,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
9199
PublicEccParametersBuilder::new()
92100
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
93101
.with_ecc_scheme(EccScheme::Null)
94-
.with_curve(EccCurve::NistP256)
102+
.with_curve(ecc_curve)
95103
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
96104
.with_is_signing_key(obj_attrs.sign_encrypt())
97105
.with_is_decryption_key(obj_attrs.decrypt())
@@ -102,10 +110,6 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
102110
EccParameter::try_from(vec![0u8; 32])?,
103111
EccParameter::try_from(vec![0u8; 32])?,
104112
)),
105-
AsymmetricAlgorithm::Null => {
106-
// TDOD: Figure out what to with Null.
107-
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
108-
}
109113
};
110114

111115
let key_builder = if let Some(ref k) = key_customization {
@@ -119,7 +123,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
119123
/// Create the Endorsement Key object from the specification templates
120124
pub fn create_ek_object<IKC: IntoKeyCustomization>(
121125
context: &mut Context,
122-
alg: AsymmetricAlgorithm,
126+
alg: AsymmetricAlgorithmSelection,
123127
key_customization: IKC,
124128
) -> Result<KeyHandle> {
125129
let ek_public = create_ek_public_from_default_template(alg, key_customization)?;
@@ -132,14 +136,21 @@ pub fn create_ek_object<IKC: IntoKeyCustomization>(
132136
}
133137

134138
/// Retrieve the Endorsement Key public certificate from the TPM
135-
pub fn retrieve_ek_pubcert(context: &mut Context, alg: AsymmetricAlgorithm) -> Result<Vec<u8>> {
139+
pub fn retrieve_ek_pubcert(
140+
context: &mut Context,
141+
alg: AsymmetricAlgorithmSelection,
142+
) -> Result<Vec<u8>> {
136143
let nv_idx = match alg {
137-
AsymmetricAlgorithm::Rsa => RSA_2048_EK_CERTIFICATE_NV_INDEX,
138-
AsymmetricAlgorithm::Ecc => ECC_P256_EK_CERTIFICATE_NV_INDEX,
139-
AsymmetricAlgorithm::Null => {
140-
// TDOD: Figure out what to with Null.
141-
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
144+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048) => RSA_2048_EK_CERTIFICATE_NV_INDEX,
145+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa3072) => RSA_3072_EK_CERTIFICATE_NV_INDEX,
146+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa4096) => RSA_4096_EK_CERTIFICATE_NV_INDEX,
147+
AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP256) => ECC_P256_EK_CERTIFICATE_NV_INDEX,
148+
AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP384) => ECC_P384_EK_CERTIFICATE_NV_INDEX,
149+
AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP521) => ECC_P521_EK_CERTIFICATE_NV_INDEX,
150+
AsymmetricAlgorithmSelection::Ecc(EccCurve::Sm2P256) => {
151+
ECC_P256_SM2_EK_CERTIFICATE_NV_INDEX
142152
}
153+
_ => return Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
143154
};
144155

145156
let nv_idx = NvIndexTpmHandle::new(nv_idx).unwrap();

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

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::{
66
constants::SessionType,
77
handles::{AuthHandle, KeyHandle, SessionHandle},
88
interface_types::{
9-
algorithm::{AsymmetricAlgorithm, HashingAlgorithm},
9+
algorithm::{AsymmetricAlgorithmSelection, HashingAlgorithm},
10+
key_bits::RsaKeyBits,
1011
session_handles::{AuthSession, PolicySession},
1112
},
1213
structures::{EncryptedSecret, IdObject, SymmetricDefinition},
@@ -154,13 +155,16 @@ impl TransientKeyContext {
154155
None,
155156
);
156157
Ok((
157-
ek::create_ek_object(&mut self.context, AsymmetricAlgorithm::Rsa, None).or_else(
158-
|e| {
159-
self.context
160-
.flush_context(SessionHandle::from(session).into())?;
161-
Err(e)
162-
},
163-
)?,
158+
ek::create_ek_object(
159+
&mut self.context,
160+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
161+
None,
162+
)
163+
.or_else(|e| {
164+
self.context
165+
.flush_context(SessionHandle::from(session).into())?;
166+
Err(e)
167+
})?,
164168
session,
165169
))
166170
}
@@ -191,7 +195,11 @@ impl TransientKeyContext {
191195
}
192196

193197
fn get_ek_object_public(context: &mut crate::Context) -> Result<PublicKey> {
194-
let key_handle = ek::create_ek_object(context, AsymmetricAlgorithm::Rsa, None)?;
198+
let key_handle = ek::create_ek_object(
199+
context,
200+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
201+
None,
202+
)?;
195203
let (attesting_key_pub, _, _) = context.read_public(key_handle).or_else(|e| {
196204
context.flush_context(key_handle.into())?;
197205
Err(e)

tss-esapi/src/interface_types/algorithm.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
use crate::{
44
constants::AlgorithmIdentifier,
5+
interface_types::{ecc::EccCurve, key_bits::RsaKeyBits},
56
tss2_esys::{
67
TPMI_ALG_ASYM, TPMI_ALG_ECC_SCHEME, TPMI_ALG_HASH, TPMI_ALG_KDF, TPMI_ALG_KEYEDHASH_SCHEME,
78
TPMI_ALG_PUBLIC, TPMI_ALG_RSA_DECRYPT, TPMI_ALG_RSA_SCHEME, TPMI_ALG_SIG_SCHEME,
@@ -335,6 +336,28 @@ impl TryFrom<TPMI_ALG_ASYM> for AsymmetricAlgorithm {
335336
}
336337
}
337338

339+
/// Enum representing the asymmetric algorithm interface type with specific properties.
340+
/// Use this instead of [AsymmetricAlgorithm], which will be deprecated at some point.
341+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
342+
pub enum AsymmetricAlgorithmSelection {
343+
Rsa(RsaKeyBits),
344+
Ecc(EccCurve),
345+
}
346+
347+
impl TryFrom<AsymmetricAlgorithm> for AsymmetricAlgorithmSelection {
348+
type Error = Error;
349+
350+
fn try_from(value: AsymmetricAlgorithm) -> std::result::Result<Self, Self::Error> {
351+
match value {
352+
AsymmetricAlgorithm::Rsa => Ok(AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048)),
353+
AsymmetricAlgorithm::Ecc => Ok(AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP256)),
354+
AsymmetricAlgorithm::Null => {
355+
Err(Error::local_error(WrapperErrorKind::UnsupportedParam))
356+
}
357+
}
358+
}
359+
}
360+
338361
/// Enum representing the signature scheme interface type.
339362
///
340363
/// # Details

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

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ use tss_esapi::{
99
constants::SessionType,
1010
handles::AuthHandle,
1111
interface_types::{
12-
algorithm::{AsymmetricAlgorithm, HashingAlgorithm, SignatureSchemeAlgorithm},
12+
algorithm::{AsymmetricAlgorithmSelection, HashingAlgorithm, SignatureSchemeAlgorithm},
13+
ecc::EccCurve,
14+
key_bits::RsaKeyBits,
1315
session_handles::PolicySession,
1416
},
1517
structures::{Auth, Digest, PublicBuilder, SymmetricDefinition},
@@ -21,11 +23,17 @@ use crate::common::create_ctx_without_session;
2123
fn test_create_ak_rsa_rsa() {
2224
let mut context = create_ctx_without_session();
2325

24-
let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
26+
let ek_rsa = ek::create_ek_object(
27+
&mut context,
28+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
29+
None,
30+
)
31+
.unwrap();
2532
ak::create_ak(
2633
&mut context,
2734
ek_rsa,
2835
HashingAlgorithm::Sha256,
36+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
2937
SignatureSchemeAlgorithm::RsaPss,
3038
None,
3139
None,
@@ -37,11 +45,17 @@ fn test_create_ak_rsa_rsa() {
3745
fn test_create_ak_rsa_ecc() {
3846
let mut context = create_ctx_without_session();
3947

40-
let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
48+
let ek_rsa = ek::create_ek_object(
49+
&mut context,
50+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
51+
None,
52+
)
53+
.unwrap();
4154
if ak::create_ak(
4255
&mut context,
4356
ek_rsa,
4457
HashingAlgorithm::Sha256,
58+
AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP256),
4559
SignatureSchemeAlgorithm::Sm2,
4660
None,
4761
None,
@@ -57,12 +71,18 @@ fn test_create_ak_rsa_ecc() {
5771
fn test_create_and_use_ak() {
5872
let mut context = create_ctx_without_session();
5973

60-
let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
74+
let ek_rsa = ek::create_ek_object(
75+
&mut context,
76+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
77+
None,
78+
)
79+
.unwrap();
6180
let ak_auth = Auth::try_from(vec![0x1, 0x2, 0x42]).unwrap();
6281
let att_key = ak::create_ak(
6382
&mut context,
6483
ek_rsa,
6584
HashingAlgorithm::Sha256,
85+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
6686
SignatureSchemeAlgorithm::RsaPss,
6787
Some(ak_auth.clone()),
6888
None,
@@ -158,13 +178,19 @@ fn test_create_custom_ak() {
158178
}
159179
let mut context = create_ctx_without_session();
160180

161-
let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
181+
let ek_rsa = ek::create_ek_object(
182+
&mut context,
183+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
184+
None,
185+
)
186+
.unwrap();
162187
let ak_auth = Auth::try_from(vec![0x1, 0x2, 0x42]).unwrap();
163188
// Without customization, no st clear
164189
let att_key_without = ak::create_ak(
165190
&mut context,
166191
ek_rsa,
167192
HashingAlgorithm::Sha256,
193+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
168194
SignatureSchemeAlgorithm::RsaPss,
169195
Some(ak_auth.clone()),
170196
None,
@@ -181,6 +207,7 @@ fn test_create_custom_ak() {
181207
&mut context,
182208
ek_rsa,
183209
HashingAlgorithm::Sha256,
210+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
184211
SignatureSchemeAlgorithm::RsaPss,
185212
Some(ak_auth),
186213
&CustomizeKey,

0 commit comments

Comments
 (0)