mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-29 04:20:12 +00:00
Add PSA crypto sim client and server implementations of psa_hash_compute()
A Perl script that creates them is also included as reference. This is not the final script (that will be in Python) but a proof-of-concept to show that creaation client and server wrappers can be scripted. It is not hooked into the build: it must be run manually. It is not part of the deliverables for this PR. Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
This commit is contained in:
parent
e68fb72d8c
commit
54b4ccdbf8
@ -1,9 +1,18 @@
|
||||
/* THIS FILE WAS AUTO-GENERATED BY psa_sim_generate.pl. DO NOT EDIT!! */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef _PSA_FUNCTIONS_CODES_H_
|
||||
#define _PSA_FUNCTIONS_CODES_H_
|
||||
|
||||
enum {
|
||||
PSA_CRYPTO_INIT = 0x00,
|
||||
/* Add other PSA functions here */
|
||||
/* Start here to avoid overlap with PSA_IPC_CONNECT, PSA_IPC_DISCONNECT
|
||||
* and VERSION_REQUEST */
|
||||
PSA_CRYPTO_INIT = 100,
|
||||
PSA_HASH_COMPUTE,
|
||||
};
|
||||
|
||||
#endif /* _PSA_FUNCTIONS_CODES_H_ */
|
||||
|
207
tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
Normal file
207
tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
Normal file
@ -0,0 +1,207 @@
|
||||
/* THIS FILE WAS AUTO-GENERATED BY psa_sim_generate.pl. DO NOT EDIT!! */
|
||||
|
||||
/* client calls */
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Includes from psasim */
|
||||
#include <client.h>
|
||||
#include <util.h>
|
||||
#include "psa_manifest/sid.h"
|
||||
#include "psa_functions_codes.h"
|
||||
#include "psa_sim_serialise.h"
|
||||
|
||||
/* Includes from mbedtls */
|
||||
#include "mbedtls/version.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#define CLIENT_PRINT(fmt, ...) \
|
||||
PRINT("Client: " fmt, ##__VA_ARGS__)
|
||||
|
||||
static psa_handle_t handle = -1;
|
||||
|
||||
int psa_crypto_call(int function,
|
||||
uint8_t *in_params, size_t in_params_len,
|
||||
uint8_t **out_params, size_t *out_params_len)
|
||||
{
|
||||
// psa_outvec outvecs[1];
|
||||
if (handle < 0) {
|
||||
fprintf(stderr, "NOT CONNECTED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
psa_invec invec;
|
||||
invec.base = in_params;
|
||||
invec.len = in_params_len;
|
||||
|
||||
size_t max_receive = 8192;
|
||||
uint8_t *receive = malloc(max_receive);
|
||||
if (receive == NULL) {
|
||||
fprintf(stderr, "FAILED to allocate %u bytes\n", (unsigned) max_receive);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
size_t actual_received = 0;
|
||||
|
||||
psa_outvec outvecs[2];
|
||||
outvecs[0].base = &actual_received;
|
||||
outvecs[0].len = sizeof(actual_received);
|
||||
outvecs[1].base = receive;
|
||||
outvecs[1].len = max_receive;
|
||||
|
||||
psa_status_t status = psa_call(handle, function, &invec, 1, outvecs, 2);
|
||||
if (status != PSA_SUCCESS) {
|
||||
free(receive);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_params = receive;
|
||||
*out_params_len = actual_received;
|
||||
|
||||
return 1; // success
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_init(void)
|
||||
{
|
||||
char mbedtls_version[18];
|
||||
uint8_t *result = NULL;
|
||||
size_t result_length;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
mbedtls_version_get_string_full(mbedtls_version);
|
||||
CLIENT_PRINT("%s", mbedtls_version);
|
||||
|
||||
CLIENT_PRINT("My PID: %d", getpid());
|
||||
|
||||
CLIENT_PRINT("PSA version: %u", psa_version(PSA_SID_CRYPTO_SID));
|
||||
handle = psa_connect(PSA_SID_CRYPTO_SID, 1);
|
||||
|
||||
if (handle < 0) {
|
||||
CLIENT_PRINT("Couldn't connect %d", handle);
|
||||
return PSA_ERROR_COMMUNICATION_FAILURE;
|
||||
}
|
||||
|
||||
int ok = psa_crypto_call(PSA_CRYPTO_INIT, NULL, 0, &result, &result_length);
|
||||
CLIENT_PRINT("PSA_CRYPTO_INIT returned: %d", ok);
|
||||
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uint8_t *rpos = result;
|
||||
size_t rremain = result_length;
|
||||
|
||||
ok = psasim_deserialise_begin(&rpos, &rremain);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(result);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void mbedtls_psa_crypto_free(void)
|
||||
{
|
||||
CLIENT_PRINT("Closing handle");
|
||||
psa_close(handle);
|
||||
handle = -1;
|
||||
}
|
||||
|
||||
|
||||
psa_status_t psa_hash_compute(
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input, size_t input_length,
|
||||
uint8_t *hash, size_t hash_size,
|
||||
size_t *hash_length
|
||||
)
|
||||
{
|
||||
uint8_t *params = NULL;
|
||||
uint8_t *result = NULL;
|
||||
size_t result_length;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
size_t needed = psasim_serialise_begin_needs() +
|
||||
psasim_serialise_psa_algorithm_t_needs(alg) +
|
||||
psasim_serialise_buffer_needs(input, input_length) +
|
||||
psasim_serialise_buffer_needs(hash, hash_size) +
|
||||
psasim_serialise_size_t_needs(*hash_length);
|
||||
|
||||
params = malloc(needed);
|
||||
if (params == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uint8_t *pos = params;
|
||||
size_t remaining = needed;
|
||||
int ok;
|
||||
ok = psasim_serialise_begin(&pos, &remaining);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_buffer(&pos, &remaining, input, input_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_size);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
ok = psasim_serialise_size_t(&pos, &remaining, *hash_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psa_crypto_call(PSA_HASH_COMPUTE,
|
||||
params, (size_t) (pos - params), &result, &result_length);
|
||||
if (!ok) {
|
||||
printf("XXX server call failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uint8_t *rpos = result;
|
||||
size_t rremain = result_length;
|
||||
|
||||
ok = psasim_deserialise_begin(&rpos, &rremain);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_return_buffer(&rpos, &rremain, hash, hash_size);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_size_t(&rpos, &rremain, hash_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(params);
|
||||
free(result);
|
||||
|
||||
return status;
|
||||
}
|
225
tests/psa-client-server/psasim/src/psa_sim_crypto_server.c
Normal file
225
tests/psa-client-server/psasim/src/psa_sim_crypto_server.c
Normal file
@ -0,0 +1,225 @@
|
||||
/* THIS FILE WAS AUTO-GENERATED BY psa_sim_generate.pl. DO NOT EDIT!! */
|
||||
|
||||
/* server implementations */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
#include "psa_functions_codes.h"
|
||||
#include "psa_sim_serialise.h"
|
||||
|
||||
#include "service.h"
|
||||
|
||||
// Returns 1 for success, 0 for failure
|
||||
int psa_crypto_init_wrapper(
|
||||
uint8_t *in_params, size_t in_params_len,
|
||||
uint8_t **out_params, size_t *out_params_len)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
uint8_t *result = NULL;
|
||||
int ok;
|
||||
|
||||
// Now we call the actual target function
|
||||
|
||||
status = psa_crypto_init(
|
||||
);
|
||||
|
||||
// NOTE: Should really check there is no overflow as we go along.
|
||||
size_t result_size =
|
||||
psasim_serialise_begin_needs() +
|
||||
psasim_serialise_psa_status_t_needs(status);
|
||||
|
||||
result = malloc(result_size);
|
||||
if (result == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uint8_t *rpos = result;
|
||||
size_t rremain = result_size;
|
||||
|
||||
ok = psasim_serialise_begin(&rpos, &rremain);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_serialise_psa_status_t(&rpos, &rremain, status);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*out_params = result;
|
||||
*out_params_len = result_size;
|
||||
|
||||
return 1; // success
|
||||
|
||||
fail:
|
||||
free(result);
|
||||
return 0; // This shouldn't happen!
|
||||
}
|
||||
|
||||
// Returns 1 for success, 0 for failure
|
||||
int psa_hash_compute_wrapper(
|
||||
uint8_t *in_params, size_t in_params_len,
|
||||
uint8_t **out_params, size_t *out_params_len)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_algorithm_t alg;
|
||||
uint8_t *input = NULL;
|
||||
size_t input_length;
|
||||
uint8_t *hash = NULL;
|
||||
size_t hash_size;
|
||||
size_t hash_length;
|
||||
|
||||
uint8_t *pos = in_params;
|
||||
size_t remaining = in_params_len;
|
||||
uint8_t *result = NULL;
|
||||
int ok;
|
||||
|
||||
ok = psasim_deserialise_begin(&pos, &remaining);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_size);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_deserialise_size_t(&pos, &remaining, &hash_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Now we call the actual target function
|
||||
|
||||
status = psa_hash_compute(
|
||||
alg,
|
||||
input, input_length,
|
||||
hash, hash_size,
|
||||
&hash_length
|
||||
);
|
||||
|
||||
// NOTE: Should really check there is no overflow as we go along.
|
||||
size_t result_size =
|
||||
psasim_serialise_begin_needs() +
|
||||
psasim_serialise_psa_status_t_needs(status) +
|
||||
psasim_serialise_buffer_needs(hash, hash_size) +
|
||||
psasim_serialise_size_t_needs(hash_length);
|
||||
|
||||
result = malloc(result_size);
|
||||
if (result == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uint8_t *rpos = result;
|
||||
size_t rremain = result_size;
|
||||
|
||||
ok = psasim_serialise_begin(&rpos, &rremain);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_serialise_psa_status_t(&rpos, &rremain, status);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_serialise_buffer(&rpos, &rremain, hash, hash_size);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = psasim_serialise_size_t(&rpos, &rremain, hash_length);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*out_params = result;
|
||||
*out_params_len = result_size;
|
||||
|
||||
return 1; // success
|
||||
|
||||
fail:
|
||||
free(result);
|
||||
return 0; // This shouldn't happen!
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_call(psa_msg_t msg)
|
||||
{
|
||||
int ok = 0;
|
||||
|
||||
int func = msg.type;
|
||||
|
||||
/* We only expect a single input buffer, with everything serialised in it */
|
||||
if (msg.in_size[1] != 0 || msg.in_size[2] != 0 || msg.in_size[3] != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/* We expect exactly 2 output buffers, one for size, the other for data */
|
||||
if (msg.out_size[0] != sizeof(size_t) || msg.out_size[1] == 0 ||
|
||||
msg.out_size[2] != 0 || msg.out_size[3] != 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
uint8_t *in_params = NULL;
|
||||
size_t in_params_len = 0;
|
||||
uint8_t *out_params = NULL;
|
||||
size_t out_params_len = 0;
|
||||
|
||||
in_params_len = msg.in_size[0];
|
||||
in_params = malloc(in_params_len);
|
||||
if (in_params == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
/* Read the bytes from the client */
|
||||
size_t actual = psa_read(msg.handle, 0, in_params, in_params_len);
|
||||
if (actual != in_params_len) {
|
||||
free(in_params);
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
switch (func) {
|
||||
case PSA_CRYPTO_INIT:
|
||||
ok = psa_crypto_init_wrapper(in_params, in_params_len,
|
||||
&out_params, &out_params_len);
|
||||
break;
|
||||
case PSA_HASH_COMPUTE:
|
||||
ok = psa_hash_compute_wrapper(in_params, in_params_len,
|
||||
&out_params, &out_params_len);
|
||||
break;
|
||||
}
|
||||
|
||||
free(in_params);
|
||||
|
||||
if (out_params_len > msg.out_size[1]) {
|
||||
fprintf(stderr, "unable to write %zu bytes into buffer of %zu bytes\n",
|
||||
out_params_len, msg.out_size[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Write the exact amount of data we're returning */
|
||||
psa_write(msg.handle, 0, &out_params_len, sizeof(out_params_len));
|
||||
|
||||
/* And write the data itself */
|
||||
if (out_params_len) {
|
||||
psa_write(msg.handle, 1, out_params, out_params_len);
|
||||
}
|
||||
|
||||
free(out_params);
|
||||
|
||||
return ok ? PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
1130
tests/psa-client-server/psasim/src/psa_sim_generate.pl
Normal file
1130
tests/psa-client-server/psasim/src/psa_sim_generate.pl
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user