Skip to content

Commit

Permalink
20231125 tpm context (#26)
Browse files Browse the repository at this point in the history
* Add support for tpm idkey signing and verification
  • Loading branch information
Firstyear authored Dec 21, 2023
1 parent 95c09a5 commit e2c81c6
Show file tree
Hide file tree
Showing 4 changed files with 548 additions and 55 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ authors = ["William Brown <[email protected]>"]
# default = ["tpm"]
tpm = ["dep:tss-esapi"]

# tss-esapi = { path = "../rust-tss-esapi/tss-esapi" }

[dependencies]
argon2 = { version = "0.5.2", features = ["alloc"] }
hex = "0.4.3"
Expand All @@ -23,3 +25,5 @@ zeroize = "1.6.0"

[dev-dependencies]
tracing-subscriber = "^0.3.17"


120 changes: 114 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
use argon2::MIN_SALT_LEN;
use openssl::pkey::{PKey, Private};
use openssl::x509::X509;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use tracing::error;
use zeroize::Zeroizing;

#[cfg(not(feature = "tpm"))]
use serde::{Deserialize, Serialize};

pub mod soft;

#[cfg(feature = "tpm")]
Expand Down Expand Up @@ -187,9 +189,28 @@ pub enum TpmError {
TpmHmacKeyCreate,
TpmHmacKeyLoad,
TpmHmacSign,

TpmHmacInputTooLarge,

TpmIdentityKeyObjectAttributesInvalid,
TpmIdentityKeyAlgorithmInvalid,
TpmIdentityKeyBuilderInvalid,
TpmIdentityKeyCreate,
TpmIdentityKeySign,
TpmIdentityKeySignatureInvalid,
TpmIdentityKeyEcdsaSigRInvalid,
TpmIdentityKeyEcdsaSigSInvalid,
TpmIdentityKeyEcdsaSigFromParams,
TpmIdentityKeyEcdsaSigToDer,

TpmIdentityKeyParamInvalid,
TpmIdentityKeyParamsToRsaSig,

TpmIdentityKeyDerToEcdsaSig,
TpmIdentityKeyParamRInvalid,
TpmIdentityKeyParamSInvalid,
TpmIdentityKeyParamsToEcdsaSig,
TpmIdentityKeyVerify,

TpmOperationUnsupported,

Entropy,
Expand Down Expand Up @@ -254,11 +275,12 @@ pub enum HmacKey {
},
#[cfg(not(feature = "tpm"))]
TpmSha256 {
key_handle: (),
key_context: (),
},
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone)]
#[cfg_attr(not(feature = "tpm"), derive(Serialize, Deserialize))]
pub enum LoadableIdentityKey {
SoftEcdsa256V1 {
key: Vec<u8>,
Expand All @@ -272,6 +294,22 @@ pub enum LoadableIdentityKey {
iv: [u8; 16],
x509: Option<Vec<u8>>,
},
#[cfg(feature = "tpm")]
TpmEcdsa256V1 {
private: tpm::Private,
public: tpm::Public,
x509: Option<Vec<u8>>,
},
#[cfg(not(feature = "tpm"))]
TpmEcdsa256V1 { private: (), public: (), x509: () },
#[cfg(feature = "tpm")]
TpmRsa2048V1 {
private: tpm::Private,
public: tpm::Public,
x509: Option<Vec<u8>>,
},
#[cfg(not(feature = "tpm"))]
TpmRsa2048V1 { private: (), public: (), x509: () },
}

pub enum IdentityKey {
Expand All @@ -283,13 +321,31 @@ pub enum IdentityKey {
pkey: PKey<Private>,
x509: Option<X509>,
},
#[cfg(feature = "tpm")]
TpmEcdsa256 {
key_context: tpm::TpmsContext,
x509: Option<X509>,
},
#[cfg(not(feature = "tpm"))]
TpmEcdsa256 { key_context: (), x509: () },
#[cfg(feature = "tpm")]
TpmRsa2048 {
key_context: tpm::TpmsContext,
x509: Option<X509>,
},
#[cfg(not(feature = "tpm"))]
TpmRsa2048 { key_context: (), x509: () },
}

impl IdentityKey {
pub fn alg(&self) -> KeyAlgorithm {
match self {
IdentityKey::SoftEcdsa256 { .. } => KeyAlgorithm::Ecdsa256,
IdentityKey::SoftRsa2048 { .. } => KeyAlgorithm::Rsa2048,
IdentityKey::SoftEcdsa256 { .. } | IdentityKey::TpmEcdsa256 { .. } => {
KeyAlgorithm::Ecdsa256
}
IdentityKey::SoftRsa2048 { .. } | IdentityKey::TpmRsa2048 { .. } => {
KeyAlgorithm::Rsa2048
}
}
}
}
Expand Down Expand Up @@ -555,6 +611,58 @@ mod tests {
};
}

