Skip to content

Commit eea6443

Browse files
author
itayzafrir
committed
crypto service: Implement function psa_hash_clone over IPC
1 parent 3c10e5d commit eea6443

File tree

3 files changed

+151
-2
lines changed

3 files changed

+151
-2
lines changed

components/TARGET_PSA/services/crypto/COMPONENT_PSA_SRV_IPC/crypto_platform_spe.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ typedef enum psa_sec_function_s {
5858
PSA_HASH_FINISH,
5959
PSA_HASH_VERIFY,
6060
PSA_HASH_ABORT,
61+
PSA_HASH_CLONE_BEGIN,
62+
PSA_HASH_CLONE_END,
6163
PSA_MAC_SIGN_SETUP,
6264
PSA_MAC_VERIFY_SETUP,
6365
PSA_MAC_UPDATE,

components/TARGET_PSA/services/crypto/COMPONENT_PSA_SRV_IPC/psa_crypto_spm.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,46 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
355355
psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
356356
psa_hash_operation_t *target_operation)
357357
{
358-
return (PSA_ERROR_NOT_SUPPORTED);
358+
psa_error_t err_call = 0;
359+
psa_crypto_ipc_t psa_crypto_ipc = { 0, 0, 0 };
360+
size_t index;
361+
362+
psa_invec_t in_vec[2] = {
363+
{ &psa_crypto_ipc, sizeof(psa_crypto_ipc) },
364+
{ &index, sizeof(index) }
365+
};
366+
psa_outvec_t out_vec = { &index, sizeof(index) };
367+
368+
if (source_operation->handle <= PSA_NULL_HANDLE || target_operation->handle != PSA_NULL_HANDLE) {
369+
return (PSA_ERROR_BAD_STATE);
370+
}
371+
372+
target_operation->handle = psa_connect(PSA_HASH_ID, MINOR_VER);
373+
if (target_operation->handle <= PSA_NULL_HANDLE) {
374+
return (PSA_ERROR_COMMUNICATION_FAILURE);
375+
}
376+
377+
psa_crypto_ipc.func = PSA_HASH_CLONE_BEGIN;
378+
err_call = psa_call(source_operation->handle, in_vec, 1, &out_vec, 1);
379+
if (err_call < 0) {
380+
err_call = (psa_error_t) PSA_ERROR_COMMUNICATION_FAILURE;
381+
}
382+
if (err_call != 0) {
383+
goto exit;
384+
}
385+
386+
psa_crypto_ipc.func = PSA_HASH_CLONE_END;
387+
err_call = psa_call(target_operation->handle, in_vec, 2, NULL, 0);
388+
if (err_call < 0) {
389+
err_call = (psa_error_t) PSA_ERROR_COMMUNICATION_FAILURE;
390+
}
391+
392+
exit:
393+
if (err_call != 0) {
394+
psa_close(target_operation->handle);
395+
target_operation->handle = PSA_NULL_HANDLE;
396+
}
397+
return ((psa_status_t) err_call);
359398
}
360399

361400
/****************************************************************/

components/TARGET_PSA/services/crypto/COMPONENT_SPE/psa_crypto_partition.c

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// ---------------------------------- Includes ---------------------------------
2+
#include <stdint.h>
3+
#include <string.h>
24
#include "spm_panic.h"
35
#include "spm_server.h"
46
#include "spm/psa_defs.h"
@@ -16,9 +18,80 @@
1618
#define mbedtls_calloc calloc
1719
#define mbedtls_free free
1820
#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 ----------------------------------
2030
static int psa_spm_init_refence_counter = 0;
2131

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+
2295
// ------------------------- Partition's Main Thread ---------------------------
2396
static void psa_crypto_init_operation(void)
2497
{
@@ -36,6 +109,9 @@ static void psa_crypto_init_operation(void)
36109
status = psa_crypto_init();
37110
if (status == PSA_SUCCESS) {
38111
++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+
}
39115
}
40116

41117
break;
@@ -71,6 +147,7 @@ static void psa_crypto_free_operation(void)
71147
}
72148

73149
if (psa_spm_init_refence_counter == 0) {
150+
memset(psa_spm_hash_clones, 0, sizeof(psa_spm_hash_clones));
74151
mbedtls_psa_crypto_free();
75152
}
76153

@@ -325,6 +402,7 @@ static void psa_hash_operation(void)
325402
}
326403

327404
mbedtls_free(hash);
405+
destroy_hash_clone(msg.rhandle);
328406
break;
329407
}
330408

@@ -350,11 +428,40 @@ static void psa_hash_operation(void)
350428

351429
status = psa_hash_verify(msg.rhandle, hash, hash_length);
352430
mbedtls_free(hash);
431+
destroy_hash_clone(msg.rhandle);
353432
break;
354433
}
355434

356435
case PSA_HASH_ABORT: {
357436
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+
}
358465
break;
359466
}
360467

@@ -370,6 +477,7 @@ static void psa_hash_operation(void)
370477
case PSA_IPC_DISCONNECT: {
371478
psa_hash_abort(msg.rhandle);
372479
if (msg.rhandle != NULL) {
480+
destroy_hash_clone(msg.rhandle);
373481
mbedtls_free(msg.rhandle);
374482
}
375483

0 commit comments

Comments
 (0)