Skip to content

Commit 9d306a0

Browse files
THS-onSuperhepper
andcommitted
ek, ak abstractions: allow to specficy exact key type
This adds support other keys than RSA2048 and ECC Nist P256. The difference between this commit and the original is that it has been adopted to be compatible with the 7.x.y branch(Jesper Brynolf). Co-authored-by: Jesper Brynolf <[email protected]> Signed-off-by: Thore Sommer <[email protected]>
1 parent 96f6855 commit 9d306a0

File tree

8 files changed

+169
-75
lines changed

8 files changed

+169
-75
lines changed

tss-esapi/src/abstraction/ak.rs

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,30 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use crate::{
5-
abstraction::{cipher::Cipher, IntoKeyCustomization, KeyCustomization},
5+
abstraction::{
6+
cipher::Cipher, AsymmetricAlgorithmSelection, IntoKeyCustomization, KeyCustomization,
7+
},
68
attributes::{ObjectAttributesBuilder, SessionAttributesBuilder},
79
constants::{AlgorithmIdentifier, SessionType},
810
handles::{AuthHandle, KeyHandle, SessionHandle},
911
interface_types::{
1012
algorithm::{
11-
AsymmetricAlgorithm, EccSchemeAlgorithm, HashingAlgorithm, PublicAlgorithm,
12-
RsaSchemeAlgorithm, SignatureSchemeAlgorithm,
13+
EccSchemeAlgorithm, HashingAlgorithm, PublicAlgorithm, RsaSchemeAlgorithm,
14+
SignatureSchemeAlgorithm,
1315
},
14-
ecc::EccCurve,
15-
key_bits::RsaKeyBits,
1616
session_handles::PolicySession,
1717
},
1818
structures::{
19-
Auth, CreateKeyResult, EccScheme, KeyDerivationFunctionScheme, Private, Public,
19+
Auth, CreateKeyResult, EccPoint, EccScheme, KeyDerivationFunctionScheme, Private, Public,
2020
PublicBuilder, PublicEccParametersBuilder, PublicKeyRsa, PublicRsaParametersBuilder,
2121
RsaExponent, RsaScheme, SymmetricDefinitionObject,
2222
},
2323
Context, Error, Result, WrapperErrorKind,
2424
};
25-
use log::error;
2625
use std::convert::{TryFrom, TryInto};
2726

2827
fn create_ak_public<IKC: IntoKeyCustomization>(
29-
key_alg: AsymmetricAlgorithm,
28+
key_alg: AsymmetricAlgorithmSelection,
3029
hash_alg: HashingAlgorithm,
3130
sign_alg: SignatureSchemeAlgorithm,
3231
key_customization: IKC,
@@ -50,7 +49,7 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
5049
.build()?;
5150

5251
let key_builder = match key_alg {
53-
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
52+
AsymmetricAlgorithmSelection::Rsa(key_bits) => PublicBuilder::new()
5453
.with_public_algorithm(PublicAlgorithm::Rsa)
5554
.with_name_hashing_algorithm(hash_alg)
5655
.with_object_attributes(obj_attrs)
@@ -60,15 +59,15 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
6059
RsaSchemeAlgorithm::try_from(AlgorithmIdentifier::from(sign_alg))?,
6160
Some(hash_alg),
6261
)?)
63-
.with_key_bits(RsaKeyBits::Rsa2048)
62+
.with_key_bits(key_bits)
6463
.with_exponent(RsaExponent::default())
6564
.with_is_signing_key(obj_attrs.sign_encrypt())
6665
.with_is_decryption_key(obj_attrs.decrypt())
6766
.with_restricted(obj_attrs.restricted())
6867
.build()?,
6968
)
7069
.with_rsa_unique_identifier(PublicKeyRsa::default()),
71-
AsymmetricAlgorithm::Ecc => PublicBuilder::new()
70+
AsymmetricAlgorithmSelection::Ecc(ecc_curve) => PublicBuilder::new()
7271
.with_public_algorithm(PublicAlgorithm::Ecc)
7372
.with_name_hashing_algorithm(hash_alg)
7473
.with_object_attributes(obj_attrs)
@@ -80,14 +79,11 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
8079
Some(hash_alg),
8180
Some(0),
8281
)?)
83-
.with_curve(EccCurve::NistP192)
82+
.with_curve(ecc_curve)
8483
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
8584
.build()?,
86-
),
87-
AsymmetricAlgorithm::Null => {
88-
// TODO: Figure out what to with Null.
89-
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
90-
}
85+
)
86+
.with_ecc_unique_identifier(EccPoint::default()),
9187
};
9288

