Skip to content

Instantly share code, notes, and snippets.

@brandsimon
Created September 10, 2023 20:01
Show Gist options
  • Save brandsimon/b6c898a5a5021cf9757756a8319b741e to your computer and use it in GitHub Desktop.
Save brandsimon/b6c898a5a5021cf9757756a8319b741e to your computer and use it in GitHub Desktop.
TPM2 rust-tss-esapi problem
#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_variables)]
use std::io;
use std::io::BufReader;
use std::io::Read;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
use std::fs::File;
use std::str::FromStr;
use tss_esapi::{
attributes::{
ObjectAttributesBuilder,
SessionAttributesBuilder,
},
Context,
constants::{
SessionType,
StructureTag,
tss::{
TPM2_ST_HASHCHECK,
TPM2_RH_ENDORSEMENT,
},
},
handles::{
KeyHandle,
ObjectHandle,
PcrHandle,
},
interface_types::{
algorithm::{
HashingAlgorithm,
PublicAlgorithm,
SymmetricMode,
},
ecc::EccCurve,
key_bits::AesKeyBits,
resource_handles::Hierarchy,
session_handles::AuthSession,
},
structures::{
Auth,
Digest,
DigestValues,
EccPoint,
EccScheme,
HashScheme,
HashcheckTicket,
KeyDerivationFunctionScheme,
PcrSelectionList,
PcrSlot,
Private,
Public,
PublicBuffer,
PublicBuilder,
PublicEccParametersBuilder,
SignatureScheme,
SymmetricDefinition,
SymmetricDefinitionObject,
},
TctiNameConf,
tcti_ldr::DeviceConfig,
tss2_esys::TPMT_TK_HASHCHECK,
};
pub use tss_esapi::Error;
fn to_path_buf(s: &str) -> PathBuf {
return Path::new(s).to_path_buf();
}
fn read_file(filename: &PathBuf) -> io::Result<Vec<u8>> {
let f = File::open(filename)?;
let mut reader = BufReader::new(f);
let mut buffer = Vec::new();
reader.read_to_end(&mut buffer)?;
return Ok(buffer);
}
fn run() -> Result<(), Error> {
let device = TctiNameConf::Device(
DeviceConfig::from_str(&"/dev/tpm0")?);
let mut context = Context::new(device)?;
println!("Was here 0");
//tpm2_createprimary \
// --attributes "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|restricted|decrypt"
let primary_ecc_parms = PublicEccParametersBuilder::new()
.with_ecc_scheme(
EccScheme::EcDh(HashScheme::new(HashingAlgorithm::Sha256)),
)
.with_curve(EccCurve::NistP256)
.with_is_decryption_key(true)
.with_restricted(true)
.with_symmetric(SymmetricDefinitionObject::Aes {
key_bits: AesKeyBits::Aes128,
// mode: SymmetricMode::Null,
mode: SymmetricMode::Cfb
})
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
// .with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Kdf2(HashScheme::new(HashingAlgorithm::Sha256)))
.build()?;
let primary_object_attributes = ObjectAttributesBuilder::new()
.with_fixed_tpm(true)
.with_fixed_parent(true)
.with_sensitive_data_origin(true)
.with_user_with_auth(true)
.with_restricted(true)
.with_decrypt(true)
.build()?;
let primary_pub = PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(primary_object_attributes)
.with_ecc_parameters(primary_ecc_parms)
.with_ecc_unique_identifier(EccPoint::default())
.build()?;
println!("Was here 1");
let session = context.start_auth_session(
None, None, None,
SessionType::Hmac,
// SymmetricDefinition::AES_256_CFB,
SymmetricDefinition::Aes {
key_bits: AesKeyBits::Aes128,
// mode: SymmetricMode::Null,
mode: SymmetricMode::Cfb,
},
HashingAlgorithm::Sha256,
)?.unwrap();
let (session_attributes, session_attributes_mask) = SessionAttributesBuilder::new()
.with_decrypt(true)
.with_encrypt(true)
.build();
context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)?;
context.set_sessions((Some(session), None, None));
let pcrs = PcrSelectionList::builder()
.with_selection(HashingAlgorithm::Sha256, &[PcrSlot::Slot7])
.build()?;
println!("Was here 1b");
let primary = context.create_primary(Hierarchy::Endorsement, primary_pub, None, None, None, Some(pcrs.clone()))?;
println!("Was here 2");
//tpm2_create \
// --attributes "fixedtpm|fixedparent|sensitivedataorigin${create_attribute}|noda|sign"
let ecc_parms = PublicEccParametersBuilder::new()
.with_ecc_scheme(
EccScheme::EcDsa(HashScheme::new(HashingAlgorithm::Sha256)),
)
.with_curve(EccCurve::NistP256)
.with_is_signing_key(true)
.with_restricted(true)
.with_key_derivation_function_scheme(KeyDerivationFunctionScheme::Null)
.build()?;
let object_attributes = ObjectAttributesBuilder::new()
.with_fixed_tpm(true)
.with_fixed_parent(true)
.with_sensitive_data_origin(true)
.with_no_da(true)
.with_sign_encrypt(true)
// .with_restricted(true)
.build()?;
let public_attr = PublicBuilder::new()
.with_public_algorithm(PublicAlgorithm::Ecc)
.with_name_hashing_algorithm(HashingAlgorithm::Sha256)
.with_object_attributes(object_attributes)
// .with_auth_policy(digest)
.with_ecc_parameters(ecc_parms)
.with_ecc_unique_identifier(EccPoint::default())
.build()?;
println!("Was here 3");
let public_content = read_file(&to_path_buf("initramfs/tpm2/test/ecc.pub")).unwrap();
let private_content = read_file(&to_path_buf("initramfs/tpm2/test/ecc.priv")).unwrap();
let private = Private::try_from(private_content)?;
let public = Public::try_from(PublicBuffer::try_from(public_content)?)?;
let handle = context.load(primary.key_handle, private, public)?;
println!("Was here 4");
/*
let res = context.create(
primary.key_handle, public_attr,
None, None, None, Some(pcrs))?;
*/
let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let digest = Digest::try_from(data.clone())?;
let ticket = HashcheckTicket::try_from(TPMT_TK_HASHCHECK {
tag: TPM2_ST_HASHCHECK,
hierarchy: TPM2_RH_ENDORSEMENT,
digest: Default::default(),
})?;
let sig_scheme = SignatureScheme::EcDsa {
hash_scheme: HashScheme::new(HashingAlgorithm::Sha256),
};
let result = context.sign(handle, digest, sig_scheme, ticket);
println!("{:?}", result);
return Ok(());
}
fn main() {
run().unwrap();
}
Compiling cryptographic-id-rs v0.2.2 (/home/desktop/cryptographic-id-rs)
Finished dev [unoptimized + debuginfo] target(s) in 1.69s
Running `target/debug/cryptographic-id-rs`
Was here 0
Was here 1
Was here 1b
WARNING:esys:src/tss2-esys/api/Esys_CreatePrimary.c:400:Esys_CreatePrimary_Finish() Received TPM Error
ERROR:esys:src/tss2-esys/api/Esys_CreatePrimary.c:135:Esys_CreatePrimary() Esys Finish ErrorCode (0x000002d2)
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Tss2Error(FormatOne(FormatOneResponseCode { .0: 722, error_number: 18, parameter: true, format_selector: true, number: 2 }))', src/main.rs:204:11
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
#!/usr/bin/sh
sign_tpm2() {
dir="${1}"
pcrs="7"
tpm2_startauthsession \
-S "/tmp/session.ctx" \
--policy-session
tpm2_policypcr \
--quiet \
--policy "/tmp/policy.pcr" \
--session "/tmp/session.ctx" \
--pcr-list "sha256:${pcrs}"
policy="/tmp/policy.pcr"
auth="session:/tmp/session.ctx"
tpm2_createprimary \
--quiet \
--hierarchy e \
--hash-algorithm sha256 \
--key-algorithm ecc256 \
--key-context "/tmp/primary.ctx" \
--policy "${policy}" \
--attributes "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|restricted|decrypt"
handle="/tmp/handle"
tpm2_load \
--quiet \
--parent-context "/tmp/primary.ctx" \
--public "${dir}/ecc.pub" \
--private "${dir}/ecc.priv" \
--key-context "${handle}"
echo "text" > /tmp/to_sign.bin
tpm2_sign \
--key-context "${handle}" \
--hash-algorithm sha256 \
--scheme ecdsa \
--format plain \
--auth "${auth}" \
--signature "/tmp/signature" \
"/tmp/to_sign.bin"
tpm2_flushcontext "/tmp/session.ctx"
sha256sum /tmp/signature
rm -f "/tmp/policy.pcr" "/tmp/session.ctx"
rm -f "/tmp/signature"
rm -f "/tmp/to_sign.bin"
}
sign_tpm2 initramfs/tpm2/test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment