Skip to content

Commit

Permalink
ek abstractions: allow to specficy exact key type
Browse files Browse the repository at this point in the history
This adds support other keys than RSA2048 and ECC Nist P256.

Signed-off-by: Thore Sommer <[email protected]>
  • Loading branch information
THS-on committed Jun 11, 2023
1 parent 1e04007 commit d909944
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 17 deletions.
95 changes: 83 additions & 12 deletions tss-esapi/src/abstraction/ek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,76 @@ use crate::{
},
Context, Error, Result, WrapperErrorKind,
};
use std::convert::TryFrom;
use std::convert::{TryFrom, TryInto};
// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
// Section 2.2.1.4 (Low Range) for Windows compatibility
const RSA_2048_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c00002;
const ECC_P256_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0000a;

// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
// Section 2.2.1.5 (High Range)
const ECC_P384_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c00016;
const ECC_P521_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c00018;
const ECC_P256_SM2_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0001a;
const RSA_3072_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0001c;
const RSA_4096_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0001e;

/// Enum representing the asymmetric algorithm interface type with specific properties.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum AsymmetricAlgorithmSelection {
Rsa2048,
Rsa3072,
Rsa4096,
EccP256,
EccP384,
EccP521,
EccP256Sm2,
Null,
}

impl From<AsymmetricAlgorithm> for AsymmetricAlgorithmSelection {
fn from(value: AsymmetricAlgorithm) -> Self {
match value {
AsymmetricAlgorithm::Rsa => AsymmetricAlgorithmSelection::Rsa2048,
AsymmetricAlgorithm::Ecc => AsymmetricAlgorithmSelection::EccP256,
AsymmetricAlgorithm::Null => AsymmetricAlgorithmSelection::Null,
}
}
}

impl TryFrom<AsymmetricAlgorithmSelection> for RsaKeyBits {
type Error = Error;

fn try_from(value: AsymmetricAlgorithmSelection) -> std::result::Result<Self, Self::Error> {
match value {
AsymmetricAlgorithmSelection::Rsa2048 => Ok(RsaKeyBits::Rsa2048),
AsymmetricAlgorithmSelection::Rsa3072 => Ok(RsaKeyBits::Rsa3072),
AsymmetricAlgorithmSelection::Rsa4096 => Ok(RsaKeyBits::Rsa4096),
_ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
}
}
}

impl TryFrom<AsymmetricAlgorithmSelection> for EccCurve {
type Error = Error;

fn try_from(value: AsymmetricAlgorithmSelection) -> std::result::Result<Self, Self::Error> {
match value {
AsymmetricAlgorithmSelection::EccP256 => Ok(EccCurve::NistP256),
AsymmetricAlgorithmSelection::EccP384 => Ok(EccCurve::NistP384),
AsymmetricAlgorithmSelection::EccP521 => Ok(EccCurve::NistP521),
AsymmetricAlgorithmSelection::EccP256Sm2 => Ok(EccCurve::Sm2P256),
_ => Err(Error::local_error(WrapperErrorKind::InvalidParam)),
}
}
}

/// Get the [`Public`] representing a default Endorsement Key
///
/// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2
/// Appendix B.3.3 and B.3.4
pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
alg: AsymmetricAlgorithm,
alg: AsymmetricAlgorithmSelection,
key_customization: IKC,
) -> Result<Public> {
let key_customization = key_customization.into_key_customization();
Expand Down Expand Up @@ -65,7 +123,9 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
];

