Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get random authvalues locally instead of from the TPM #510

Merged
merged 3 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Security policy

Security is of paramount importance to the tss-esapi project. We do all we can to identify and fix
issues, however some problems might slip through the cracks. Any efforts towards responsible
disclosure of security problems are greatly appreciated and your contributions will be acknowledged.

## Our disclosure policy

All security vulnerabilities affecting the tss-esapi project - including those reported using the
steps highlighted below, those discovered during routine testing, and those found in our dependency
tree either through `cargo-audit` or otherwise - will receive
[security advisories](https://github.com/parallaxsecond/rust-tss-esapi/security) in a timely
manner. The advisories should include sufficient information about the cause, effect, and possible
mitigations for the vulnerability. If any information is missing, or you would like to raise a
question about the advisories, please open an issue in
[our repo](https://github.com/parallaxsecond/rust-tss-esapi).

Efforts to mitigate for the reported vulnerabilities will be tracked using GitHub issues linked to
the corresponding advisories.

## Reporting a vulnerability

To report a vulnerability, please send an email to
[[email protected]](mailto:[email protected]). We will
promptly reply to your report and we will strive to keep you in the loop as we try to reach a
resolution.

# Security considerations for the use of the software

The authvalue provided to the TPM to perform certain operations like creating Primary Keys is
currently randomly generated by [getrandom](https://crates.io/crates/getrandom), which assumes
"that the system always provides high-quality cryptographically secure random data, ideally backed
by hardware entropy sources."

The user of this software should take this into consideration when setting up their system and using
this software.
1 change: 1 addition & 0 deletions tss-esapi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ cfg-if = "1.0.0"
strum = { version = "0.25.0", optional = true }
strum_macros = { version = "0.25.0", optional = true }
paste = "1.0.14"
getrandom = "0.2.11"

[dev-dependencies]
env_logger = "0.9.0"
Expand Down
25 changes: 17 additions & 8 deletions tss-esapi/src/abstraction/transient/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ impl TransientKeyContext {
///
/// # Errors
/// * if the authentication size is larger than 32 a `WrongParamSize` wrapper error is returned
/// * if there is an error when obtaining random numbers from the local machine
pub fn create_key(
&mut self,
key_params: KeyParams,
Expand All @@ -147,8 +148,12 @@ impl TransientKeyContext {
}
let key_auth = if auth_size > 0 {
self.set_session_attrs()?;
let random_bytes = self.context.get_random(auth_size)?;
Some(Auth::from_bytes(random_bytes.as_bytes())?)
let mut random_bytes = vec![0u8; auth_size];
getrandom::getrandom(&mut random_bytes).map_err(|_| {
log::error!("Failed to obtain a random authvalue for key creation");
Error::WrapperError(ErrorKind::InternalError)
})?;
Some(Auth::from_bytes(random_bytes.as_slice())?)
} else {
None
};
Expand Down Expand Up @@ -630,7 +635,7 @@ impl TransientKeyContextBuilder {
/// Bootstrap the TransientKeyContext.
///
/// The root key is created as a primary key in the provided hierarchy and thus authentication is
/// needed for said hierarchy. The authentication value for the key is generated by the TPM itself,
/// needed for said hierarchy. The authentication value for the key is generated locally in the machine,
/// with a configurable length, and never exposed outside the context.
///
/// # Warning
Expand All @@ -643,9 +648,9 @@ impl TransientKeyContextBuilder {
/// * `root_key_auth_size` must be at most 32
///
/// # Errors
/// * errors are returned if any method calls return an error: `Context::get_random`,
/// `Context::start_auth_session`, `Context::create_primary`, `Context::flush_context`,
/// `Context::set_handle_auth`
/// * errors are returned if any method calls return an error: `Context::start_auth_session`
/// `Context::create_primary`, `Context::flush_context`, `Context::set_handle_auth`
/// or if an internal error occurs when getting random numbers from the local machine
/// * if the root key authentication size is given greater than 32 or if the root key size is
/// not 1024, 2048, 3072 or 4096, a `InvalidParam` wrapper error is returned
pub fn build(mut self) -> Result<TransientKeyContext> {
Expand All @@ -658,8 +663,12 @@ impl TransientKeyContextBuilder {
let mut context = Context::new(self.tcti_name_conf)?;

let root_key_auth = if self.root_key_auth_size > 0 {
let random = context.get_random(self.root_key_auth_size)?;
Some(Auth::from_bytes(random.as_bytes())?)
let mut random = vec![0u8; self.root_key_auth_size];
getrandom::getrandom(&mut random).map_err(|_| {
log::error!("Failed to obtain a random value for root key authentication");
Error::WrapperError(ErrorKind::InternalError)
})?;
Some(Auth::from_bytes(random.as_slice())?)
} else {
None
};
Expand Down
10 changes: 6 additions & 4 deletions tss-esapi/src/context/tpm_commands/asymmetric_primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ impl Context {
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
/// # .expect("Failed to set attributes on session");
/// # context.set_sessions((Some(session), None, None));
/// # let random_digest = context.get_random(16).unwrap();
/// # let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
/// # let mut random_digest = vec![0u8; 16];
/// # getrandom::getrandom(&mut random_digest).unwrap();
/// # let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();
/// #
/// // Create a key suitable for ECDH key generation
/// let ecc_parms = PublicEccParametersBuilder::new()
Expand Down Expand Up @@ -262,8 +263,9 @@ impl Context {
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
/// # .expect("Failed to set attributes on session");
/// # context.set_sessions((Some(session), None, None));
/// # let random_digest = context.get_random(16).unwrap();
/// # let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
/// # let mut random_digest = vec![0u8; 16];
/// # getrandom::getrandom(&mut random_digest).unwrap();
/// # let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();
/// #
/// // Create a key suitable for ECDH key generation
/// let ecc_parms = PublicEccParametersBuilder::new()
Expand Down
7 changes: 3 additions & 4 deletions tss-esapi/src/context/tpm_commands/context_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,9 @@ impl Context {
///
/// // Execute context methods using the session
/// context.execute_with_session(Some(session), |ctx| {
/// let random_digest = ctx.get_random(16)
/// .expect("Call to get_random failed");
/// let key_auth = Auth::from_bytes(random_digest.as_bytes())
/// .expect("Failed to create Auth");
/// let mut random_digest = vec![0u8; 16];
/// getrandom::getrandom(&mut random_digest).expect("Call to getrandom failed");
/// let key_auth = Auth::from_bytes(random_digest.as_slice()).expect("Failed to create Auth");
/// let key_handle = ctx
/// .create_primary(
/// Hierarchy::Owner,
Expand Down
22 changes: 10 additions & 12 deletions tss-esapi/src/context/tpm_commands/symmetric_primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,11 @@ impl Context {
/// # .tr_set_auth(tss_esapi::interface_types::reserved_handles::Hierarchy::Owner.into(), Auth::default())
/// # .expect("Failed to set auth to empty for owner");
/// # // Create primary key auth
/// # let primary_key_auth = Auth::try_from(
/// # context
/// # .get_random(16)
/// # .expect("get_rand call failed")
/// # .as_bytes()
/// # .to_vec(),
/// # let mut random_digest = vec![0u8; 16];
/// # getrandom::getrandom(&mut random_digest).expect("get_rand call failed");
/// # let primary_key_auth = Auth::from_bytes(
/// # random_digest
/// # .as_slice()
/// # )
/// # .expect("Failed to create primary key auth");
/// # // Create primary key
Expand Down Expand Up @@ -103,12 +102,11 @@ impl Context {
/// # .build()
/// # .expect("Failed to create public for symmetric key public");
/// # // Create auth for the symmetric key
/// # let symmetric_key_auth = Auth::try_from(
/// # context
/// # .get_random(16)
/// # .expect("get_rand call failed")
/// # .as_bytes()
/// # .to_vec(),
/// # let mut random_digest = vec![0u8; 16];
/// # getrandom::getrandom(&mut random_digest).expect("get_rand call failed");
/// # let symmetric_key_auth = Auth::from_bytes(
/// # random_digest
/// # .as_slice()
/// # )
/// # .expect("Failed to create symmetric key auth");
/// # // Create symmetric key data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,8 +502,9 @@ fn ctx_migration_test() {
// Create two key contexts using `Context`, one for an RSA keypair,
// one for just the public part of the key
let mut basic_ctx = crate::common::create_ctx_with_session();
let random_digest = basic_ctx.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();
let prim_key_handle = basic_ctx
.create_primary(
Hierarchy::Owner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ mod test_rsa_encrypt_decrypt {
#[test]
fn test_encrypt_decrypt() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let key_handle = context
.create_primary(
Expand Down Expand Up @@ -59,8 +60,9 @@ mod test_rsa_encrypt_decrypt {
#[test]
fn test_ecdh() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let ecc_parms = PublicEccParametersBuilder::new()
.with_ecc_scheme(EccScheme::EcDh(HashScheme::new(HashingAlgorithm::Sha256)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ mod test_ctx_save {
#[test]
fn test_ctx_save() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let key_handle = context
.create_primary(
Expand All @@ -27,8 +28,9 @@ mod test_ctx_save {
#[test]
fn test_ctx_save_leaf() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let prim_key_handle = context
.create_primary(
Expand Down Expand Up @@ -70,13 +72,14 @@ mod test_ctx_load {
#[test]
fn test_ctx_load() {
let mut context = create_ctx_with_session();
let key_auth = context.get_random(16).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();

let prim_key_handle = context
.create_primary(
Hierarchy::Owner,
decryption_key_pub(),
Some(Auth::from_bytes(key_auth.as_bytes()).unwrap()),
Some(Auth::from_bytes(random_digest.as_slice()).unwrap()),
None,
None,
None,
Expand All @@ -88,7 +91,7 @@ mod test_ctx_load {
.create(
prim_key_handle,
signing_key_pub(),
Some(Auth::from_bytes(key_auth.as_bytes()).unwrap()),
Some(Auth::from_bytes(random_digest.as_slice()).unwrap()),
None,
None,
None,
Expand All @@ -112,8 +115,9 @@ mod test_flush_context {
#[test]
fn test_flush_ctx() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let key_handle = context
.create_primary(
Expand All @@ -133,8 +137,9 @@ mod test_flush_context {
#[test]
fn test_flush_parent_ctx() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let prim_key_handle = context
.create_primary(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,8 +536,9 @@ mod test_policy_authorize {
#[test]
fn test_policy_authorize() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let key_handle = context
.create_primary(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ mod test_create_primary {
#[test]
fn test_create_primary() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let key_handle = context
.create_primary(
Expand Down Expand Up @@ -93,8 +94,9 @@ mod test_change_auth {
)
.unwrap();

let random_digest = context.get_random(16).unwrap();
let new_key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let new_key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let new_private = context
.object_change_auth(loaded_key.into(), prim_key_handle.into(), new_key_auth)
Expand All @@ -108,8 +110,9 @@ mod test_change_auth {
fn test_hierarchy_change_auth() {
let mut context = create_ctx_with_session();

let random_digest = context.get_random(16).unwrap();
let new_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let new_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

// NOTE: If this test failed on your system, you are probably running it against a
// real (hardware) TPM or one that is provisioned. This hierarchy is supposed to be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// SPDX-License-Identifier: Apache-2.0
mod test_create {
use crate::common::{create_ctx_with_session, decryption_key_pub};
use std::convert::TryFrom;
use tss_esapi::{interface_types::reserved_handles::Hierarchy, structures::Auth};

#[test]
fn test_create() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::try_from(random_digest.as_bytes().to_vec()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let prim_key_handle = context
.create_primary(
Expand Down Expand Up @@ -38,14 +38,14 @@ mod test_create {

mod test_load {
use crate::common::{create_ctx_with_session, decryption_key_pub, signing_key_pub};
use std::convert::TryFrom;
use tss_esapi::{interface_types::reserved_handles::Hierarchy, structures::Auth};

#[test]
fn test_load() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::try_from(random_digest.as_bytes().to_vec()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let prim_key_handle = context
.create_primary(
Expand Down Expand Up @@ -237,8 +237,9 @@ mod test_read_public {
#[test]
fn test_read_public() {
let mut context = create_ctx_with_session();
let random_digest = context.get_random(16).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_bytes()).unwrap();
let mut random_digest = vec![0u8; 16];
getrandom::getrandom(&mut random_digest).unwrap();
let key_auth = Auth::from_bytes(random_digest.as_slice()).unwrap();

let key_handle = context
.create_primary(
Expand Down
Loading
Loading