9389
let key_builder = if let Some(ref k) = key_customization {
@@ -160,16 +156,11 @@ pub fn create_ak<IKC: IntoKeyCustomization>(
160156
context: &mut Context,
161157
parent: KeyHandle,
162158
hash_alg: HashingAlgorithm,
159+
key_alg: AsymmetricAlgorithmSelection,
163160
sign_alg: SignatureSchemeAlgorithm,
164161
ak_auth_value: Option<Auth>,
165162
key_customization: IKC,
166163
) -> 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-
173164
let ak_pub = create_ak_public(key_alg, hash_alg, sign_alg, key_customization)?;
174165

175166
let policy_auth_session = context

tss-esapi/src/abstraction/ek.rs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use crate::{
5-
abstraction::{nv, IntoKeyCustomization, KeyCustomization},
5+
abstraction::{nv, AsymmetricAlgorithmSelection, IntoKeyCustomization, KeyCustomization},
66
attributes::ObjectAttributesBuilder,
77
handles::{KeyHandle, NvIndexTpmHandle, TpmHandle},
88
interface_types::{
9-
algorithm::{AsymmetricAlgorithm, HashingAlgorithm, PublicAlgorithm},
9+
algorithm::{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/mod.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@ pub mod pcr;
99
pub mod public;
1010
pub mod transient;
1111

12-
use crate::{attributes::ObjectAttributesBuilder, structures::PublicBuilder};
12+
use std::convert::TryFrom;
1313

14-
/// KeyCustomizaion allows to adjust how a key is going to be created
14+
use crate::{
15+
attributes::ObjectAttributesBuilder,
16+
interface_types::{algorithm::AsymmetricAlgorithm, ecc::EccCurve, key_bits::RsaKeyBits},
17+
structures::PublicBuilder,
18+
Error, WrapperErrorKind,
19+
};
20+
21+
/// KeyCustomization allows to adjust how a key is going to be created
1522
pub trait KeyCustomization {
1623
/// Alter the attributes used on key creation
1724
fn attributes(&self, attributes_builder: ObjectAttributesBuilder) -> ObjectAttributesBuilder {
@@ -60,3 +67,29 @@ impl IntoKeyCustomization for Option<DefaultKey> {
6067
None
6168
}
6269
}
70+
71+
/// Enum representing the asymmetric algorithm interface type with specific properties.
72+
///
73+
/// # Details
74+
/// Use this instead of [AsymmetricAlgorithm].
75+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
76+
pub enum AsymmetricAlgorithmSelection {
77+
Rsa(RsaKeyBits),
78+
Ecc(EccCurve),
79+
}
80+
81+
/// The conversion assumes for RSA 2048 bit size and for ECC the Nist P256 curve,
82+
/// which matches the defaults in tpm2-tools.
83+
impl TryFrom<AsymmetricAlgorithm> for AsymmetricAlgorithmSelection {
84+
type Error = Error;
85+
86+
fn try_from(value: AsymmetricAlgorithm) -> Result<Self, Self::Error> {
87+
match value {
88+
AsymmetricAlgorithm::Rsa => Ok(AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048)),
89+
AsymmetricAlgorithm::Ecc => Ok(AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP256)),
90+
AsymmetricAlgorithm::Null => {
91+
Err(Error::local_error(WrapperErrorKind::UnsupportedParam))
92+
}
93+
}
94+
}
95+
}

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

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
// SPDX-License-Identifier: Apache-2.0
33
use super::{ObjectWrapper, TransientKeyContext};
44
use crate::{
5-
abstraction::ek,
5+
abstraction::{ek, AsymmetricAlgorithmSelection},
66
constants::SessionType,
77
handles::{AuthHandle, KeyHandle, SessionHandle},
88
interface_types::{
9-
algorithm::{AsymmetricAlgorithm, HashingAlgorithm},
9+
algorithm::HashingAlgorithm,
10+
key_bits::RsaKeyBits,
1011
session_handles::{AuthSession, PolicySession},
1112
},
1213
structures::{EncryptedSecret, IdObject, SymmetricDefinition},
@@ -151,13 +152,16 @@ impl TransientKeyContext {
151152
None,
152153
);
153154
Ok((
154-
ek::create_ek_object(&mut self.context, AsymmetricAlgorithm::Rsa, None).or_else(
155-
|e| {
156-
self.context
157-
.flush_context(SessionHandle::from(session).into())?;
158-
Err(e)
159-
},
160-
)?,
155+
ek::create_ek_object(
156+
&mut self.context,
157+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
158+
None,
159+
)
160+
.or_else(|e| {
161+
self.context
162+
.flush_context(SessionHandle::from(session).into())?;
163+
Err(e)
164+
})?,
161165
session,
162166
))
163167
}
@@ -188,7 +192,11 @@ impl TransientKeyContext {
188192
}
189193

190194
fn get_ek_object_public(context: &mut crate::Context) -> Result<PublicKey> {
191-
let key_handle = ek::create_ek_object(context, AsymmetricAlgorithm::Rsa, None)?;
195+
let key_handle = ek::create_ek_object(
196+
context,
197+
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
198+
None,
199+
)?;
192200
let (attesting_key_pub, _, _) = context.read_public(key_handle).or_else(|e| {
193201
context.flush_context(key_handle.into())?;
194202
Err(e)

tss-esapi/src/interface_types/algorithm.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@ impl TryFrom<TPMI_ALG_SYM_MODE> for SymmetricMode {
292292
/// Enum representing the asymmetric algorithm interface type.
293293
///
294294
/// # Details
295-
/// This corresponds to TPMI_ALG_ASYM
295+
/// Use [crate::abstraction::AsymmetricAlgorithmSelection] instead where possible.
296+
/// This corresponds to TPMI_ALG_ASYM.
296297
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
297298
pub enum AsymmetricAlgorithm {
298299
Rsa,

0 commit comments

Comments
 (0)