Skip to content

Commit 52194ff

Browse files
authored
Merge pull request #414 from THS-on/feature/algorithmselection
ek, ak abstractions: allow to specficy exact key type
2 parents 1e04007 + 04a42ea commit 52194ff

File tree

8 files changed

+164
-71
lines changed

8 files changed

+164
-71
lines changed

tss-esapi/src/abstraction/ak.rs

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
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::{
@@ -22,11 +22,10 @@ use crate::{
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,10 @@ 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()?,
8685
),
87-
AsymmetricAlgorithm::Null => {
88-
// TODO: Figure out what to with Null.
89-
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
90-
}
9186
};
9287

9388
let key_builder = if let Some(ref k) = key_customization {
@@ -160,16 +155,11 @@ pub fn create_ak<IKC: IntoKeyCustomization>(
160155
context: &mut Context,
161156
parent: KeyHandle,
162157
hash_alg: HashingAlgorithm,
158+
key_alg: AsymmetricAlgorithmSelection,
163159
sign_alg: SignatureSchemeAlgorithm,
164160
ak_auth_value: Option<Auth>,
165161
key_customization: IKC,
166162
) -> 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-
173163
let ak_pub = create_ak_public(key_alg, hash_alg, sign_alg, key_customization)?;
174164

175165
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: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@ pub mod pcr;
99
pub mod public;
1010
pub mod transient;
1111

12-
use crate::{attributes::ObjectAttributesBuilder, structures::PublicBuilder};
12+
use std::convert::TryFrom;
13+
14+
use crate::{
15+
attributes::ObjectAttributesBuilder,
16+
interface_types::{algorithm::AsymmetricAlgorithm, ecc::EccCurve, key_bits::RsaKeyBits},
17+
structures::PublicBuilder,
18+
Error, WrapperErrorKind,
19+
};
1320

1421
/// KeyCustomizaion allows to adjust how a key is going to be created
1522
pub trait KeyCustomization {
@@ -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},
@@ -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: 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 [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)