Skip to content

Commit 9ba573f

Browse files
committed
ek 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 9ba573f

File tree

5 files changed

+121
-43
lines changed

5 files changed

+121
-43
lines changed

tss-esapi/src/abstraction/ek.rs

Lines changed: 84 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,79 @@ use crate::{
1818
},
1919
Context, Error, Result, WrapperErrorKind,
2020
};
21-
use std::convert::TryFrom;
21+
use std::convert::{TryFrom, TryInto};
2222
// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
2323
// Section 2.2.1.4 (Low Range) for Windows compatibility
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+
35+
/// Enum representing the asymmetric algorithm interface type with specific properties.
36+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
37+
pub enum AsymmetricAlgorithmSelection {
38+
Rsa2048,
39+
Rsa3072,
40+
Rsa4096,
41+
EccP256,
42+
EccP384,
43+
EccP521,
44+
EccP256Sm2,
45+
}
46+
47+
impl TryFrom<AsymmetricAlgorithm> for AsymmetricAlgorithmSelection {
48+
type Error = Error;
49+
50+
fn try_from(value: AsymmetricAlgorithm) -> std::result::Result<Self, Self::Error> {
51+
match value {
52+
AsymmetricAlgorithm::Rsa => Ok(AsymmetricAlgorithmSelection::Rsa2048),
53+
AsymmetricAlgorithm::Ecc => Ok(AsymmetricAlgorithmSelection::EccP256),
54+
AsymmetricAlgorithm::Null => {
55+
Err(Error::local_error(WrapperErrorKind::UnsupportedParam))
56+
}
57+
}
58+
}
59+
}
60+
61+
impl TryFrom<AsymmetricAlgorithmSelection> for RsaKeyBits {
62+
type Error = Error;
63+
64+
fn try_from(value: AsymmetricAlgorithmSelection) -> std::result::Result<Self, Self::Error> {
65+
match value {
66+
AsymmetricAlgorithmSelection::Rsa2048 => Ok(RsaKeyBits::Rsa2048),
67+
AsymmetricAlgorithmSelection::Rsa3072 => Ok(RsaKeyBits::Rsa3072),
68+
AsymmetricAlgorithmSelection::Rsa4096 => Ok(RsaKeyBits::Rsa4096),
69+
_ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
70+
}
71+
}
72+
}
73+
74+
impl TryFrom<AsymmetricAlgorithmSelection> for EccCurve {
75+
type Error = Error;
76+
77+
fn try_from(value: AsymmetricAlgorithmSelection) -> std::result::Result<Self, Self::Error> {
78+
match value {
79+
AsymmetricAlgorithmSelection::EccP256 => Ok(EccCurve::NistP256),
80+
AsymmetricAlgorithmSelection::EccP384 => Ok(EccCurve::NistP384),
81+
AsymmetricAlgorithmSelection::EccP521 => Ok(EccCurve::NistP521),
82+
AsymmetricAlgorithmSelection::EccP256Sm2 => Ok(EccCurve::Sm2P256),
83+
_ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
84+
}
85+
}
86+
}
87+
2788
/// Get the [`Public`] representing a default Endorsement Key
2889
///
2990
/// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
3091
/// Appendix B.3.3 and B.3.4
3192
pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
32-
alg: AsymmetricAlgorithm,
93+
alg: AsymmetricAlgorithmSelection,
3394
key_customization: IKC,
3495
) -> Result<Public> {
3596
let key_customization = key_customization.into_key_customization();
@@ -65,7 +126,9 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
65126
];
66127

