rust-tss-esapi icon indicating copy to clipboard operation
rust-tss-esapi copied to clipboard

ek, ak abstractions: allow to specficy exact key type

Open Superhepper opened this issue 1 year ago • 7 comments

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 )

Superhepper avatar Sep 22 '24 17:09 Superhepper

I need to rebase it on https://github.com/parallaxsecond/rust-tss-esapi/pull/547 before it will pass all CI tests.

Superhepper avatar Sep 22 '24 20:09 Superhepper

@Superhepper I'll develop try to develop the fix for this issue against this branch and will report back. Thanks for backporting it!

THS-on avatar Sep 27 '24 13:09 THS-on

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?

THS-on avatar Oct 01 '24 20:10 THS-on

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.

Superhepper avatar Oct 02 '24 08:10 Superhepper

Now, I just need to figure out why these changes made the tests fail on Fedora ..

Superhepper avatar Oct 02 '24 10:10 Superhepper

@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

THS-on avatar Oct 03 '24 09:10 THS-on

@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.

Superhepper avatar Oct 04 '24 18:10 Superhepper

@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.

Superhepper avatar Oct 14 '24 18:10 Superhepper

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:

THS-on avatar Oct 15 '24 20:10 THS-on

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);
}

THS-on avatar Oct 16 '24 08:10 THS-on

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.

Superhepper avatar Oct 16 '24 18:10 Superhepper

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!

THS-on avatar Oct 17 '24 09:10 THS-on

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

THS-on avatar Oct 17 '24 10:10 THS-on

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.

THS-on avatar Oct 17 '24 13:10 THS-on

Changes are implemented in https://github.com/parallaxsecond/rust-tss-esapi/pull/552

THS-on avatar Oct 21 '24 10:10 THS-on

I will add the changes #552 to this PR when I got the time.

Superhepper avatar Oct 30 '24 11:10 Superhepper

@THS-on I have added your latest patch this one so please try it out again.

Superhepper avatar Nov 07 '24 20:11 Superhepper

@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.

THS-on avatar Nov 08 '24 07:11 THS-on

I will make a more thorough check to see if I messed something up when I added the latest commit yesterday.

Superhepper avatar Nov 08 '24 07:11 Superhepper

@THS-on - if you can share the code you used to get the above error, that would be good enough too.

ionut-arm avatar Nov 09 '24 10:11 ionut-arm

@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

THS-on avatar Nov 09 '24 11:11 THS-on