Skip to content

Commit 744e57b

Browse files
committed
Add default context cipher selection for TPM provider
This commit allows the TPM provider to identify the most appropriate cipher that is supported by the underlying TPM, using it for session encryption and as the main algorithm for the primary storage key. Signed-off-by: Ionut Mihalcea <ionut.mihalcea@arm.com>
1 parent 4f48d1d commit 744e57b

File tree

1 file changed

+42
-8
lines changed
  • src/providers/tpm_provider

1 file changed

+42
-8
lines changed

src/providers/tpm_provider/mod.rs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use parsec_interface::operations::{
1717
use parsec_interface::requests::{Opcode, ProviderID, ResponseStatus, Result};
1818
use std::io::ErrorKind;
1919
use std::sync::{Arc, Mutex, RwLock};
20+
use tss_esapi::utils::algorithm_specifiers::Cipher;
2021
use tss_esapi::Tcti;
2122
use uuid::Uuid;
2223

@@ -216,6 +217,41 @@ impl TpmProviderBuilder {
216217
}
217218
}
218219

220+
/// Identify the best cipher for our needs supported by the TPM.
221+
///
222+
/// The algorithms sought are the following, in the given order:
223+
/// * AES-256 in CFB mode
224+
/// * AES-128 in CFB mode
225+
///
226+
/// The method is unsafe because it relies on creating a TSS Context which could cause
227+
/// undefined behaviour if multiple such contexts are opened concurrently.
228+
unsafe fn find_default_context_cipher(&self) -> std::io::Result<Cipher> {
229+
let ciphers = [Cipher::aes_256_cfb(), Cipher::aes_128_cfb()];
230+
let mut ctx = tss_esapi::Context::new(
231+
self.tcti
232+
.ok_or_else(|| std::io::Error::new(ErrorKind::InvalidData, "missing TCTI"))?,
233+
)
234+
.or_else(|e| {
235+
error!("Error when creating TSS Context ({})", e);
236+
Err(std::io::Error::new(
237+
ErrorKind::InvalidData,
238+
"failed initializing TSS context",
239+
))
240+
})?;
241+
for cipher in ciphers.iter() {
242+
if ctx
243+
.test_parms(tss_esapi::utils::PublicParmsUnion::SymDetail(*cipher))
244+
.is_ok()
245+
{
246+
return Ok(*cipher);
247+
}
248+
}
249+
Err(std::io::Error::new(
250+
ErrorKind::Other,
251+
"desired ciphers not supported by TPM",
252+
))
253+
}
254+
219255
/// Create an instance of TpmProvider
220256
///
221257
/// # Safety
@@ -224,26 +260,24 @@ impl TpmProviderBuilder {
224260
/// using a same TCTI that does not handle multiple applications concurrently.
225261
pub unsafe fn build(mut self) -> std::io::Result<TpmProvider> {
226262
let hierarchy_auth = self.get_hierarchy_auth()?;
263+
let default_cipher = self.find_default_context_cipher()?;
264+
let tcti = self
265+
.tcti
266+
.ok_or_else(|| std::io::Error::new(ErrorKind::InvalidData, "missing TCTI"))?;
227267
TpmProvider::new(
228268
self.key_info_store.ok_or_else(|| {
229269
std::io::Error::new(ErrorKind::InvalidData, "missing key info store")
230270
})?,
231271
tss_esapi::abstraction::transient::TransientKeyContextBuilder::new()
232-
.with_tcti(
233-
self.tcti.ok_or_else(|| {
234-
std::io::Error::new(ErrorKind::InvalidData, "missing TCTI")
235-
})?,
236-
)
272+
.with_tcti(tcti)
237273
.with_root_key_size(ROOT_KEY_SIZE)
238274
.with_root_key_auth_size(ROOT_KEY_AUTH_SIZE)
239275
.with_hierarchy_auth(hierarchy_auth)
240276
.with_hierarchy(tss_esapi::utils::Hierarchy::Owner)
241277
.with_session_hash_alg(
242278
tss_esapi::utils::algorithm_specifiers::HashingAlgorithm::Sha256.into(),
243279
)
244-
.with_default_context_cipher(
245-
tss_esapi::utils::algorithm_specifiers::Cipher::aes_256_cfb(),
246-
)
280+
.with_default_context_cipher(default_cipher)
247281
.build()
248282
.or_else(|e| {
249283
error!("Error creating TSS Transient Object Context ({}).", e);

0 commit comments

Comments
 (0)