crypto service: Implement function psa_hash_clone over IPC

pull/9529/head
itayzafrir 2019-01-27 17:35:52 +02:00 committed by Oren Cohen
parent 81a4ff6425
commit 861fb0cbf0
3 changed files with 151 additions and 2 deletions

View File

@ -58,6 +58,8 @@ typedef enum psa_sec_function_s {
PSA_HASH_FINISH,
PSA_HASH_VERIFY,
PSA_HASH_ABORT,
PSA_HASH_CLONE_BEGIN,
PSA_HASH_CLONE_END,
PSA_MAC_SIGN_SETUP,
PSA_MAC_VERIFY_SETUP,
PSA_MAC_UPDATE,

View File

@ -355,7 +355,46 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation)
{
return (PSA_ERROR_NOT_SUPPORTED);
psa_error_t err_call = 0;
psa_crypto_ipc_t psa_crypto_ipc = { 0, 0, 0 };
size_t index;
psa_invec_t in_vec[2] = {
{ &psa_crypto_ipc, sizeof(psa_crypto_ipc) },
{ &index, sizeof(index) }
};
psa_outvec_t out_vec = { &index, sizeof(index) };
if (source_operation->handle <= PSA_NULL_HANDLE || target_operation->handle != PSA_NULL_HANDLE) {
return (PSA_ERROR_BAD_STATE);
}
target_operation->handle = psa_connect(PSA_HASH_ID, MINOR_VER);
if (target_operation->handle <= PSA_NULL_HANDLE) {
return (PSA_ERROR_COMMUNICATION_FAILURE);
}
psa_crypto_ipc.func = PSA_HASH_CLONE_BEGIN;
err_call = psa_call(source_operation->handle, in_vec, 1, &out_vec, 1);
if (err_call < 0) {
err_call = (psa_error_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
if (err_call != 0) {
goto exit;
}
psa_crypto_ipc.func = PSA_HASH_CLONE_END;
err_call = psa_call(target_operation->handle, in_vec, 2, NULL, 0);
if (err_call < 0) {
err_call = (psa_error_t) PSA_ERROR_COMMUNICATION_FAILURE;
}
exit:
if (err_call != 0) {
psa_close(target_operation->handle);
target_operation->handle = PSA_NULL_HANDLE;
}
return ((psa_status_t) err_call);
}
/****************************************************************/

View File

@ -1,4 +1,6 @@
// ---------------------------------- Includes ---------------------------------
#include <stdint.h>
#include <string.h>
#include "spm_panic.h"
#include "spm_server.h"
#include "spm/psa_defs.h"
@ -16,9 +18,80 @@
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
// ------------------------- Globals ---------------------------
// -------------------------------- Structures ---------------------------------
typedef struct psa_spm_hash_clone_s {
int32_t partition_id;
void *source_operation;
uint8_t ref_count;
} psa_spm_hash_clone_t;
// ---------------------------------- Globals ----------------------------------
static int psa_spm_init_refence_counter = 0;
#ifndef MAX_CONCURRENT_HASH_CLONES
#define MAX_CONCURRENT_HASH_CLONES 2
#endif
static psa_spm_hash_clone_t psa_spm_hash_clones[MAX_CONCURRENT_HASH_CLONES];
// ------------------------- Internal Helper Functions -------------------------
static inline psa_status_t reserve_hash_clone(int32_t partition_id, void *source_operation, size_t *index)
{
for (*index = 0; *index < MAX_CONCURRENT_HASH_CLONES; (*index)++) {
if (psa_spm_hash_clones[*index].partition_id == partition_id &&
psa_spm_hash_clones[*index].source_operation == source_operation) {
psa_spm_hash_clones[*index].ref_count++;
return PSA_SUCCESS;
}
}
for (*index = 0; *index < MAX_CONCURRENT_HASH_CLONES; (*index)++) {
if (psa_spm_hash_clones[*index].partition_id == 0 &&
psa_spm_hash_clones[*index].source_operation == NULL) {
psa_spm_hash_clones[*index].partition_id = partition_id;
psa_spm_hash_clones[*index].source_operation = source_operation;
psa_spm_hash_clones[*index].ref_count++;
return PSA_SUCCESS;
}
}
return PSA_ERROR_BAD_STATE;
}
static inline void release_hash_clone(psa_spm_hash_clone_t *hash_clone)
{
hash_clone->ref_count--;
if (hash_clone->ref_count == 0) {
hash_clone->partition_id = 0;
hash_clone->source_operation = NULL;
}
}
static void destroy_hash_clone(void *source_operation)
{
for (size_t i = 0; i < MAX_CONCURRENT_HASH_CLONES; i++) {
if (psa_spm_hash_clones[i].source_operation == source_operation) {
psa_spm_hash_clones[i].partition_id = 0;
psa_spm_hash_clones[i].source_operation = NULL;
psa_spm_hash_clones[i].ref_count = 0;
break;
}
}
}
static inline psa_status_t get_hash_clone(size_t index, int32_t partition_id,
psa_spm_hash_clone_t **hash_clone)
{
if (index >= MAX_CONCURRENT_HASH_CLONES ||
psa_spm_hash_clones[index].partition_id != partition_id ||
psa_spm_hash_clones[index].source_operation == NULL) {
return PSA_ERROR_BAD_STATE;
}
*hash_clone = &psa_spm_hash_clones[index];
return PSA_SUCCESS;
}
// ------------------------- Partition's Main Thread ---------------------------
static void psa_crypto_init_operation(void)
{
@ -36,6 +109,9 @@ static void psa_crypto_init_operation(void)
status = psa_crypto_init();
if (status == PSA_SUCCESS) {
++psa_spm_init_refence_counter;
if (psa_spm_init_refence_counter == 1) {
memset(psa_spm_hash_clones, 0, sizeof(psa_spm_hash_clones));
}
}
break;
@ -71,6 +147,7 @@ static void psa_crypto_free_operation(void)
}
if (psa_spm_init_refence_counter == 0) {
memset(psa_spm_hash_clones, 0, sizeof(psa_spm_hash_clones));
mbedtls_psa_crypto_free();
}
@ -325,6 +402,7 @@ static void psa_hash_operation(void)
}
mbedtls_free(hash);
destroy_hash_clone(msg.rhandle);
break;
}
@ -350,11 +428,40 @@ static void psa_hash_operation(void)
status = psa_hash_verify(msg.rhandle, hash, hash_length);
mbedtls_free(hash);
destroy_hash_clone(msg.rhandle);
break;
}
case PSA_HASH_ABORT: {
status = psa_hash_abort(msg.rhandle);
destroy_hash_clone(msg.rhandle);
break;
}
case PSA_HASH_CLONE_BEGIN: {
size_t index = 0;
status = reserve_hash_clone(psa_identity(msg.handle), msg.rhandle, &index);
if (status == PSA_SUCCESS) {
psa_write(msg.handle, 0, &index, sizeof(index));
}
break;
}
case PSA_HASH_CLONE_END: {
psa_spm_hash_clone_t *hash_clone = NULL;
size_t index;
bytes_read = psa_read(msg.handle, 1, &index, msg.in_size[1]);
if (bytes_read != msg.in_size[1]) {
SPM_PANIC("SPM read length mismatch");
}
status = get_hash_clone(index, psa_identity(msg.handle), &hash_clone);
if (status == PSA_SUCCESS) {
status = psa_hash_clone(hash_clone->source_operation, msg.rhandle);
release_hash_clone(hash_clone);
}
break;
}
@ -370,6 +477,7 @@ static void psa_hash_operation(void)
case PSA_IPC_DISCONNECT: {
psa_hash_abort(msg.rhandle);
if (msg.rhandle != NULL) {
destroy_hash_clone(msg.rhandle);
mbedtls_free(msg.rhandle);
}