rust-tss-esapi
rust-tss-esapi copied to clipboard
ek, ak abstractions: allow to specficy exact key type
This adds support other keys than RSA2048 and ECC Nist P256.
This takes the following PRs and from the main branch and adapts them so that they can be merged into the 7.x.y branch:
https://github.com/parallaxsecond/rust-tss-esapi/pull/464 (By @ionut-arm ) https://github.com/parallaxsecond/rust-tss-esapi/pull/414 (By @THS-on )
I need to rebase it on https://github.com/parallaxsecond/rust-tss-esapi/pull/547 before it will pass all CI tests.
@Superhepper I'll develop try to develop the fix for this issue against this branch and will report back. Thanks for backporting it!
When using create_ak(), I get:
ECC unique identifier have not been set in the Public Builder even though the ECC algorithm have been selected. Consider using: .with_ecc_unique_identifier(&EccPoint::default())
Can we just add this to the create_ak_public() function or does this need to be customizable?
been selected. Consider using: .with_ecc_unique_identifier(&EccPoint
Nah, I think it can be added. It has been added in the main branch probably just me who missed it. And the customization would work anyway. Because you can just overwrite it using the key customization.
Now, I just need to figure out why these changes made the tests fail on Fedora ..
@Superhepper for reference, this is probably the change that we then also want to fully backport: https://github.com/parallaxsecond/rust-tss-esapi/pull/464
@Superhepper for reference, this is probably the change that we then also want to fully backport: #464
I will try to add that as well.
@THS-on If you missed it this PR has now been updated with the requested changes so it should work better now I hope. Please try it out.
It now seems to work, but I get a miss match between the EK generated and in the EK cert on the Keylime verifier side. Still need to check where this actually goes wrong, somewhere between rust-tss-esapi, agent and verifier (which implements its own parser for TPM data structures). Once I checked that its not in rust-tss-esapi this PR can be merged :+1:
I tried to write a simple example to compare the generated key with the one in the certificate, but I cannot figure out why it doesn't find the TryFrom<Public> for SubjectPublicKeyInfo. Which is kinda weird as in the Keylime codebase it just works.
use std::convert::TryFrom;
use picky_asn1_x509::SubjectPublicKeyInfo;
use tss_esapi::{abstraction::{ek, AsymmetricAlgorithmSelection, DefaultKey}, interface_types, Context, TctiNameConf};
fn main() {
let tcti_name_conf = TctiNameConf::from_environment_variable().expect("Failed to get TCTI");
let mut ctx = Context::new(tcti_name_conf).expect("Failed to init context");
let ek = ek::create_ek_object(&mut ctx, AsymmetricAlgorithmSelection::Ecc(interface_types::ecc::EccCurve::NistP384), DefaultKey).unwrap();
let (ekpub, _, _) = ctx.read_public(ek).unwrap();
// Here it does not find the trait implementation
let key = SubjectPublicKeyInfo::try_from(ekpub).unwrap();
let res = ek::retrieve_ek_pubcert(&mut ctx, AsymmetricAlgorithmSelection::Ecc(interface_types::ecc::EccCurve::NistP384)).expect("Failed to get ECC Cert");
print!("Data {:#?}", res);
}
I think you have jus
I tried to write a simple example to compare the generated key with the one in the certificate, but I cannot figure out why it doesn't find the TryFrom for SubjectPublicKeyInfo. Which is kinda weird as in the Keylime codebase it just works.
use std::convert::TryFrom; use picky_asn1_x509::SubjectPublicKeyInfo; use tss_esapi::{abstraction::{ek, AsymmetricAlgorithmSelection, DefaultKey}, interface_types, Context, TctiNameConf}; fn main() { let tcti_name_conf = TctiNameConf::from_environment_variable().expect("Failed to get TCTI"); let mut ctx = Context::new(tcti_name_conf).expect("Failed to init context"); let ek = ek::create_ek_object(&mut ctx, AsymmetricAlgorithmSelection::Ecc(interface_types::ecc::EccCurve::NistP384), DefaultKey).unwrap(); let (ekpub, _, _) = ctx.read_public(ek).unwrap(); // Here it does not find the trait implementation let key = SubjectPublicKeyInfo::try_from(ekpub).unwrap(); let res = ek::retrieve_ek_pubcert(&mut ctx, AsymmetricAlgorithmSelection::Ecc(interface_types::ecc::EccCurve::NistP384)).expect("Failed to get ECC Cert"); print!("Data {:#?}", res); }
I just think you have forgotten to add picky-asn1-x509 = "0.12.0" as dependency in the Cargo.toml.
Edit: issue seems to be somewhere in tss-esapi
Old:
I just think you have forgotten to add picky-asn1-x509 = "0.12.0" as dependency in the Cargo.toml.
Thanks for the hint. I've added version "0.13.0", which then didn't work. I can confirm that the issue is somewhere on > the Keylime side, so this can be merged. Thank you for backporting this!
In my test script I only compared the bits and not the fully key. There seems to be still an issue in tss-esapi.
Reproducer
use openssl::pkey::PKey;
use picky_asn1_x509::SubjectPublicKeyInfo;
use tss_esapi::{abstraction::{ek, AsymmetricAlgorithmSelection, DefaultKey}, interface_types, Context, TctiNameConf};
use tss_esapi::structures::Public;
fn main() {
let tcti_name_conf = TctiNameConf::from_environment_variable().expect("Failed to get TCTI");
let mut ctx = Context::new(tcti_name_conf).expect("Failed to init context");
let ek = ek::create_ek_object(&mut ctx, AsymmetricAlgorithmSelection::Ecc(interface_types::ecc::EccCurve::NistP384), DefaultKey).unwrap();
let (ekpub, _, _): (Public, _, _ )= ctx.read_public(ek).unwrap();
let key = PKey::public_key_from_der(&picky_asn1_der::to_vec(&SubjectPublicKeyInfo::try_from(ekpub).unwrap()).unwrap()).unwrap();
let nv_cert = ek::retrieve_ek_pubcert(&mut ctx, AsymmetricAlgorithmSelection::Ecc(interface_types::ecc::EccCurve::NistP384)).expect("Failed to get ECC Cert");
let cert = openssl::x509::X509::from_der(&nv_cert).expect("Failed to parse EK cert");
if key.public_eq(&cert.public_key().unwrap()){
println!("Equal");
}
}
Cargo.toml
[package]
name = "minimal-read-ek"
version = "0.1.0"
edition = "2021"
[dependencies]
picky-asn1-x509 = "0.12.0"
picky-asn1-der = "0.4"
openssl = "0.10.15"
tss-esapi = { git = "https://github.com/parallaxsecond/rust-tss-esapi.git", rev = "refs/pull/546/head" }
Tested with libvrit VM using swtpm version 0.8.2.
Validation that the EK and EK certificate actually match using tpm2-tools:
tpm2_nvread 0x1c00016 | openssl x509 -noout -pubkey | sha256sum
tpm2_createek -G ecc384 -u ek.pub -f pem -c ek.ctx
sha256sum ek.pub
Found the issue. The hashAlg and authPolicy are different for each ECC curve (e.g. section B.4.6 of https://trustedcomputinggroup.org/wp-content/uploads/TCG-EK-Credential-Profile-V-2.5-R2_published.pdf). We hard code them to sha256.
I'll create a PR probably next week that fixes this in the main branch that we then can backport.
Changes are implemented in https://github.com/parallaxsecond/rust-tss-esapi/pull/552
I will add the changes #552 to this PR when I got the time.
@THS-on I have added your latest patch this one so please try it out again.
@Superhepper currently fails with the following in Keylime:
Nov 08 08:14:04 localhost.localdomain keylime_agent[6588]: WARNING:esys:src/tss2-esys/api/Esys_ActivateCredential.c:321:Esys_ActivateCredential_Finish() Received TPM Error
Nov 08 08:14:04 localhost.localdomain keylime_agent[6588]: ERROR:esys:src/tss2-esys/api/Esys_ActivateCredential.c:105:Esys_ActivateCredential() Esys Finish ErrorCode (0x00000a9d)
Nov 08 08:14:04 localhost.localdomain keylime_agent[6588]: Error: Tpm(Tss2 { err: Tss2Error(FormatOne(FormatOneResponseCode { .0: 2717, error_number: 29, parameter: false, format_selector: true, number: 10 })), kind: Some(PolicyFail), message: "a policy check failed (associated with session number 2)" })
I'll try to build a minimal reproducer.
I will make a more thorough check to see if I messed something up when I added the latest commit yesterday.
@THS-on - if you can share the code you used to get the above error, that would be good enough too.
@Superhepper @ionut-arm sorry for the noise regarding this one. It has nothing to do with the rust bindings itself.
Also for activate credential we need to set the policy accordingly for the upper profiles, we are currently are not: https://github.com/keylime/rust-keylime/blob/a3bfd5aa2c3ecea078ac0262821c3878cbdc8b94/keylime/src/tpm.rs#L1205