Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ek, ak abstractions: allow to specficy exact key type #414

Merged
merged 1 commit into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 11 additions & 21 deletions tss-esapi/src/abstraction/ak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
// SPDX-License-Identifier: Apache-2.0

use crate::{
abstraction::{cipher::Cipher, IntoKeyCustomization, KeyCustomization},
abstraction::{
cipher::Cipher, AsymmetricAlgorithmSelection, IntoKeyCustomization, KeyCustomization,
},
attributes::{ObjectAttributesBuilder, SessionAttributesBuilder},
constants::{AlgorithmIdentifier, SessionType},
handles::{AuthHandle, KeyHandle, SessionHandle},
interface_types::{
algorithm::{
AsymmetricAlgorithm, EccSchemeAlgorithm, HashingAlgorithm, PublicAlgorithm,
RsaSchemeAlgorithm, SignatureSchemeAlgorithm,
EccSchemeAlgorithm, HashingAlgorithm, PublicAlgorithm, RsaSchemeAlgorithm,
SignatureSchemeAlgorithm,
},
ecc::EccCurve,
key_bits::RsaKeyBits,
session_handles::PolicySession,
},
structures::{
Expand All @@ -22,11 +22,10 @@ use crate::{
},
Context, Error, Result, WrapperErrorKind,
};
use log::error;
use std::convert::{TryFrom, TryInto};

fn create_ak_public<IKC: IntoKeyCustomization>(
key_alg: AsymmetricAlgorithm,
key_alg: AsymmetricAlgorithmSelection,
hash_alg: HashingAlgorithm,
sign_alg: SignatureSchemeAlgorithm,
key_customization: IKC,
Expand All @@ -50,7 +49,7 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
.build()?;

let key_builder = match key_alg {
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
AsymmetricAlgorithmSelection::Rsa(key_bits) => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Rsa)
.with_name_hashing_algorithm(hash_alg)
.with_object_attributes(obj_attrs)
Expand All @@ -60,15 +59,15 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
RsaSchemeAlgorithm::try_from(AlgorithmIdentifier::from(sign_alg))?,
Some(hash_alg),
)?)
.with_key_bits(RsaKeyBits::Rsa2048)
.with_key_bits(key_bits)
.with_exponent(RsaExponent::default())
.with_is_signing_key(obj_attrs.sign_encrypt())
.with_is_decryption_key(obj_attrs.decrypt())
.with_restricted(obj_attrs.restricted())
.build()?,
)
.with_rsa_unique_identifier(PublicKeyRsa::default()),
AsymmetricAlgorithm::Ecc => PublicBuilder::new()
AsymmetricAlgorithmSelection::Ecc(ecc_curve) => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(hash_alg)
.with_object_attributes(obj_attrs)
Expand All @@ -80,14 +79,10 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
Some(hash_alg),
Some(0),
)?)
.with_curve(EccCurve::NistP192)
.with_curve(ecc_curve)
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
.build()?,
),
AsymmetricAlgorithm::Null => {
// TODO: Figure out what to with Null.
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
}
};

let key_builder = if let Some(ref k) = key_customization {
Expand Down Expand Up @@ -160,16 +155,11 @@ pub fn create_ak<IKC: IntoKeyCustomization>(
context: &mut Context,
parent: KeyHandle,
hash_alg: HashingAlgorithm,
key_alg: AsymmetricAlgorithmSelection,
sign_alg: SignatureSchemeAlgorithm,
ionut-arm marked this conversation as resolved.
Show resolved Hide resolved
ak_auth_value: Option<Auth>,
key_customization: IKC,
) -> Result<CreateKeyResult> {
let key_alg = AsymmetricAlgorithm::try_from(sign_alg).map_err(|e| {
// sign_alg is either HMAC or Null.
error!("Could not retrieve asymmetric algorithm for provided signature scheme");
e
})?;

let ak_pub = create_ak_public(key_alg, hash_alg, sign_alg, key_customization)?;

let policy_auth_session = context
Expand Down
47 changes: 29 additions & 18 deletions tss-esapi/src/abstraction/ek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// SPDX-License-Identifier: Apache-2.0

use crate::{
abstraction::{nv, IntoKeyCustomization, KeyCustomization},
abstraction::{nv, AsymmetricAlgorithmSelection, IntoKeyCustomization, KeyCustomization},
attributes::ObjectAttributesBuilder,
handles::{KeyHandle, NvIndexTpmHandle, TpmHandle},
interface_types::{
algorithm::{AsymmetricAlgorithm, HashingAlgorithm, PublicAlgorithm},
algorithm::{HashingAlgorithm, PublicAlgorithm},
ecc::EccCurve,
key_bits::RsaKeyBits,
resource_handles::{Hierarchy, NvAuth},
Expand All @@ -24,12 +24,20 @@ use std::convert::TryFrom;
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;

/// 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 +73,7 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
];

let key_builder = match alg {
AsymmetricAlgorithm::Rsa => PublicBuilder::new()
AsymmetricAlgorithmSelection::Rsa(key_bits) => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Rsa)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(obj_attrs)
Expand All @@ -74,15 +82,15 @@ 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(key_bits)
.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::Ecc(ecc_curve) => PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(obj_attrs)
Expand All @@ -91,7 +99,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(ecc_curve)
.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,10 +110,6 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
EccParameter::try_from(vec![0u8; 32])?,
EccParameter::try_from(vec![0u8; 32])?,
)),
AsymmetricAlgorithm::Null => {
// TDOD: Figure out what to with Null.
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
}
};

