Skip to content

Commit

Permalink
Merge pull request #510 from parallaxsecond/tg/random-fix-main
Browse files Browse the repository at this point in the history
Get random authvalues locally instead of from the TPM
  • Loading branch information
gowthamsk-arm authored Mar 14, 2024
2 parents 7899a72 + e8220a0 commit 5a0f772
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 91 deletions.
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 @@ -636,7 +641,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 @@ -649,9 +654,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 @@ -664,8 +669,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

0 comments on commit 5a0f772

Please sign in to comment.