@@ -27,14 +27,13 @@ use parsec_interface::operations::{OpExportPublicKey, ResultExportPublicKey};
27
27
use parsec_interface:: operations:: { OpImportKey , ResultImportKey } ;
28
28
use parsec_interface:: operations:: { OpListOpcodes , ResultListOpcodes } ;
29
29
use parsec_interface:: requests:: { Opcode , ProviderID , ResponseStatus , Result } ;
30
- use psa_crypto_binding:: psa_key_handle_t as KeyHandle ;
31
- use psa_crypto_binding:: psa_key_id_t as KeyId ;
30
+ use psa_crypto_binding:: psa_key_id_t;
32
31
use std:: collections:: HashSet ;
33
32
use std:: convert:: TryInto ;
34
33
use std:: io:: { Error , ErrorKind } ;
35
34
use std:: sync:: { Arc , Mutex , RwLock } ;
36
35
use std_semaphore:: Semaphore ;
37
- use utils:: Key ;
36
+ use utils:: KeyHandle ;
38
37
use uuid:: Uuid ;
39
38
40
39
#[ allow(
@@ -53,7 +52,7 @@ mod psa_crypto_binding {
53
52
mod constants;
54
53
mod utils;
55
54
56
- type LocalIdStore = HashSet < KeyId > ;
55
+ type LocalIdStore = HashSet < psa_key_id_t > ;
57
56
58
57
const SUPPORTED_OPCODES : [ Opcode ; 7 ] = [
59
58
Opcode :: CreateKey ,
@@ -91,7 +90,7 @@ pub struct MbedProvider {
91
90
/// Gets a PSA Key ID from the Key ID Manager.
92
91
/// Wrapper around the get method of the Key ID Manager to convert the key ID to the psa_key_id_t
93
92
/// type.
94
- fn get_key_id ( key_triple : & KeyTriple , store_handle : & dyn ManageKeyIDs ) -> Result < KeyId > {
93
+ fn get_key_id ( key_triple : & KeyTriple , store_handle : & dyn ManageKeyIDs ) -> Result < psa_key_id_t > {
95
94
match store_handle. get ( key_triple) {
96
95
Ok ( Some ( key_id) ) => {
97
96
if let Ok ( key_id_bytes) = key_id. try_into ( ) {
@@ -114,13 +113,13 @@ fn create_key_id(
114
113
key_triple : KeyTriple ,
115
114
store_handle : & mut dyn ManageKeyIDs ,
116
115
local_ids_handle : & mut LocalIdStore ,
117
- ) -> Result < KeyId > {
118
- let mut key_id = rand:: random :: < KeyId > ( ) ;
116
+ ) -> Result < psa_key_id_t > {
117
+ let mut key_id = rand:: random :: < psa_key_id_t > ( ) ;
119
118
while local_ids_handle. contains ( & key_id)
120
119
|| key_id == 0
121
120
|| key_id > constants:: PSA_MAX_PERSISTENT_KEY_IDENTIFIER
122
121
{
123
- key_id = rand:: random :: < KeyId > ( ) ;
122
+ key_id = rand:: random :: < psa_key_id_t > ( ) ;
124
123
}
125
124
match store_handle. insert ( key_triple. clone ( ) , key_id. to_ne_bytes ( ) . to_vec ( ) ) {
126
125
Ok ( insert_option) => {
@@ -140,7 +139,7 @@ fn create_key_id(
140
139
141
140
fn remove_key_id (
142
141
key_triple : & KeyTriple ,
143
- key_id : KeyId ,
142
+ key_id : psa_key_id_t ,
144
143
store_handle : & mut dyn ManageKeyIDs ,
145
144
local_ids_handle : & mut LocalIdStore ,
146
145
) -> Result < ( ) > {
@@ -172,6 +171,8 @@ impl MbedProvider {
172
171
/// if there, delete them. Adds Key IDs currently in use in the local IDs store.
173
172
/// Returns `None` if the initialisation failed.
174
173
fn new ( key_id_store : Arc < RwLock < dyn ManageKeyIDs + Send + Sync > > ) -> Option < MbedProvider > {
174
+ // Safety: this function should be called before any of the other Mbed Crypto functions
175
+ // are.
175
176
if unsafe { psa_crypto_binding:: psa_crypto_init ( ) } != PSA_SUCCESS {
176
177
error ! ( "Error when initialising Mbed Crypto" ) ;
177
178
return None ;
@@ -208,23 +209,22 @@ impl MbedProvider {
208
209
continue ;
209
210
}
210
211
} ;
211
- let mut key_handle: KeyHandle = Default :: default ( ) ;
212
- let open_key_status =
213
- unsafe { psa_crypto_binding:: psa_open_key ( key_id, & mut key_handle) } ;
214
- if open_key_status == constants:: PSA_ERROR_DOES_NOT_EXIST {
215
- to_remove. push ( key_triple. clone ( ) ) ;
216
- } else if open_key_status != PSA_SUCCESS {
217
- error ! (
218
- "Error {} when opening a persistent Mbed Crypto key." ,
219
- open_key_status
220
- ) ;
221
- return None ;
222
- } else {
223
- let _ = local_ids_handle. insert ( key_id) ;
224
- unsafe {
225
- let _ = psa_crypto_binding:: psa_close_key ( key_handle) ;
212
+
213
+ // Safety: safe because:
214
+ // * the Mbed Crypto library has been initialized
215
+ // * this code is executed only by the main thread
216
+ match unsafe { KeyHandle :: open ( key_id) } {
217
+ Ok ( _) => {
218
+ let _ = local_ids_handle. insert ( key_id) ;
219
+ }
220
+ Err ( ResponseStatus :: PsaErrorDoesNotExist ) => {
221
+ to_remove. push ( key_triple. clone ( ) )
222
+ }
223
+ Err ( e) => {
224
+ error ! ( "Error {} when opening a persistent Mbed Crypto key." , e) ;
225
+ return None ;
226
226
}
227
- }
227
+ } ;
228
228
}
229
229
}
230
230
Err ( string) => {
@@ -282,28 +282,30 @@ impl Provide for MbedProvider {
282
282
) ?;
283
283
284
284
let key_attrs = utils:: convert_key_attributes ( & key_attributes, key_id) ?;
285
- let mut key = Key :: new ( & self . key_handle_mutex ) ;
286
-
287
- let generate_key_status = unsafe {
288
- let _guard = self
289
- . key_handle_mutex
290
- . lock ( )
291
- . expect ( "Grabbing key handle mutex failed" ) ;
292
- psa_crypto_binding:: psa_generate_key ( & key_attrs, key. as_mut ( ) )
293
- } ;
294
285
295
- if generate_key_status != PSA_SUCCESS {
286
+ let _guard = self
287
+ . key_handle_mutex
288
+ . lock ( )
289
+ . expect ( "Grabbing key handle mutex failed" ) ;
290
+
291
+ // Safety:
292
+ // * at this point the provider has been instantiated so Mbed Crypto has been initialized
293
+ // * self.key_handle_mutex prevents concurrent accesses
294
+ // * self.key_slot_semaphore prevents overflowing key slots
295
+ let mut key_handle = unsafe { KeyHandle :: generate ( & key_attrs) } . or_else ( |e| {
296
296
remove_key_id (
297
297
& key_triple,
298
298
key_id,
299
299
& mut * store_handle,
300
300
& mut local_ids_handle,
301
301
) ?;
302
- error ! ( "Generate key status: {}" , generate_key_status) ;
303
- return Err ( utils:: convert_status ( generate_key_status) . ok_or_else ( || {
304
- error ! ( "Failed to convert error status." ) ;
305
- ResponseStatus :: PsaErrorGenericError
306
- } ) ?) ;
302
+ error ! ( "Generate key status: {}" , e) ;
303
+ Err ( e)
304
+ } ) ?;
305
+
306
+ // Safety: same conditions than above.
307
+ unsafe {
308
+ key_handle. close ( ) ?;
307
309
}
308
310
309
311
Ok ( ResultCreateKey { } )
@@ -328,33 +330,30 @@ impl Provide for MbedProvider {
328
330
) ?;
329
331
330
332
let key_attrs = utils:: convert_key_attributes ( & key_attributes, key_id) ?;
331
- let mut key = Key :: new ( & self . key_handle_mutex ) ;
332
-
333
- let import_key_status = unsafe {
334
- let _guard = self
335
- . key_handle_mutex
336
- . lock ( )
337
- . expect ( "Grabbing key handle mutex failed" ) ;
338
- psa_crypto_binding:: psa_import_key (
339
- & key_attrs,
340
- key_data. as_ptr ( ) ,
341
- key_data. len ( ) ,
342
- key. as_mut ( ) ,
343
- )
344
- } ;
345
333
346
- if import_key_status != PSA_SUCCESS {
334
+ let _guard = self
335
+ . key_handle_mutex
336
+ . lock ( )
337
+ . expect ( "Grabbing key handle mutex failed" ) ;
338
+
339
+ // Safety:
340
+ // * at this point the provider has been instantiated so Mbed Crypto has been initialized
341
+ // * self.key_handle_mutex prevents concurrent accesses
342
+ // * self.key_slot_semaphore prevents overflowing key slots
343
+ let mut key_handle = unsafe { KeyHandle :: import ( & key_attrs, key_data) } . or_else ( |e| {
347
344
remove_key_id (
348
345
& key_triple,
349
346
key_id,
350
347
& mut * store_handle,
351
348
& mut local_ids_handle,
352
349
) ?;
353
- error ! ( "Import key status: {}" , import_key_status) ;
354
- return Err ( utils:: convert_status ( import_key_status) . ok_or_else ( || {
355
- error ! ( "Failed to convert error status." ) ;
356
- ResponseStatus :: PsaErrorGenericError
357
- } ) ?) ;
350
+ error ! ( "Import key status: {}" , e) ;
351
+ Err ( e)
352
+ } ) ?;
353
+
354
+ // Safety: same conditions than above.
355
+ unsafe {
356
+ key_handle. close ( ) ?;
358
357
}
359
358
360
359
Ok ( ResultImportKey { } )
@@ -371,24 +370,43 @@ impl Provide for MbedProvider {
371
370
let key_triple = KeyTriple :: new ( app_name, ProviderID :: MbedProvider , key_name) ;
372
371
let store_handle = self . key_id_store . read ( ) . expect ( "Key store lock poisoned" ) ;
373
372
let key_id = get_key_id ( & key_triple, & * store_handle) ?;
374
- let key = Key :: open_key ( key_id, & self . key_handle_mutex ) ?;
375
373
376
- let key_attrs = key. get_attributes ( ) ?;
377
- let buffer_size = utils:: psa_export_public_key_size ( & key_attrs) ?;
374
+ let _guard = self
375
+ . key_handle_mutex
376
+ . lock ( )
377
+ . expect ( "Grabbing key handle mutex failed" ) ;
378
+
379
+ let mut key_handle;
380
+ let mut key_attrs;
381
+ // Safety:
382
+ // * at this point the provider has been instantiated so Mbed Crypto has been initialized
383
+ // * self.key_handle_mutex prevents concurrent accesses
384
+ // * self.key_slot_semaphore prevents overflowing key slots
385
+ unsafe {
386
+ key_handle = KeyHandle :: open ( key_id) ?;
387
+ key_attrs = key_handle. attributes ( ) ?;
388
+ }
389
+
390
+ let buffer_size = utils:: psa_export_public_key_size ( key_attrs. as_ref ( ) ) ?;
378
391
let mut buffer = vec ! [ 0u8 ; buffer_size] ;
379
392
let mut actual_size = 0 ;
380
393
381
- let export_status = unsafe {
382
- psa_crypto_binding:: psa_export_public_key (
383
- key. raw_handle ( ) ,
394
+ let export_status;
395
+ // Safety: same conditions than above.
396
+ unsafe {
397
+ export_status = psa_crypto_binding:: psa_export_public_key (
398
+ key_handle. raw ( ) ,
384
399
buffer. as_mut_ptr ( ) ,
385
400
buffer_size,
386
401
& mut actual_size,
387
- )
402
+ ) ;
403
+ key_attrs. reset ( ) ;
404
+ key_handle. close ( ) ?;
388
405
} ;
389
406
390
407
if export_status != PSA_SUCCESS {
391
408
error ! ( "Export status: {}" , export_status) ;
409
+ // Safety: same conditions than above.
392
410
return Err ( utils:: convert_status ( export_status) . ok_or_else ( || {
393
411
error ! ( "Failed to convert error status." ) ;
394
412
ResponseStatus :: PsaErrorGenericError
@@ -407,9 +425,23 @@ impl Provide for MbedProvider {
407
425
let mut store_handle = self . key_id_store . write ( ) . expect ( "Key store lock poisoned" ) ;
408
426
let mut local_ids_handle = self . local_ids . write ( ) . expect ( "Local ID lock poisoned" ) ;
409
427
let key_id = get_key_id ( & key_triple, & * store_handle) ?;
410
- let key = Key :: open_key ( key_id, & self . key_handle_mutex ) ?;
411
428
412
- let destroy_key_status = unsafe { psa_crypto_binding:: psa_destroy_key ( key. raw_handle ( ) ) } ;
429
+ let _guard = self
430
+ . key_handle_mutex
431
+ . lock ( )
432
+ . expect ( "Grabbing key handle mutex failed" ) ;
433
+
434
+ let key_handle;
435
+ let destroy_key_status;
436
+
437
+ // Safety:
438
+ // * at this point the provider has been instantiated so Mbed Crypto has been initialized
439
+ // * self.key_handle_mutex prevents concurrent accesses
440
+ // * self.key_slot_semaphore prevents overflowing key slots
441
+ unsafe {
442
+ key_handle = KeyHandle :: open ( key_id) ?;
443
+ destroy_key_status = psa_crypto_binding:: psa_destroy_key ( key_handle. raw ( ) ) ;
444
+ }
413
445
414
446
if destroy_key_status == PSA_SUCCESS {
415
447
remove_key_id (
@@ -436,23 +468,41 @@ impl Provide for MbedProvider {
436
468
let key_triple = KeyTriple :: new ( app_name, ProviderID :: MbedProvider , key_name) ;
437
469
let store_handle = self . key_id_store . read ( ) . expect ( "Key store lock poisoned" ) ;
438
470
let key_id = get_key_id ( & key_triple, & * store_handle) ?;
439
- let key = Key :: open_key ( key_id, & self . key_handle_mutex ) ?;
440
- let key_attrs = key. get_attributes ( ) ?;
441
471
442
- let buffer_size = utils:: psa_asymmetric_sign_output_size ( & key_attrs) ?;
472
+ let _guard = self
473
+ . key_handle_mutex
474
+ . lock ( )
475
+ . expect ( "Grabbing key handle mutex failed" ) ;
476
+
477
+ let mut key_handle;
478
+ let mut key_attrs;
479
+ // Safety:
480
+ // * at this point the provider has been instantiated so Mbed Crypto has been initialized
481
+ // * self.key_handle_mutex prevents concurrent accesses
482
+ // * self.key_slot_semaphore prevents overflowing key slots
483
+ unsafe {
484
+ key_handle = KeyHandle :: open ( key_id) ?;
485
+ key_attrs = key_handle. attributes ( ) ?;
486
+ }
487
+
488
+ let buffer_size = utils:: psa_asymmetric_sign_output_size ( key_attrs. as_ref ( ) ) ?;
443
489
let mut signature = vec ! [ 0u8 ; buffer_size] ;
444
490
let mut signature_size: usize = 0 ;
445
491
446
- let sign_status = unsafe {
447
- psa_crypto_binding:: psa_asymmetric_sign (
448
- key. raw_handle ( ) ,
449
- key_attrs. core . policy . alg ,
492
+ let sign_status;
493
+ // Safety: same conditions than above.
494
+ unsafe {
495
+ sign_status = psa_crypto_binding:: psa_asymmetric_sign (
496
+ key_handle. raw ( ) ,
497
+ key_attrs. raw ( ) . core . policy . alg ,
450
498
hash. as_ptr ( ) ,
451
499
hash. len ( ) ,
452
500
signature. as_mut_ptr ( ) ,
453
501
buffer_size,
454
502
& mut signature_size,
455
- )
503
+ ) ;
504
+ key_attrs. reset ( ) ;
505
+ key_handle. close ( ) ?;
456
506
} ;
457
507
458
508
if sign_status == PSA_SUCCESS {
@@ -481,19 +531,33 @@ impl Provide for MbedProvider {
481
531
let key_triple = KeyTriple :: new ( app_name, ProviderID :: MbedProvider , key_name) ;
482
532
let store_handle = self . key_id_store . read ( ) . expect ( "Key store lock poisoned" ) ;
483
533
let key_id = get_key_id ( & key_triple, & * store_handle) ?;
484
- let key = Key :: open_key ( key_id, & self . key_handle_mutex ) ?;
485
- let key_attrs = key. get_attributes ( ) ?;
486
534
487
- let verify_status = unsafe {
488
- psa_crypto_binding:: psa_asymmetric_verify (
489
- key. raw_handle ( ) ,
490
- key_attrs. core . policy . alg ,
535
+ let _guard = self
536
+ . key_handle_mutex
537
+ . lock ( )
538
+ . expect ( "Grabbing key handle mutex failed" ) ;
539
+
540
+ let mut key_handle;
541
+ let mut key_attrs;
542
+ let verify_status;
543
+ // Safety:
544
+ // * at this point the provider has been instantiated so Mbed Crypto has been initialized
545
+ // * self.key_handle_mutex prevents concurrent accesses
546
+ // * self.key_slot_semaphore prevents overflowing key slots
547
+ unsafe {
548
+ key_handle = KeyHandle :: open ( key_id) ?;
549
+ key_attrs = key_handle. attributes ( ) ?;
550
+ verify_status = psa_crypto_binding:: psa_asymmetric_verify (
551
+ key_handle. raw ( ) ,
552
+ key_attrs. raw ( ) . core . policy . alg ,
491
553
hash. as_ptr ( ) ,
492
554
hash. len ( ) ,
493
555
signature. as_ptr ( ) ,
494
556
signature. len ( ) ,
495
- )
496
- } ;
557
+ ) ;
558
+ key_attrs. reset ( ) ;
559
+ key_handle. close ( ) ?;
560
+ }
497
561
498
562
if verify_status == PSA_SUCCESS {
499
563
Ok ( ResultAsymVerify { } )
@@ -508,6 +572,7 @@ impl Provide for MbedProvider {
508
572
509
573
impl Drop for MbedProvider {
510
574
fn drop ( & mut self ) {
575
+ // Safety: the Provider was initialized with psa_crypto_init
511
576
unsafe {
512
577
psa_crypto_binding:: mbedtls_psa_crypto_free ( ) ;
513
578
}
0 commit comments