let key_builder = if let Some(ref k) = key_customization {
Expand All @@ -119,7 +123,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,14 +136,21 @@ 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 => {
// TDOD: Figure out what to with Null.
return Err(Error::local_error(WrapperErrorKind::UnsupportedParam));
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048) => RSA_2048_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa3072) => RSA_3072_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa4096) => RSA_4096_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP256) => ECC_P256_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP384) => ECC_P384_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP521) => ECC_P521_EK_CERTIFICATE_NV_INDEX,
AsymmetricAlgorithmSelection::Ecc(EccCurve::Sm2P256) => {
ECC_P256_SM2_EK_CERTIFICATE_NV_INDEX
}
_ => return Err(Error::local_error(WrapperErrorKind::UnsupportedParam)),
};

let nv_idx = NvIndexTpmHandle::new(nv_idx).unwrap();
Expand Down
35 changes: 34 additions & 1 deletion tss-esapi/src/abstraction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ pub mod pcr;
pub mod public;
pub mod transient;

use crate::{attributes::ObjectAttributesBuilder, structures::PublicBuilder};
use std::convert::TryFrom;

use crate::{
attributes::ObjectAttributesBuilder,
interface_types::{algorithm::AsymmetricAlgorithm, ecc::EccCurve, key_bits::RsaKeyBits},
structures::PublicBuilder,
Error, WrapperErrorKind,
};

/// KeyCustomizaion allows to adjust how a key is going to be created
pub trait KeyCustomization {
Expand Down Expand Up @@ -60,3 +67,29 @@ impl IntoKeyCustomization for Option<DefaultKey> {
None
}
}

/// Enum representing the asymmetric algorithm interface type with specific properties.
///
/// # Details
/// Use this instead of [AsymmetricAlgorithm].
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AsymmetricAlgorithmSelection {
Rsa(RsaKeyBits),
Ecc(EccCurve),
}

/// The conversion assumes for RSA 2048 bit size and for ECC the Nist P256 curve,
/// which matches the defaults in tpm2-tools.
impl TryFrom<AsymmetricAlgorithm> for AsymmetricAlgorithmSelection {
type Error = Error;

fn try_from(value: AsymmetricAlgorithm) -> Result<Self, Self::Error> {
match value {
AsymmetricAlgorithm::Rsa => Ok(AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048)),
AsymmetricAlgorithm::Ecc => Ok(AsymmetricAlgorithmSelection::Ecc(EccCurve::NistP256)),
AsymmetricAlgorithm::Null => {
Err(Error::local_error(WrapperErrorKind::UnsupportedParam))
}
}
}
}
28 changes: 18 additions & 10 deletions tss-esapi/src/abstraction/transient/key_attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
use super::{ObjectWrapper, TransientKeyContext};
use crate::{
abstraction::ek,
abstraction::{ek, AsymmetricAlgorithmSelection},
constants::SessionType,
handles::{AuthHandle, KeyHandle, SessionHandle},
interface_types::{
algorithm::{AsymmetricAlgorithm, HashingAlgorithm},
algorithm::HashingAlgorithm,
key_bits::RsaKeyBits,
session_handles::{AuthSession, PolicySession},
},
structures::{EncryptedSecret, IdObject, SymmetricDefinition},
Expand Down Expand Up @@ -154,13 +155,16 @@ impl TransientKeyContext {
None,
);
Ok((
ek::create_ek_object(&mut self.context, AsymmetricAlgorithm::Rsa, None).or_else(
|e| {
self.context
.flush_context(SessionHandle::from(session).into())?;
Err(e)
},
)?,
ek::create_ek_object(
&mut self.context,
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
None,
)
.or_else(|e| {
self.context
.flush_context(SessionHandle::from(session).into())?;
Err(e)
})?,
session,
))
}
Expand Down Expand Up @@ -191,7 +195,11 @@ 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,
AsymmetricAlgorithmSelection::Rsa(RsaKeyBits::Rsa2048),
None,
)?;
let (attesting_key_pub, _, _) = context.read_public(key_handle).or_else(|e| {
context.flush_context(key_handle.into())?;
Err(e)
Expand Down
3 changes: 2 additions & 1 deletion tss-esapi/src/interface_types/algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ impl TryFrom<TPMI_ALG_SYM_MODE> for SymmetricMode {
/// Enum representing the asymmetric algorithm interface type.
///
/// # Details
/// This corresponds to TPMI_ALG_ASYM
/// Use [AsymmetricAlgorithmSelection] instead where possible.
/// This corresponds to TPMI_ALG_ASYM.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum AsymmetricAlgorithm {
Rsa,
Expand Down
Loading