67128
let key_builder = match alg {
68-
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
129+
AsymmetricAlgorithmSelection::Rsa2048
130+
| AsymmetricAlgorithmSelection::Rsa3072
131+
| AsymmetricAlgorithmSelection::Rsa4096 => PublicBuilder::new()
69132
.with_public_algorithm(PublicAlgorithm::Rsa)
70133
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
71134
.with_object_attributes(obj_attrs)
@@ -74,15 +137,18 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
74137
PublicRsaParametersBuilder::new()
75138
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
76139
.with_scheme(RsaScheme::Null)
77-
.with_key_bits(RsaKeyBits::Rsa2048)
140+
.with_key_bits(alg.try_into()?)
78141
.with_exponent(RsaExponent::default())
79142
.with_is_signing_key(obj_attrs.sign_encrypt())
80143
.with_is_decryption_key(obj_attrs.decrypt())
81144
.with_restricted(obj_attrs.decrypt())
82145
.build()?,
83146
)
84147
.with_rsa_unique_identifier(PublicKeyRsa::new_empty_with_size(RsaKeyBits::Rsa2048)),
85-
AsymmetricAlgorithm::Ecc => PublicBuilder::new()
148+
AsymmetricAlgorithmSelection::EccP256
149+
| AsymmetricAlgorithmSelection::EccP384
150+
| AsymmetricAlgorithmSelection::EccP521
151+
| AsymmetricAlgorithmSelection::EccP256Sm2 => PublicBuilder::new()
86152
.with_public_algorithm(PublicAlgorithm::Ecc)
87153
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
88154
.with_object_attributes(obj_attrs)
@@ -91,7 +157,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
91157
PublicEccParametersBuilder::new()
92158
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
93159
.with_ecc_scheme(EccScheme::Null)
94-
.with_curve(EccCurve::NistP256)
160+
.with_curve(alg.try_into()?)
95161
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
96162
.with_is_signing_key(obj_attrs.sign_encrypt())
97163
.with_is_decryption_key(obj_attrs.decrypt())
@@ -102,10 +168,6 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
102168
EccParameter::try_from(vec![0u8; 32])?,
103169
EccParameter::try_from(vec![0u8; 32])?,
104170
)),
105-
AsymmetricAlgorithm::Null => {
106-
// TDOD: Figure out what to with Null.
107-
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
108-
}
109171
};
110172

111173
let key_builder = if let Some(ref k) = key_customization {
@@ -119,7 +181,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
119181
/// Create the Endorsement Key object from the specification templates
120182
pub fn create_ek_object<IKC: IntoKeyCustomization>(
121183
context: &mut Context,
122-
alg: AsymmetricAlgorithm,
184+
alg: AsymmetricAlgorithmSelection,
123185
key_customization: IKC,
124186
) -> Result<KeyHandle> {
125187
let ek_public = create_ek_public_from_default_template(alg, key_customization)?;
@@ -132,14 +194,18 @@ pub fn create_ek_object<IKC: IntoKeyCustomization>(
132194
}
133195

134196
/// Retrieve the Endorsement Key public certificate from the TPM
135-
pub fn retrieve_ek_pubcert(context: &mut Context, alg: AsymmetricAlgorithm) -> Result<Vec<u8>> {
197+
pub fn retrieve_ek_pubcert(
198+
context: &mut Context,
199+
alg: AsymmetricAlgorithmSelection,
200+
) -> Result<Vec<u8>> {
136201
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));
142-
}
202+
AsymmetricAlgorithmSelection::Rsa2048 => RSA_2048_EK_CERTIFICATE_NV_INDEX,
203+
AsymmetricAlgorithmSelection::Rsa3072 => RSA_3072_EK_CERTIFICATE_NV_INDEX,
204+
AsymmetricAlgorithmSelection::Rsa4096 => RSA_4096_EK_CERTIFICATE_NV_INDEX,
205+
AsymmetricAlgorithmSelection::EccP256 => ECC_P256_EK_CERTIFICATE_NV_INDEX,
206+
AsymmetricAlgorithmSelection::EccP384 => ECC_P384_EK_CERTIFICATE_NV_INDEX,
207+
AsymmetricAlgorithmSelection::EccP521 => ECC_P521_EK_CERTIFICATE_NV_INDEX,
208+
AsymmetricAlgorithmSelection::EccP256Sm2 => ECC_P256_SM2_EK_CERTIFICATE_NV_INDEX,
143209
};
144210

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

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
constants::SessionType,
77
handles::{AuthHandle, KeyHandle, SessionHandle},
88
interface_types::{
9-
algorithm::{AsymmetricAlgorithm, HashingAlgorithm},
9+
algorithm::HashingAlgorithm,
1010
session_handles::{AuthSession, PolicySession},
1111
},
1212
structures::{EncryptedSecret, IdObject, SymmetricDefinition},
@@ -154,13 +154,16 @@ impl TransientKeyContext {
154154
None,
155155
);
156156
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-
)?,
157+
ek::create_ek_object(
158+
&mut self.context,
159+
ek::AsymmetricAlgorithmSelection::Rsa2048,
160+
None,
161+
)
162+
.or_else(|e| {
163+
self.context
164+
.flush_context(SessionHandle::from(session).into())?;
165+
Err(e)
166+
})?,
164167
session,
165168
))
166169
}
@@ -191,7 +194,8 @@ impl TransientKeyContext {
191194
}
192195

193196
fn get_ek_object_public(context: &mut crate::Context) -> Result<PublicKey> {
194-
let key_handle = ek::create_ek_object(context, AsymmetricAlgorithm::Rsa, None)?;
197+
let key_handle =
198+
ek::create_ek_object(context, ek::AsymmetricAlgorithmSelection::Rsa2048, None)?;
195199
let (attesting_key_pub, _, _) = context.read_public(key_handle).or_else(|e| {
196200
context.flush_context(key_handle.into())?;
197201
Err(e)

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
use std::convert::{TryFrom, TryInto};
55

66
use tss_esapi::{
7+
abstraction::ek::AsymmetricAlgorithmSelection,
78
abstraction::{ak, ek, KeyCustomization},
89
attributes::{ObjectAttributesBuilder, SessionAttributesBuilder},
910
constants::SessionType,
1011
handles::AuthHandle,
1112
interface_types::{
12-
algorithm::{AsymmetricAlgorithm, HashingAlgorithm, SignatureSchemeAlgorithm},
13+
algorithm::{HashingAlgorithm, SignatureSchemeAlgorithm},
1314
session_handles::PolicySession,
1415
},
1516
structures::{Auth, Digest, PublicBuilder, SymmetricDefinition},
@@ -21,7 +22,8 @@ use crate::common::create_ctx_without_session;
2122
fn test_create_ak_rsa_rsa() {
2223
let mut context = create_ctx_without_session();
2324

24-
let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
25+
let ek_rsa =
26+
ek::create_ek_object(&mut context, AsymmetricAlgorithmSelection::Rsa2048, None).unwrap();
2527
ak::create_ak(
2628
&mut context,
2729
ek_rsa,
@@ -37,7 +39,8 @@ fn test_create_ak_rsa_rsa() {
3739
fn test_create_ak_rsa_ecc() {
3840
let mut context = create_ctx_without_session();
3941

40-
let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
42+
let ek_rsa =
43+
ek::create_ek_object(&mut context, AsymmetricAlgorithmSelection::Rsa2048, None).unwrap();
4144
if ak::create_ak(
4245
&mut context,
4346
ek_rsa,
@@ -57,7 +60,8 @@ fn test_create_ak_rsa_ecc() {
5760
fn test_create_and_use_ak() {
5861
let mut context = create_ctx_without_session();
5962

60-
let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
63+
let ek_rsa =
64+
ek::create_ek_object(&mut context, AsymmetricAlgorithmSelection::Rsa2048, None).unwrap();
6165
let ak_auth = Auth::try_from(vec![0x1, 0x2, 0x42]).unwrap();
6266
let att_key = ak::create_ak(
6367
&mut context,
@@ -158,7 +162,8 @@ fn test_create_custom_ak() {
158162
}
159163
let mut context = create_ctx_without_session();
160164

161-
let ek_rsa = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
165+
let ek_rsa =
166+
ek::create_ek_object(&mut context, AsymmetricAlgorithmSelection::Rsa2048, None).unwrap();
162167
let ak_auth = Auth::try_from(vec![0x1, 0x2, 0x42]).unwrap();
163168
// Without customization, no st clear
164169
let att_key_without = ak::create_ak(

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

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

44
use tss_esapi::{
5-
abstraction::ek, constants::return_code::TpmFormatOneError, error::TpmResponseCode,
6-
interface_types::algorithm::AsymmetricAlgorithm, Error, ReturnCode,
5+
abstraction::ek, abstraction::ek::AsymmetricAlgorithmSelection,
6+
constants::return_code::TpmFormatOneError, error::TpmResponseCode, Error, ReturnCode,
77
};
88

99
use crate::common::create_ctx_without_session;
@@ -14,14 +14,14 @@ fn test_retrieve_ek_pubcert() {
1414

1515
// The error 395 is for "handle could not be found" - this makes it that if the NV Index
1616
// did not exist (the test is run on a TPM without an endorsement cert), it still passes.
17-
match ek::retrieve_ek_pubcert(&mut context, AsymmetricAlgorithm::Rsa) {
17+
match ek::retrieve_ek_pubcert(&mut context, AsymmetricAlgorithmSelection::Rsa2048) {
1818
Ok(_) => (),
1919
Err(Error::TssError(ReturnCode::Tpm(TpmResponseCode::FormatOne(error)))) => {
2020
assert_eq!(error.error_number(), TpmFormatOneError::Handle)
2121
}
2222
Err(e) => panic!("Error was unexpected: {:?}", e),
2323
};
24-
match ek::retrieve_ek_pubcert(&mut context, AsymmetricAlgorithm::Ecc) {
24+
match ek::retrieve_ek_pubcert(&mut context, AsymmetricAlgorithmSelection::EccP256) {
2525
Ok(_) => (),
2626
Err(Error::TssError(ReturnCode::Tpm(TpmResponseCode::FormatOne(error)))) => {
2727
assert_eq!(error.error_number(), TpmFormatOneError::Handle)
@@ -34,6 +34,8 @@ fn test_retrieve_ek_pubcert() {
3434
fn test_create_ek() {
3535
let mut context = create_ctx_without_session();
3636

37-
let _ = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Rsa, None).unwrap();
38-
let _ = ek::create_ek_object(&mut context, AsymmetricAlgorithm::Ecc, None).unwrap();
37+
let _ =
38+
ek::create_ek_object(&mut context, AsymmetricAlgorithmSelection::Rsa2048, None).unwrap();
39+
let _ =
40+
ek::create_ek_object(&mut context, AsymmetricAlgorithmSelection::EccP256, None).unwrap();
3941
}

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
use std::convert::{TryFrom, TryInto};
44
use tss_esapi::{
55
abstraction::ek,
6+
abstraction::ek::AsymmetricAlgorithmSelection,
67
abstraction::transient::{KeyParams, ObjectWrapper, TransientKeyContextBuilder},
78
constants::return_code::{TpmFormatOneError, TpmFormatZeroError},
89
error::{TpmFormatZeroResponseCode, TpmResponseCode},
910
interface_types::{
10-
algorithm::{
11-
AsymmetricAlgorithm, EccSchemeAlgorithm, HashingAlgorithm, RsaSchemeAlgorithm,
12-
},
11+
algorithm::{EccSchemeAlgorithm, HashingAlgorithm, RsaSchemeAlgorithm},
1312
ecc::EccCurve,
1413
key_bits::RsaKeyBits,
1514
resource_handles::Hierarchy,
@@ -631,7 +630,8 @@ fn activate_credential() {
631630

632631
// the public part of the EK is used, so we retrieve the parameters
633632
let key_pub =
634-
ek::create_ek_public_from_default_template(AsymmetricAlgorithm::Rsa, None).unwrap();
633+
ek::create_ek_public_from_default_template(AsymmetricAlgorithmSelection::Rsa2048, None)
634+
.unwrap();
635635
let key_pub = if let Public::Rsa {
636636
object_attributes,
637637
name_hashing_algorithm,
@@ -755,7 +755,8 @@ fn activate_credential_wrong_key() {
755755

756756
// the public part of the EK is used, so we retrieve the parameters
757757
let key_pub =
758-
ek::create_ek_public_from_default_template(AsymmetricAlgorithm::Rsa, None).unwrap();
758+
ek::create_ek_public_from_default_template(AsymmetricAlgorithmSelection::Rsa2048, None)
759+
.unwrap();
759760
let key_pub = if let Public::Rsa {
760761
object_attributes,
761762
name_hashing_algorithm,

0 commit comments

Comments
 (0)