Skip to content

Commit b9efab3

Browse files
src: Get random authvalues locally instead of from the TPM
Currently, the TPM itself is the root of trust for randomness in authvalues used for creating Primary Keys. This is susceptible to physical attacks over the TPM bus. * Get authvalues via the 'getrandom' crate getrandom retrieves random data from the (operating) system sources and assumes "that the system always provides high-quality cryptographically secure random data, ideally backed by hardware entropy sources", so the administrator of the platfrom should take this into account. Note: This change may slow down the tests as accessing random values from the OS instead of the TPM may be slower. Signed-off-by: Tomás González <[email protected]>
1 parent 40a28ca commit b9efab3

13 files changed

+108
-87
lines changed

tss-esapi/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ tss-esapi-sys = { path = "../tss-esapi-sys", version = "0.5.0" }
2727
oid = "0.2.1"
2828
picky-asn1 = "0.8.0"
2929
picky-asn1-x509 = "0.12.0"
30+
getrandom = "0.2.11"
3031

3132
[dev-dependencies]
3233
env_logger = "0.10.0"

tss-esapi/src/abstraction/transient/mod.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ impl TransientKeyContext {
137137
///
138138
/// # Errors
139139
/// * if the authentication size is larger than 32 a `WrongParamSize` wrapper error is returned
140+
/// * if there is an error when obtaining random numbers from the local machine
140141
pub fn create_key(
141142
&mut self,
142143
key_params: KeyParams,
@@ -147,8 +148,12 @@ impl TransientKeyContext {
147148
}
148149
let key_auth = if auth_size > 0 {
149150
self.set_session_attrs()?;
150-
let random_bytes = self.context.get_random(auth_size)?;
151-
Some(Auth::try_from(random_bytes.value().to_vec())?)
151+
let mut random_bytes = vec![0u8; auth_size];
152+
getrandom::getrandom(&mut random_bytes).map_err(|_| {
153+
log::error!("Failed to obtain a random authvalue for key creation");
154+
Error::WrapperError(ErrorKind::InternalError)
155+
})?;
156+
Some(Auth::try_from(random_bytes)?)
152157
} else {
153158
None
154159
};
@@ -637,7 +642,7 @@ impl TransientKeyContextBuilder {
637642
/// Bootstrap the TransientKeyContext.
638643
///
639644
/// The root key is created as a primary key in the provided hierarchy and thus authentication is
640-
/// needed for said hierarchy. The authentication valuei for the key is generated by the TPM itself,
645+
/// needed for said hierarchy. The authentication value for the key is generated locally in the machine,
641646
/// with a configurable length, and never exposed outside the context.
642647
///
643648
/// # Warning
@@ -650,9 +655,9 @@ impl TransientKeyContextBuilder {
650655
/// * `root_key_auth_size` must be at most 32
651656
///
652657
/// # Errors
653-
/// * errors are returned if any method calls return an error: `Context::get_random`,
654-
/// `Context::start_auth_session`, `Context::create_primary`, `Context::flush_context`,
655-
/// `Context::set_handle_auth`
658+
/// * errors are returned if any method calls return an error: `Context::start_auth_session`
659+
/// `Context::create_primary`, `Context::flush_context`, `Context::set_handle_auth`
660+
/// or if an internal error occurs when getting random numbers from the local machine
656661
/// * if the root key authentication size is given greater than 32 or if the root key size is
657662
/// not 1024, 2048, 3072 or 4096, a `InvalidParam` wrapper error is returned
658663
pub fn build(mut self) -> Result<TransientKeyContext> {
@@ -665,8 +670,12 @@ impl TransientKeyContextBuilder {
665670
let mut context = Context::new(self.tcti_name_conf)?;
666671

667672
let root_key_auth = if self.root_key_auth_size > 0 {
668-
let random = context.get_random(self.root_key_auth_size)?;
669-
Some(Auth::try_from(random.value().to_vec())?)
673+
let mut random = vec![0u8; self.root_key_auth_size];
674+
getrandom::getrandom(&mut random).map_err(|_| {
675+
log::error!("Failed to obtain a random value for root key authentication");
676+
Error::WrapperError(ErrorKind::InternalError)
677+
})?;
678+
Some(Auth::try_from(random)?)
670679
} else {
671680
None
672681
};

tss-esapi/src/context/tpm_commands/asymmetric_primitives.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ impl Context {
131131
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
132132
/// # .expect("Failed to set attributes on session");
133133
/// # context.set_sessions((Some(session), None, None));
134-
/// # let random_digest = context.get_random(16).unwrap();
135-
/// # let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
134+
/// # let mut random_digest = vec![0u8; 16];
135+
/// # getrandom::getrandom(&mut random_digest).unwrap();
136+
/// # let key_auth = Auth::try_from(random_digest).unwrap();
136137
/// #
137138
/// // Create a key suitable for ECDH key generation
138139
/// let ecc_parms = PublicEccParametersBuilder::new()
@@ -268,8 +269,9 @@ impl Context {
268269
/// # context.tr_sess_set_attributes(session, session_attributes, session_attributes_mask)
269270
/// # .expect("Failed to set attributes on session");
270271
/// # context.set_sessions((Some(session), None, None));
271-
/// # let random_digest = context.get_random(16).unwrap();
272-
/// # let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
272+
/// # let mut random_digest = vec![0u8; 16];
273+
/// # getrandom::getrandom(&mut random_digest).unwrap();
274+
/// # let key_auth = Auth::try_from(random_digest).unwrap();
273275
/// #
274276
/// // Create a key suitable for ECDH key generation
275277
/// let ecc_parms = PublicEccParametersBuilder::new()

tss-esapi/src/context/tpm_commands/context_management.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,9 @@ impl Context {
109109
///
110110
/// // Execute context methods using the session
111111
/// context.execute_with_session(Some(session), |ctx| {
112-
/// let random_digest = ctx.get_random(16)
113-
/// .expect("Call to get_random failed");
114-
/// let key_auth = Auth::try_from(random_digest.value().to_vec())
115-
/// .expect("Failed to create Auth");
112+
/// let mut random_digest = vec![0u8; 16];
113+
/// getrandom::getrandom(&mut random_digest).expect("Call to getrandom failed");
114+
/// let key_auth = Auth::try_from(random_digest).expect("Failed to create Auth");
116115
/// let key_handle = ctx
117116
/// .create_primary(
118117
/// Hierarchy::Owner,

tss-esapi/src/context/tpm_commands/symmetric_primitives.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,10 @@ impl Context {
5656
/// # .tr_set_auth(tss_esapi::interface_types::resource_handles::Hierarchy::Owner.into(), Auth::default())
5757
/// # .expect("Failed to set auth to empty for owner");
5858
/// # // Create primary key auth
59+
/// # let mut random_digest = vec![0u8; 16];
60+
/// # getrandom::getrandom(&mut random_digest).expect("get_rand call failed");
5961
/// # let primary_key_auth = Auth::try_from(
60-
/// # context
61-
/// # .get_random(16)
62-
/// # .expect("get_rand call failed")
63-
/// # .value()
64-
/// # .to_vec(),
62+
/// # random_digest
6563
/// # )
6664
/// # .expect("Failed to create primary key auth");
6765
/// # // Create primary key
@@ -103,12 +101,10 @@ impl Context {
103101
/// # .build()
104102
/// # .expect("Failed to create public for symmetric key public");
105103
/// # // Create auth for the symmetric key
104+
/// # let mut random_digest = vec![0u8; 16];
105+
/// # getrandom::getrandom(&mut random_digest).expect("get_rand call failed");
106106
/// # let symmetric_key_auth = Auth::try_from(
107-
/// # context
108-
/// # .get_random(16)
109-
/// # .expect("get_rand call failed")
110-
/// # .value()
111-
/// # .to_vec(),
107+
/// # random_digest
112108
/// # )
113109
/// # .expect("Failed to create symmetric key auth");
114110
/// # // Create symmetric key data

tss-esapi/tests/integration_tests/abstraction_tests/transient_key_context_tests.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,9 @@ fn ctx_migration_test() {
503503
// Create two key contexts using `Context`, one for an RSA keypair,
504504
// one for just the public part of the key
505505
let mut basic_ctx = crate::common::create_ctx_with_session();
506-
let random_digest = basic_ctx.get_random(16).unwrap();
507-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
506+
let mut random_digest = vec![0u8; 16];
507+
getrandom::getrandom(&mut random_digest).unwrap();
508+
let key_auth = Auth::try_from(random_digest).unwrap();
508509
let prim_key_handle = basic_ctx
509510
.create_primary(
510511
Hierarchy::Owner,

tss-esapi/tests/integration_tests/context_tests/tpm_commands/asymmetric_primitives_tests.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ mod test_rsa_encrypt_decrypt {
1919
#[test]
2020
fn test_encrypt_decrypt() {
2121
let mut context = create_ctx_with_session();
22-
let random_digest = context.get_random(16).unwrap();
23-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
22+
let mut random_digest = vec![0u8; 16];
23+
getrandom::getrandom(&mut random_digest).unwrap();
24+
let key_auth = Auth::try_from(random_digest).unwrap();
2425

2526
let key_handle = context
2627
.create_primary(
@@ -59,8 +60,9 @@ mod test_rsa_encrypt_decrypt {
5960
#[test]
6061
fn test_ecdh() {
6162
let mut context = create_ctx_with_session();
62-
let random_digest = context.get_random(16).unwrap();
63-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
63+
let mut random_digest = vec![0u8; 16];
64+
getrandom::getrandom(&mut random_digest).unwrap();
65+
let key_auth = Auth::try_from(random_digest).unwrap();
6466

6567
let ecc_parms = PublicEccParametersBuilder::new()
6668
.with_ecc_scheme(EccScheme::EcDh(HashScheme::new(HashingAlgorithm::Sha256)))

tss-esapi/tests/integration_tests/context_tests/tpm_commands/context_management_tests.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ mod test_ctx_save {
88
#[test]
99
fn test_ctx_save() {
1010
let mut context = create_ctx_with_session();
11-
let random_digest = context.get_random(16).unwrap();
12-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
11+
let mut random_digest = vec![0u8; 16];
12+
getrandom::getrandom(&mut random_digest).unwrap();
13+
let key_auth = Auth::try_from(random_digest).unwrap();
1314

1415
let key_handle = context
1516
.create_primary(
@@ -28,8 +29,9 @@ mod test_ctx_save {
2829
#[test]
2930
fn test_ctx_save_leaf() {
3031
let mut context = create_ctx_with_session();
31-
let random_digest = context.get_random(16).unwrap();
32-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
32+
let mut random_digest = vec![0u8; 16];
33+
getrandom::getrandom(&mut random_digest).unwrap();
34+
let key_auth = Auth::try_from(random_digest).unwrap();
3335

3436
let prim_key_handle = context
3537
.create_primary(
@@ -72,13 +74,14 @@ mod test_ctx_load {
7274
#[test]
7375
fn test_ctx_load() {
7476
let mut context = create_ctx_with_session();
75-
let key_auth = context.get_random(16).unwrap();
77+
let mut random_digest = vec![0u8; 16];
78+
getrandom::getrandom(&mut random_digest).unwrap();
7679

7780
let prim_key_handle = context
7881
.create_primary(
7982
Hierarchy::Owner,
8083
decryption_key_pub(),
81-
Some(Auth::try_from(key_auth.value().to_vec()).unwrap()),
84+
Some(Auth::try_from(random_digest.clone()).unwrap()),
8285
None,
8386
None,
8487
None,
@@ -90,7 +93,7 @@ mod test_ctx_load {
9093
.create(
9194
prim_key_handle,
9295
signing_key_pub(),
93-
Some(Auth::try_from(key_auth.value().to_vec()).unwrap()),
96+
Some(Auth::try_from(random_digest).unwrap()),
9497
None,
9598
None,
9699
None,
@@ -115,8 +118,9 @@ mod test_flush_context {
115118
#[test]
116119
fn test_flush_ctx() {
117120
let mut context = create_ctx_with_session();
118-
let random_digest = context.get_random(16).unwrap();
119-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
121+
let mut random_digest = vec![0u8; 16];
122+
getrandom::getrandom(&mut random_digest).unwrap();
123+
let key_auth = Auth::try_from(random_digest).unwrap();
120124

121125
let key_handle = context
122126
.create_primary(
@@ -136,8 +140,9 @@ mod test_flush_context {
136140
#[test]
137141
fn test_flush_parent_ctx() {
138142
let mut context = create_ctx_with_session();
139-
let random_digest = context.get_random(16).unwrap();
140-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
143+
let mut random_digest = vec![0u8; 16];
144+
getrandom::getrandom(&mut random_digest).unwrap();
145+
let key_auth = Auth::try_from(random_digest).unwrap();
141146

142147
let prim_key_handle = context
143148
.create_primary(

tss-esapi/tests/integration_tests/context_tests/tpm_commands/enhanced_authorization_ea_commands_tests.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,9 @@ mod test_policy_authorize {
537537
#[test]
538538
fn test_policy_authorize() {
539539
let mut context = create_ctx_with_session();
540-
let random_digest = context.get_random(16).unwrap();
541-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
540+
let mut random_digest = vec![0u8; 16];
541+
getrandom::getrandom(&mut random_digest).unwrap();
542+
let key_auth = Auth::try_from(random_digest).unwrap();
542543

543544
let key_handle = context
544545
.create_primary(

tss-esapi/tests/integration_tests/context_tests/tpm_commands/hierarchy_commands_tests.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ mod test_create_primary {
1010
#[test]
1111
fn test_create_primary() {
1212
let mut context = create_ctx_with_session();
13-
let random_digest = context.get_random(16).unwrap();
14-
let key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
13+
let mut random_digest = vec![0u8; 16];
14+
getrandom::getrandom(&mut random_digest).unwrap();
15+
let key_auth = Auth::try_from(random_digest).unwrap();
1516

1617
let key_handle = context
1718
.create_primary(
@@ -95,8 +96,9 @@ mod test_change_auth {
9596
)
9697
.unwrap();
9798

98-
let random_digest = context.get_random(16).unwrap();
99-
let new_key_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
99+
let mut random_digest = vec![0u8; 16];
100+
getrandom::getrandom(&mut random_digest).unwrap();
101+
let new_key_auth = Auth::try_from(random_digest).unwrap();
100102

101103
let new_private = context
102104
.object_change_auth(loaded_key.into(), prim_key_handle.into(), new_key_auth)
@@ -110,8 +112,9 @@ mod test_change_auth {
110112
fn test_hierarchy_change_auth() {
111113
let mut context = create_ctx_with_session();
112114

113-
let random_digest = context.get_random(16).unwrap();
114-
let new_auth = Auth::try_from(random_digest.value().to_vec()).unwrap();
115+
let mut random_digest = vec![0u8; 16];
116+
getrandom::getrandom(&mut random_digest).unwrap();
117+
let new_auth = Auth::try_from(random_digest).unwrap();
115118

116119
// NOTE: If this test failed on your system, you are probably running it against a
117120
// real (hardware) TPM or one that is provisioned. This hierarchy is supposed to be

0 commit comments

Comments
 (0)