#[macro_export]
macro_rules! test_tpm_identity_no_export {
( $tpm:expr, $alg:expr ) => {
use crate::{AuthValue, Tpm};
use std::str::FromStr;
use tracing::trace;

let _ = tracing_subscriber::fmt::try_init();

let auth_str = AuthValue::generate().expect("Failed to create hex pin");

let auth_value = AuthValue::from_str(&auth_str).expect("Unable to create auth value");

// Request a new machine-key-context. This key "owns" anything
// created underneath it.
let loadable_machine_key = $tpm
.machine_key_create(&auth_value)
.expect("Unable to create new machine key");

trace!(?loadable_machine_key);

let machine_key = $tpm
.machine_key_load(&auth_value, &loadable_machine_key)
.expect("Unable to load machine key");

// from that ctx, create an identity key
let loadable_id_key = $tpm
.identity_key_create(&machine_key, $alg)
.expect("Unable to create id key");

trace!(?loadable_id_key);

let id_key = $tpm
.identity_key_load(&machine_key, &loadable_id_key)
.expect("Unable to load id key");

let input = "test string";
let signature = $tpm
.identity_key_sign(&id_key, input.as_bytes())
.expect("Unable to sign input");

trace!(?signature);

let verify = $tpm.identity_key_verify(&id_key, input.as_bytes(), signature.as_slice());

trace!(?verify);

// Internal verification
assert!(verify.expect("Unable to sign input"));
};
}

#[macro_export]
macro_rules! test_tpm_identity {
( $tpm:expr, $alg:expr ) => {
Expand Down
42 changes: 38 additions & 4 deletions src/soft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,9 @@ impl Tpm for SoftTpm {
TpmError::IdentityKeyPublicToDer
})
}
IdentityKey::TpmEcdsa256 { .. } | IdentityKey::TpmRsa2048 { .. } => {
Err(TpmError::IncorrectKeyType)
}
}
}

Expand All @@ -339,6 +342,9 @@ impl Tpm for SoftTpm {
TpmError::IdentityKeyPublicToPem
})
}
IdentityKey::TpmEcdsa256 { .. } | IdentityKey::TpmRsa2048 { .. } => {
Err(TpmError::IncorrectKeyType)
}
}
}

Expand All @@ -355,6 +361,9 @@ impl Tpm for SoftTpm {
error!(?ossl_err);
TpmError::IdentityKeyX509ToPem
}),
IdentityKey::TpmEcdsa256 { .. } | IdentityKey::TpmRsa2048 { .. } => {
Err(TpmError::IncorrectKeyType)
}
_ => Err(TpmError::IdentityKeyX509Missing),
}
}
Expand All @@ -372,6 +381,9 @@ impl Tpm for SoftTpm {
error!(?ossl_err);
TpmError::IdentityKeyX509ToDer
}),
IdentityKey::TpmEcdsa256 { .. } | IdentityKey::TpmRsa2048 { .. } => {
Err(TpmError::IncorrectKeyType)
}
_ => Err(TpmError::IdentityKeyX509Missing),
}
}
Expand All @@ -385,12 +397,23 @@ impl Tpm for SoftTpm {
TpmError::IdentityKeyInvalidForSigning
})?
}
IdentityKey::TpmEcdsa256 { .. } | IdentityKey::TpmRsa2048 { .. } => {
return Err(TpmError::IncorrectKeyType)
}
};

signer.sign_oneshot_to_vec(input).map_err(|ossl_err| {
error!(?ossl_err);
TpmError::IdentityKeySignature
})
signer
.sign_oneshot_to_vec(input)
.map_err(|ossl_err| {
error!(?ossl_err);
TpmError::IdentityKeySignature
})
.map(|sig| {
let res = openssl::ecdsa::EcdsaSig::from_der(&sig);
tracing::debug!(res = %res.is_ok());

sig
})
}

fn identity_key_verify(
Expand All @@ -407,6 +430,9 @@ impl Tpm for SoftTpm {
TpmError::IdentityKeyInvalidForVerification
})?
}
IdentityKey::TpmEcdsa256 { .. } | IdentityKey::TpmRsa2048 { .. } => {
return Err(TpmError::IncorrectKeyType)
}
};

verifier
Expand Down Expand Up @@ -465,6 +491,9 @@ impl Tpm for SoftTpm {
TpmError::X509RequestSign
})?;
}
IdentityKey::TpmEcdsa256 { .. } | IdentityKey::TpmRsa2048 { .. } => {
return Err(TpmError::IncorrectKeyType)
}
}

req_builder.build().to_der().map_err(|ossl_err| {
Expand Down Expand Up @@ -499,6 +528,9 @@ impl Tpm for SoftTpm {
return Err(TpmError::X509KeyMismatch);
}
}
IdentityKey::TpmEcdsa256 { .. } | IdentityKey::TpmRsa2048 { .. } => {
return Err(TpmError::IncorrectKeyType)
}
};

// At this point we know the cert belongs to this key, so lets
Expand All @@ -513,6 +545,8 @@ impl Tpm for SoftTpm {
LoadableIdentityKey::SoftRsa2048V1 { ref mut x509, .. } => {
*x509 = Some(certificate_der.to_vec());
}
LoadableIdentityKey::TpmEcdsa256V1 { .. }
| LoadableIdentityKey::TpmRsa2048V1 { .. } => return Err(TpmError::IncorrectKeyType),
};

Ok(cloned_key)
Expand Down
Loading

0 comments on commit e2c81c6

Please sign in to comment.