Move tpm_objects functions to other module

Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
This commit is contained in:
Patrick Uiterwijk 2020-08-03 16:47:21 +02:00
parent 98ae987519
commit 387826aef7
2 changed files with 150 additions and 143 deletions

View file

@ -31,7 +31,6 @@ use std::io::{self, Read, Write};
use biscuit::jwe;
use biscuit::CompactJson;
use tss_esapi::constants;
use tss_esapi::tss2_esys::{ESYS_TR, ESYS_TR_NONE, ESYS_TR_RH_OWNER};
use tss_esapi::utils;
use tss_esapi::utils::tcti;
@ -41,6 +40,8 @@ use serde::{Deserialize, Serialize};
use tpm2_policy::{TPMPolicyStep, SignedPolicyList, PublicKey};
mod tpm_objects;
fn serialize_as_base64_url_no_pad<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
@ -430,39 +431,6 @@ fn get_mode_and_cfg(args: &[String]) -> Result<(ActionMode, Option<TPM2Config>),
Ok((mode, cfg))
}
fn create_tpm2b_public_sealed_object(
policy: Option<tss_esapi::utils::Digest>,
) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC, PinError> {
let mut object_attributes = utils::ObjectAttributes(0);
object_attributes.set_fixed_tpm(true);
object_attributes.set_fixed_parent(true);
object_attributes.set_no_da(true);
object_attributes.set_admin_with_policy(true);
if policy.is_none() {
object_attributes.set_user_with_auth(true);
}
let policy = match policy {
Some(p) => p,
None => tss_esapi::utils::Digest::try_from(vec![])?,
};
let mut params: tss_esapi::tss2_esys::TPMU_PUBLIC_PARMS = Default::default();
params.keyedHashDetail.scheme.scheme = tss_esapi::constants::TPM2_ALG_NULL;
Ok(tss_esapi::tss2_esys::TPM2B_PUBLIC {
size: std::mem::size_of::<tss_esapi::tss2_esys::TPMT_PUBLIC>() as u16,
publicArea: tss_esapi::tss2_esys::TPMT_PUBLIC {
type_: tss_esapi::constants::TPM2_ALG_KEYEDHASH,
nameAlg: tss_esapi::constants::TPM2_ALG_SHA256,
objectAttributes: object_attributes.0,
authPolicy: tss_esapi::tss2_esys::TPM2B_DIGEST::try_from(policy)?,
parameters: params,
unique: Default::default(),
},
})
}
fn perform_encrypt(cfg: TPM2Config, input: &str) -> Result<(), PinError> {
let key_type = match &cfg.key {
None => "ecc",
@ -494,13 +462,13 @@ fn perform_encrypt(cfg: TPM2Config, input: &str) -> Result<(), PinError> {
]);
let jwk_str = serde_json::to_string(&jwk)?;
let public = create_tpm2b_public_sealed_object(policy_digest)?;
let public = tpm_objects::create_tpm2b_public_sealed_object(policy_digest)?;
let (jwk_priv, jwk_pub) =
ctx.create_key(key_handle, &public, &[], jwk_str.as_bytes(), &[], &[])?;
let jwk_priv = get_tpm2b_private(jwk_priv)?;
let jwk_priv = tpm_objects::get_tpm2b_private(jwk_priv)?;
let jwk_pub = get_tpm2b_public(jwk_pub)?;
let jwk_pub = tpm_objects::get_tpm2b_public(jwk_pub)?;
let hdr: biscuit::jwe::Header<ClevisHeader> = biscuit::jwe::Header {
registered: biscuit::jwe::RegisteredHeader {
@ -648,112 +616,9 @@ impl CompactJson for Tpm2Inner {}
impl CompactJson for ClevisHeader {}
impl CompactJson for ClevisInner {}
fn get_tpm2b_public(val: tss_esapi::tss2_esys::TPM2B_PUBLIC) -> Result<Vec<u8>, PinError> {
let mut offset = 0 as u64;
let mut resp = Vec::with_capacity((val.size + 4) as usize);
unsafe {
let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Marshal(
&val,
resp.as_mut_ptr(),
resp.capacity() as u64,
&mut offset,
);
if res != 0 {
return Err(PinError::Text("Marshalling tpm2b_public failed"));
}
resp.set_len(offset as usize);
}
Ok(resp)
}
fn get_tpm2b_private(val: tss_esapi::tss2_esys::TPM2B_PRIVATE) -> Result<Vec<u8>, PinError> {
let mut offset = 0 as u64;
let mut resp = Vec::with_capacity((val.size + 4) as usize);
unsafe {
let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Marshal(
&val,
resp.as_mut_ptr(),
resp.capacity() as u64,
&mut offset,
);
if res != 0 {
return Err(PinError::Text("Marshalling tpm2b_private failed"));
}
resp.set_len(offset as usize);
}
Ok(resp)
}
fn build_tpm2b_private(val: &[u8]) -> Result<tss_esapi::tss2_esys::TPM2B_PRIVATE, PinError> {
let mut resp = tss_esapi::tss2_esys::TPM2B_PRIVATE::default();
let mut offset = 0 as u64;
unsafe {
let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Unmarshal(
val[..].as_ptr(),
val.len() as u64,
&mut offset,
&mut resp,
);
if res != 0 {
return Err(PinError::Text("Unmarshalling tpm2b_private failed"));
}
}
Ok(resp)
}
fn build_tpm2b_public(val: &[u8]) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC, PinError> {
let mut resp = tss_esapi::tss2_esys::TPM2B_PUBLIC::default();
let mut offset = 0 as u64;
unsafe {
let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Unmarshal(
val[..].as_ptr(),
val.len() as u64,
&mut offset,
&mut resp,
);
if res != 0 {
return Err(PinError::Text("Unmarshalling tpm2b_public failed"));
}
}
Ok(resp)
}
fn create_restricted_ecc_public() -> tss_esapi::tss2_esys::TPM2B_PUBLIC {
let ecc_params = utils::TpmsEccParmsBuilder::new_restricted_decryption_key(
utils::algorithm_specifiers::Cipher::aes_128_cfb(),
utils::algorithm_specifiers::EllipticCurve::NistP256,
)
.build()
.unwrap();
let mut object_attributes = utils::ObjectAttributes(0);
object_attributes.set_fixed_tpm(true);
object_attributes.set_fixed_parent(true);
object_attributes.set_sensitive_data_origin(true);
object_attributes.set_user_with_auth(true);
object_attributes.set_decrypt(true);
object_attributes.set_sign_encrypt(false);
object_attributes.set_restricted(true);
utils::Tpm2BPublicBuilder::new()
.with_type(constants::TPM2_ALG_ECC)
.with_name_alg(constants::TPM2_ALG_SHA256)
.with_object_attributes(object_attributes)
.with_parms(utils::PublicParmsUnion::EccDetail(ecc_params))
.build()
.unwrap()
}
fn get_key_public(key_type: &str) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC, PinError> {
match key_type {
"ecc" => Ok(create_restricted_ecc_public()),
"ecc" => Ok(tpm_objects::create_restricted_ecc_public()),
"rsa" => Ok(tss_esapi::utils::create_restricted_decryption_rsa_public(
utils::algorithm_specifiers::Cipher::aes_128_cfb(),
2048,
@ -771,8 +636,8 @@ fn perform_decrypt(input: &str) -> Result<(), PinError> {
return Err(PinError::Text("JWE pin mismatch"));
}
let jwkpub = build_tpm2b_public(&hdr.private.clevis.tpm2.jwk_pub)?;
let jwkpriv = build_tpm2b_private(&hdr.private.clevis.tpm2.jwk_priv)?;
let jwkpub = tpm_objects::build_tpm2b_public(&hdr.private.clevis.tpm2.jwk_pub)?;
let jwkpriv = tpm_objects::build_tpm2b_private(&hdr.private.clevis.tpm2.jwk_priv)?;
let policy = TPMPolicyStep::try_from(&hdr.private.clevis.tpm2)?;

142
src/tpm_objects.rs Normal file
View file

@ -0,0 +1,142 @@
use std::convert::TryFrom;
use tss_esapi::constants;
use tss_esapi::utils;
use crate::PinError;
pub(super) fn create_tpm2b_public_sealed_object(
policy: Option<tss_esapi::utils::Digest>,
) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC, PinError> {
let mut object_attributes = utils::ObjectAttributes(0);
object_attributes.set_fixed_tpm(true);
object_attributes.set_fixed_parent(true);
object_attributes.set_no_da(true);
object_attributes.set_admin_with_policy(true);
if policy.is_none() {
object_attributes.set_user_with_auth(true);
}
let policy = match policy {
Some(p) => p,
None => tss_esapi::utils::Digest::try_from(vec![])?,
};
let mut params: tss_esapi::tss2_esys::TPMU_PUBLIC_PARMS = Default::default();
params.keyedHashDetail.scheme.scheme = tss_esapi::constants::TPM2_ALG_NULL;
Ok(tss_esapi::tss2_esys::TPM2B_PUBLIC {
size: std::mem::size_of::<tss_esapi::tss2_esys::TPMT_PUBLIC>() as u16,
publicArea: tss_esapi::tss2_esys::TPMT_PUBLIC {
type_: tss_esapi::constants::TPM2_ALG_KEYEDHASH,
nameAlg: tss_esapi::constants::TPM2_ALG_SHA256,
objectAttributes: object_attributes.0,
authPolicy: tss_esapi::tss2_esys::TPM2B_DIGEST::try_from(policy)?,
parameters: params,
unique: Default::default(),
},
})
}
pub(super) fn get_tpm2b_public(val: tss_esapi::tss2_esys::TPM2B_PUBLIC) -> Result<Vec<u8>, PinError> {
let mut offset = 0 as u64;
let mut resp = Vec::with_capacity((val.size + 4) as usize);
unsafe {
let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Marshal(
&val,
resp.as_mut_ptr(),
resp.capacity() as u64,
&mut offset,
);
if res != 0 {
return Err(PinError::Text("Marshalling tpm2b_public failed"));
}
resp.set_len(offset as usize);
}
Ok(resp)
}
pub(super) fn get_tpm2b_private(val: tss_esapi::tss2_esys::TPM2B_PRIVATE) -> Result<Vec<u8>, PinError> {
let mut offset = 0 as u64;
let mut resp = Vec::with_capacity((val.size + 4) as usize);
unsafe {
let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Marshal(
&val,
resp.as_mut_ptr(),
resp.capacity() as u64,
&mut offset,
);
if res != 0 {
return Err(PinError::Text("Marshalling tpm2b_private failed"));
}
resp.set_len(offset as usize);
}
Ok(resp)
}
pub(super) fn build_tpm2b_private(val: &[u8]) -> Result<tss_esapi::tss2_esys::TPM2B_PRIVATE, PinError> {
let mut resp = tss_esapi::tss2_esys::TPM2B_PRIVATE::default();
let mut offset = 0 as u64;
unsafe {
let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PRIVATE_Unmarshal(
val[..].as_ptr(),
val.len() as u64,
&mut offset,
&mut resp,
);
if res != 0 {
return Err(PinError::Text("Unmarshalling tpm2b_private failed"));
}
}
Ok(resp)
}
pub(super) fn build_tpm2b_public(val: &[u8]) -> Result<tss_esapi::tss2_esys::TPM2B_PUBLIC, PinError> {
let mut resp = tss_esapi::tss2_esys::TPM2B_PUBLIC::default();
let mut offset = 0 as u64;
unsafe {
let res = tss_esapi::tss2_esys::Tss2_MU_TPM2B_PUBLIC_Unmarshal(
val[..].as_ptr(),
val.len() as u64,
&mut offset,
&mut resp,
);
if res != 0 {
return Err(PinError::Text("Unmarshalling tpm2b_public failed"));
}
}
Ok(resp)
}
pub(super) fn create_restricted_ecc_public() -> tss_esapi::tss2_esys::TPM2B_PUBLIC {
let ecc_params = utils::TpmsEccParmsBuilder::new_restricted_decryption_key(
utils::algorithm_specifiers::Cipher::aes_128_cfb(),
utils::algorithm_specifiers::EllipticCurve::NistP256,
)
.build()
.unwrap();
let mut object_attributes = utils::ObjectAttributes(0);
object_attributes.set_fixed_tpm(true);
object_attributes.set_fixed_parent(true);
object_attributes.set_sensitive_data_origin(true);
object_attributes.set_user_with_auth(true);
object_attributes.set_decrypt(true);
object_attributes.set_sign_encrypt(false);
object_attributes.set_restricted(true);
utils::Tpm2BPublicBuilder::new()
.with_type(constants::TPM2_ALG_ECC)
.with_name_alg(constants::TPM2_ALG_SHA256)
.with_object_attributes(object_attributes)
.with_parms(utils::PublicParmsUnion::EccDetail(ecc_params))
.build()
.unwrap()
}