let key_builder = match alg {
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
AsymmetricAlgorithmSelection::Rsa2048
| AsymmetricAlgorithmSelection::Rsa3072
| AsymmetricAlgorithmSelection::Rsa4096 => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Rsa)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(obj_attrs)
Expand All @@ -74,15 +134,18 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
PublicRsaParametersBuilder::new()
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
.with_scheme(RsaScheme::Null)
.with_key_bits(RsaKeyBits::Rsa2048)
.with_key_bits(alg.try_into()?)
.with_exponent(RsaExponent::default())
.with_is_signing_key(obj_attrs.sign_encrypt())
.with_is_decryption_key(obj_attrs.decrypt())
.with_restricted(obj_attrs.decrypt())
.build()?,
)
.with_rsa_unique_identifier(PublicKeyRsa::new_empty_with_size(RsaKeyBits::Rsa2048)),
AsymmetricAlgorithm::Ecc => PublicBuilder::new()
AsymmetricAlgorithmSelection::EccP256
| AsymmetricAlgorithmSelection::EccP384
| AsymmetricAlgorithmSelection::EccP521
| AsymmetricAlgorithmSelection::EccP256Sm2 => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(obj_attrs)
Expand All @@ -91,7 +154,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
PublicEccParametersBuilder::new()
.with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
.with_ecc_scheme(EccScheme::Null)
.with_curve(EccCurve::NistP256)
.with_curve(alg.try_into()?)
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
.with_is_signing_key(obj_attrs.sign_encrypt())
.with_is_decryption_key(obj_attrs.decrypt())
Expand All @@ -102,7 +165,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
EccParameter::try_from(vec![0u8; 32])?,
EccParameter::try_from(vec![0u8; 32])?,
)),
AsymmetricAlgorithm::Null => {
AsymmetricAlgorithmSelection::Null => {
// TDOD: Figure out what to with Null.
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
}
Expand All @@ -119,7 +182,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
/// Create the Endorsement Key object from the specification templates
pub fn create_ek_object<IKC: IntoKeyCustomization>(
context: &mut Context,
alg: AsymmetricAlgorithm,
alg: AsymmetricAlgorithmSelection,
key_customization: IKC,
) -> Result<KeyHandle> {
let ek_public = create_ek_public_from_default_template(alg, key_customization)?;
Expand All @@ -132,11 +195,19 @@ pub fn create_ek_object<IKC: IntoKeyCustomization>(
}

/// Retrieve the Endorsement Key public certificate from the TPM
pub fn retrieve_ek_pubcert(context: &mut Context, alg: AsymmetricAlgorithm) -> Result<Vec<u8>> {
pub fn retrieve_ek_pubcert(
context: &mut Context,
alg: AsymmetricAlgorithmSelection,
) -> Result<Vec<u8>> {
let nv_idx = match alg {
AsymmetricAlgorithm::Rsa => RSA_2048_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithm::Ecc => ECC_P256_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithm::Null => {
AsymmetricAlgorithmSelection::Rsa2048 => RSA_2048_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Rsa3072 => RSA_3072_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Rsa4096 => RSA_4096_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::EccP256 => ECC_P256_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::EccP384 => ECC_P384_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::EccP521 => ECC_P521_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::EccP256Sm2 => ECC_P256_SM2_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Null => {
// TDOD: Figure out what to with Null.
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
}
Expand Down
9 changes: 4 additions & 5 deletions tss-esapi/src/abstraction/transient/key_attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,12 @@ impl TransientKeyContext {
None,
);
Ok((
ek::create_ek_object(&mut self.context, AsymmetricAlgorithm::Rsa, None).or_else(
|e| {
ek::create_ek_object(&mut self.context, AsymmetricAlgorithm::Rsa.into(), None)
.or_else(|e| {
self.context
.flush_context(SessionHandle::from(session).into())?;
Err(e)
},
)?,
})?,
session,
))
}
Expand Down Expand Up @@ -191,7 +190,7 @@ impl TransientKeyContext {
}

fn get_ek_object_public(context: &mut crate::Context) -> Result<PublicKey> {
let key_handle = ek::create_ek_object(context, AsymmetricAlgorithm::Rsa, None)?;
let key_handle = ek::create_ek_object(context, AsymmetricAlgorithm::Rsa.into(), None)?;
let (attesting_key_pub, _, _) = context.read_public(key_handle).or_else(|e| {
context.flush_context(key_handle.into())?;
Err(e)
Expand Down

0 comments on commit d909944

Please sign in to comment.