@@ -17,6 +17,7 @@ use parsec_interface::operations::{
17
17
use parsec_interface:: requests:: { Opcode , ProviderID , ResponseStatus , Result } ;
18
18
use std:: io:: ErrorKind ;
19
19
use std:: sync:: { Arc , Mutex , RwLock } ;
20
+ use tss_esapi:: utils:: algorithm_specifiers:: Cipher ;
20
21
use tss_esapi:: Tcti ;
21
22
use uuid:: Uuid ;
22
23
@@ -216,6 +217,41 @@ impl TpmProviderBuilder {
216
217
}
217
218
}
218
219
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
+
219
255
/// Create an instance of TpmProvider
220
256
///
221
257
/// # Safety
@@ -224,26 +260,24 @@ impl TpmProviderBuilder {
224
260
/// using a same TCTI that does not handle multiple applications concurrently.
225
261
pub unsafe fn build ( mut self ) -> std:: io:: Result < TpmProvider > {
226
262
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" ) ) ?;
227
267
TpmProvider :: new (
228
268
self . key_info_store . ok_or_else ( || {
229
269
std:: io:: Error :: new ( ErrorKind :: InvalidData , "missing key info store" )
230
270
} ) ?,
231
271
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)
237
273
. with_root_key_size ( ROOT_KEY_SIZE )
238
274
. with_root_key_auth_size ( ROOT_KEY_AUTH_SIZE )
239
275
. with_hierarchy_auth ( hierarchy_auth)
240
276
. with_hierarchy ( tss_esapi:: utils:: Hierarchy :: Owner )
241
277
. with_session_hash_alg (
242
278
tss_esapi:: utils:: algorithm_specifiers:: HashingAlgorithm :: Sha256 . into ( ) ,
243
279
)
244
- . with_default_context_cipher (
245
- tss_esapi:: utils:: algorithm_specifiers:: Cipher :: aes_256_cfb ( ) ,
246
- )
280
+ . with_default_context_cipher ( default_cipher)
247
281
. build ( )
248
282
. or_else ( |e| {
249
283
error ! ( "Error creating TSS Transient Object Context ({})." , e) ;
0 commit comments