1
1
// ---------------------------------- Includes ---------------------------------
2
+ #include <stdint.h>
3
+ #include <string.h>
2
4
#include "spm_panic.h"
3
5
#include "spm_server.h"
4
6
#include "spm/psa_defs.h"
16
18
#define mbedtls_calloc calloc
17
19
#define mbedtls_free free
18
20
#endif
19
- // ------------------------- Globals ---------------------------
21
+
22
+ // -------------------------------- Structures ---------------------------------
23
+ typedef struct psa_spm_hash_clone_s {
24
+ int32_t partition_id ;
25
+ void * source_operation ;
26
+ uint8_t ref_count ;
27
+ } psa_spm_hash_clone_t ;
28
+
29
+ // ---------------------------------- Globals ----------------------------------
20
30
static int psa_spm_init_refence_counter = 0 ;
21
31
32
+ #ifndef MAX_CONCURRENT_HASH_CLONES
33
+ #define MAX_CONCURRENT_HASH_CLONES 2
34
+ #endif
35
+ static psa_spm_hash_clone_t psa_spm_hash_clones [MAX_CONCURRENT_HASH_CLONES ];
36
+
37
+ // ------------------------- Internal Helper Functions -------------------------
38
+ static inline psa_status_t reserve_hash_clone (int32_t partition_id , void * source_operation , size_t * index )
39
+ {
40
+ for (* index = 0 ; * index < MAX_CONCURRENT_HASH_CLONES ; (* index )++ ) {
41
+ if (psa_spm_hash_clones [* index ].partition_id == partition_id &&
42
+ psa_spm_hash_clones [* index ].source_operation == source_operation ) {
43
+ psa_spm_hash_clones [* index ].ref_count ++ ;
44
+ return PSA_SUCCESS ;
45
+ }
46
+ }
47
+
48
+ for (* index = 0 ; * index < MAX_CONCURRENT_HASH_CLONES ; (* index )++ ) {
49
+ if (psa_spm_hash_clones [* index ].partition_id == 0 &&
50
+ psa_spm_hash_clones [* index ].source_operation == NULL ) {
51
+ psa_spm_hash_clones [* index ].partition_id = partition_id ;
52
+ psa_spm_hash_clones [* index ].source_operation = source_operation ;
53
+ psa_spm_hash_clones [* index ].ref_count ++ ;
54
+ return PSA_SUCCESS ;
55
+ }
56
+ }
57
+
58
+ return PSA_ERROR_BAD_STATE ;
59
+ }
60
+
61
+ static inline void release_hash_clone (psa_spm_hash_clone_t * hash_clone )
62
+ {
63
+ hash_clone -> ref_count -- ;
64
+ if (hash_clone -> ref_count == 0 ) {
65
+ hash_clone -> partition_id = 0 ;
66
+ hash_clone -> source_operation = NULL ;
67
+ }
68
+ }
69
+
70
+ static void destroy_hash_clone (void * source_operation )
71
+ {
72
+ for (size_t i = 0 ; i < MAX_CONCURRENT_HASH_CLONES ; i ++ ) {
73
+ if (psa_spm_hash_clones [i ].source_operation == source_operation ) {
74
+ psa_spm_hash_clones [i ].partition_id = 0 ;
75
+ psa_spm_hash_clones [i ].source_operation = NULL ;
76
+ psa_spm_hash_clones [i ].ref_count = 0 ;
77
+ break ;
78
+ }
79
+ }
80
+ }
81
+
82
+ static inline psa_status_t get_hash_clone (size_t index , int32_t partition_id ,
83
+ psa_spm_hash_clone_t * * hash_clone )
84
+ {
85
+ if (index >= MAX_CONCURRENT_HASH_CLONES ||
86
+ psa_spm_hash_clones [index ].partition_id != partition_id ||
87
+ psa_spm_hash_clones [index ].source_operation == NULL ) {
88
+ return PSA_ERROR_BAD_STATE ;
89
+ }
90
+
91
+ * hash_clone = & psa_spm_hash_clones [index ];
92
+ return PSA_SUCCESS ;
93
+ }
94
+
22
95
// ------------------------- Partition's Main Thread ---------------------------
23
96
static void psa_crypto_init_operation (void )
24
97
{
@@ -36,6 +109,9 @@ static void psa_crypto_init_operation(void)
36
109
status = psa_crypto_init ();
37
110
if (status == PSA_SUCCESS ) {
38
111
++ psa_spm_init_refence_counter ;
112
+ if (psa_spm_init_refence_counter == 1 ) {
113
+ memset (psa_spm_hash_clones , 0 , sizeof (psa_spm_hash_clones ));
114
+ }
39
115
}
40
116
41
117
break ;
@@ -71,6 +147,7 @@ static void psa_crypto_free_operation(void)
71
147
}
72
148
73
149
if (psa_spm_init_refence_counter == 0 ) {
150
+ memset (psa_spm_hash_clones , 0 , sizeof (psa_spm_hash_clones ));
74
151
mbedtls_psa_crypto_free ();
75
152
}
76
153
@@ -325,6 +402,7 @@ static void psa_hash_operation(void)
325
402
}
326
403
327
404
mbedtls_free (hash );
405
+ destroy_hash_clone (msg .rhandle );
328
406
break ;
329
407
}
330
408
@@ -350,11 +428,40 @@ static void psa_hash_operation(void)
350
428
351
429
status = psa_hash_verify (msg .rhandle , hash , hash_length );
352
430
mbedtls_free (hash );
431
+ destroy_hash_clone (msg .rhandle );
353
432
break ;
354
433
}
355
434
356
435
case PSA_HASH_ABORT : {
357
436
status = psa_hash_abort (msg .rhandle );
437
+ destroy_hash_clone (msg .rhandle );
438
+ break ;
439
+ }
440
+
441
+ case PSA_HASH_CLONE_BEGIN : {
442
+ size_t index = 0 ;
443
+
444
+ status = reserve_hash_clone (psa_identity (msg .handle ), msg .rhandle , & index );
445
+ if (status == PSA_SUCCESS ) {
446
+ psa_write (msg .handle , 0 , & index , sizeof (index ));
447
+ }
448
+ break ;
449
+ }
450
+
451
+ case PSA_HASH_CLONE_END : {
452
+ psa_spm_hash_clone_t * hash_clone = NULL ;
453
+ size_t index ;
454
+
455
+ bytes_read = psa_read (msg .handle , 1 , & index , msg .in_size [1 ]);
456
+ if (bytes_read != msg .in_size [1 ]) {
457
+ SPM_PANIC ("SPM read length mismatch" );
458
+ }
459
+
460
+ status = get_hash_clone (index , psa_identity (msg .handle ), & hash_clone );
461
+ if (status == PSA_SUCCESS ) {
462
+ status = psa_hash_clone (hash_clone -> source_operation , msg .rhandle );
463
+ release_hash_clone (hash_clone );
464
+ }
358
465
break ;
359
466
}
360
467
@@ -370,6 +477,7 @@ static void psa_hash_operation(void)
370
477
case PSA_IPC_DISCONNECT : {
371
478
psa_hash_abort (msg .rhandle );
372
479
if (msg .rhandle != NULL ) {
480
+ destroy_hash_clone (msg .rhandle );
373
481
mbedtls_free (msg .rhandle );
374
482
}
375
483
0 commit comments