diff --git a/tests/psa-client-server/psasim/Makefile b/tests/psa-client-server/psasim/Makefile index 50fd0ad11b..45b31960ee 100644 --- a/tests/psa-client-server/psasim/Makefile +++ b/tests/psa-client-server/psasim/Makefile @@ -1,23 +1,51 @@ CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L ifeq ($(DEBUG),1) - CFLAGS += -DDEBUG -O0 -g + CFLAGS += -DDEBUG endif -.PHONY: all lib test run +LIBPSACLIENT_PATH := ../../libpsaclient +LIBPSASERVER_PATH := ../../libpsaserver -all: lib test +LIBPSACLIENT := -L$(LIBPSACLIENT_PATH)/library -lmbedcrypto -lmbedx509 -lmbedtls +LIBPSASERVER := -L$(LIBPSASERVER_PATH)/library -lmbedcrypto -lib: - $(MAKE) -C src CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" +LIBPSACLIENT_H := -I$(LIBPSACLIENT_PATH)/include +LIBPSASERVER_H := -I$(LIBPSASERVER_PATH)/include -test: lib - $(MAKE) -C test CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" +COMMON_INCLUDE := -I./include + +TEST_BIN = test/psa_client \ + test/psa_partition + +GENERATED_H_FILES = include/psa_manifest/manifest.h \ + include/psa_manifest/pid.h \ + include/psa_manifest/sid.h + +PSA_CLIENT_SRC = src/psa_ff_client.c \ + src/client.c + +PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c + +PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ + src/psa_ff_server.c + +.PHONY: all clean + +all: $(TEST_BIN) + +test/psa_client: $(PSA_CLIENT_SRC) $(GENERATED_H_FILES) + $(CC) $(COMMON_INCLUDE) $(LIBPSACLIENT_H) $(CFLAGS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ + +test/psa_partition: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) + $(CC) $(COMMON_INCLUDE) $(LIBPSASERVER_H) $(CFLAGS) $(PSA_SERVER_SRC) $(LIBPSASERVER) $(LDFLAGS) -o $@ + +$(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES): src/manifest.json src/server.c + tools/psa_autogen.py src/manifest.json clean: - rm -f $(PSA_LIB) $(PSA_LIB_OBJS) - $(MAKE) -C test clean - $(MAKE) -C src clean + rm -f $(TEST_BIN) + rm -f $(PARTITION_SERVER_BOOTSTRAP) + rm -rf include/psa_manifest + rm -f test/psa_service_* test/psa_notify_* -run: test - cd test && ./run_test.sh diff --git a/tests/psa-client-server/psasim/include/psa/client.h b/tests/psa-client-server/psasim/include/client.h similarity index 98% rename from tests/psa-client-server/psasim/include/psa/client.h rename to tests/psa-client-server/psasim/include/client.h index 1044c84bbd..d48498e682 100644 --- a/tests/psa-client-server/psasim/include/psa/client.h +++ b/tests/psa-client-server/psasim/include/client.h @@ -17,7 +17,7 @@ extern "C" { #include "psa/crypto.h" -#include "psa/error_ext.h" +#include "error_ext.h" /*********************** PSA Client Macros and Types *************************/ #define PSA_FRAMEWORK_VERSION (0x0100) diff --git a/tests/psa-client-server/psasim/include/psa/common.h b/tests/psa-client-server/psasim/include/common.h similarity index 100% rename from tests/psa-client-server/psasim/include/psa/common.h rename to tests/psa-client-server/psasim/include/common.h diff --git a/tests/psa-client-server/psasim/include/psa/error_ext.h b/tests/psa-client-server/psasim/include/error_ext.h similarity index 94% rename from tests/psa-client-server/psasim/include/psa/error_ext.h rename to tests/psa-client-server/psasim/include/error_ext.h index efbba864fc..6c82b8a72f 100644 --- a/tests/psa-client-server/psasim/include/psa/error_ext.h +++ b/tests/psa-client-server/psasim/include/error_ext.h @@ -10,7 +10,7 @@ #include -#include "psa/common.h" +#include "common.h" #define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t) -129) #define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t) -130) diff --git a/tests/psa-client-server/psasim/include/psasim/init.h b/tests/psa-client-server/psasim/include/init.h similarity index 94% rename from tests/psa-client-server/psasim/include/psasim/init.h rename to tests/psa-client-server/psasim/include/init.h index 9496fc2a1c..de95d905c7 100644 --- a/tests/psa-client-server/psasim/include/psasim/init.h +++ b/tests/psa-client-server/psasim/include/init.h @@ -6,7 +6,7 @@ */ #include -#include +#include void raise_signal(psa_signal_t signal); void __init_psasim(const char **array, int size, diff --git a/tests/psa-client-server/psasim/include/psa/lifecycle.h b/tests/psa-client-server/psasim/include/lifecycle.h similarity index 100% rename from tests/psa-client-server/psasim/include/psa/lifecycle.h rename to tests/psa-client-server/psasim/include/lifecycle.h diff --git a/tests/psa-client-server/psasim/include/psa/service.h b/tests/psa-client-server/psasim/include/service.h similarity index 99% rename from tests/psa-client-server/psasim/include/psa/service.h rename to tests/psa-client-server/psasim/include/service.h index b6c968427a..cbcb918cb2 100644 --- a/tests/psa-client-server/psasim/include/psa/service.h +++ b/tests/psa-client-server/psasim/include/service.h @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "psa/common.h" +#include "common.h" #include "psa/crypto.h" diff --git a/tests/psa-client-server/psasim/include/psa/util.h b/tests/psa-client-server/psasim/include/util.h similarity index 97% rename from tests/psa-client-server/psasim/include/psa/util.h rename to tests/psa-client-server/psasim/include/util.h index c3669a125d..558149fe2b 100644 --- a/tests/psa-client-server/psasim/include/psa/util.h +++ b/tests/psa-client-server/psasim/include/util.h @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ -#include "psa/service.h" +#include "service.h" #define PRINT(fmt, ...) \ fprintf(stdout, fmt "\n", ##__VA_ARGS__) diff --git a/tests/psa-client-server/psasim/src/Makefile b/tests/psa-client-server/psasim/src/Makefile deleted file mode 100644 index 119971b084..0000000000 --- a/tests/psa-client-server/psasim/src/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# Here I'm picking also libpsaclient/include because I just need it for the -# psa/crypto.h include. libpsaserver would have worked the same. -INCLUDE = -I../include/ -I../../../libpsaclient/include -PSA_LIB = libpsaff.a - -PSA_LIB_OBJS = client.o service.o - -.PHONY: all lib - -all: $(PSA_LIB) - -%.o: %.c - $(CC) $(INCLUDE) $(CFLAGS) -c $< -o $@ - -$(PSA_LIB): $(PSA_LIB_OBJS) - $(AR) rcs $(PSA_LIB) client.o service.o - -clean: - rm -f $(PSA_LIB) $(PSA_LIB_OBJS) diff --git a/tests/psa-client-server/psasim/src/client.c b/tests/psa-client-server/psasim/src/client.c index bd1d5d8813..e8f370d97d 100644 --- a/tests/psa-client-server/psasim/src/client.c +++ b/tests/psa-client-server/psasim/src/client.c @@ -1,392 +1,54 @@ -/* PSA firmware framework client API */ +/* psasim test client */ /* * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include +#include -#include "psa/client.h" -#include "psa/common.h" -#include "psa/error_ext.h" -#include "psa/util.h" +/* Includes from psasim */ +#include +#include +#include "psa_manifest/sid.h" +#include "psa_functions_codes.h" -typedef struct internal_handle { - int server_qid; - int client_qid; - int internal_server_qid; - int valid; -} internal_handle_t; +/* Includes from mbedtls */ +#include "mbedtls/version.h" +#include "psa/crypto.h" -typedef struct vectors { - const psa_invec *in_vec; - size_t in_len; - psa_outvec *out_vec; - size_t out_len; -} vectors_t; +#define CLIENT_PRINT(fmt, ...) \ + PRINT("Client: " fmt, ##__VA_ARGS__) -/* Note that this implementation is functional and not secure */ -int __psa_ff_client_security_state = NON_SECURE; - -/* Access to this global is not thread safe */ -#define MAX_HANDLES 32 -static internal_handle_t handles[MAX_HANDLES] = { { 0 } }; - -static int get_next_free_handle() +int main() { - /* Never return handle 0 as it's a special null handle */ - for (int i = 1; i < MAX_HANDLES; i++) { - if (handles[i].valid == 0) { - return i; - } - } - return -1; -} + char mbedtls_version[18]; + // psa_invec invecs[1]; + // psa_outvec outvecs[1]; + psa_status_t status; -static int handle_is_valid(psa_handle_t handle) -{ - if (handle > 0 && handle < MAX_HANDLES) { - if (handles[handle].valid == 1) { - return 1; - } + 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_SHA256_SID)); + psa_handle_t h = psa_connect(PSA_SID_SHA256_SID, 1); + + if (h < 0) { + CLIENT_PRINT("Couldn't connect %d", h); + return 1; + } + + status = psa_call(h, PSA_CRYPTO_INIT, NULL, 0, NULL, 0); + CLIENT_PRINT("PSA_CRYPTO_INIT returned: %d", status); + + CLIENT_PRINT("Closing handle"); + psa_close(h); + + if (status != PSA_SUCCESS) { + return 1; } - ERROR("ERROR: Invalid handle"); return 0; } - -static int get_queue_info(char *path, int *cqid, int *sqid) -{ - - key_t server_queue_key; - int rx_qid, server_qid; - - INFO("Attempting to contact a RoT service queue"); - - if ((rx_qid = msgget(IPC_PRIVATE, 0660)) == -1) { - ERROR("msgget: rx_qid"); - return -1; - } - - if ((server_queue_key = ftok(path, PROJECT_ID)) == -1) { - ERROR("ftok"); - return -2; - } - - if ((server_qid = msgget(server_queue_key, 0)) == -1) { - ERROR("msgget: server_qid"); - return -3; - } - - *cqid = rx_qid; - *sqid = server_qid; - - return 0; -} - -static psa_status_t process_response(int rx_qid, vectors_t *vecs, int type, - int *internal_server_qid) -{ - - struct message response, request; - psa_status_t ret = PSA_ERROR_CONNECTION_REFUSED; - size_t invec_seek[4] = { 0 }; - size_t data_size; - psa_status_t invec, outvec; /* TODO: Should these be size_t ? */ - - assert(internal_server_qid > 0); - - while (1) { - data_size = 0; - invec = 0; - outvec = 0; - - // read response from server - if (msgrcv(rx_qid, &response, sizeof(struct message_text), 0, 0) == -1) { - ERROR(" msgrcv failed"); - return ret; - } - - // process return message from server - switch (response.message_type) { - case PSA_REPLY: - memcpy(&ret, response.message_text.buf, sizeof(psa_status_t)); - INFO(" Message received from server: %d", ret); - if (type == PSA_IPC_CONNECT && ret > 0) { - *internal_server_qid = ret; - INFO(" ASSSIGNED q ID %d", *internal_server_qid); - ret = PSA_SUCCESS; - } - return ret; - break; - case READ_REQUEST: - /* read data request */ - request.message_type = READ_RESPONSE; - - assert(vecs != 0); - - memcpy(&invec, response.message_text.buf, sizeof(psa_status_t)); - memcpy(&data_size, response.message_text.buf+sizeof(size_t), sizeof(size_t)); - INFO(" Partition asked for %lu bytes from invec %d", data_size, invec); - - /* need to add more checks here */ - assert(invec >= 0 && invec < PSA_MAX_IOVEC); - - if (data_size > MAX_FRAGMENT_SIZE) { - data_size = MAX_FRAGMENT_SIZE; - } - - /* send response */ - INFO(" invec_seek[invec] is %lu", invec_seek[invec]); - INFO(" Reading from offset %p", vecs->in_vec[invec].base + invec_seek[invec]); - memcpy(request.message_text.buf, - (vecs->in_vec[invec].base + invec_seek[invec]), - data_size); - - /* update invec base TODO: check me */ - invec_seek[invec] = invec_seek[invec] + data_size; - - INFO(" Sending message of type %li", request.message_type); - INFO(" with content %s", request.message_text.buf); - - if (msgsnd(*internal_server_qid, &request, - sizeof(int) + sizeof(uint32_t) + data_size, 0) == -1) { - ERROR("Internal error: failed to respond to read request"); - } - break; - case WRITE_REQUEST: - assert(vecs != 0); - - request.message_type = WRITE_RESPONSE; - - memcpy(&outvec, response.message_text.buf, sizeof(psa_status_t)); - memcpy(&data_size, response.message_text.buf + sizeof(size_t), sizeof(size_t)); - INFO(" Partition wants to write %lu bytes to outvec %d", data_size, outvec); - - assert(outvec >= 0 && outvec < PSA_MAX_IOVEC); - - /* copy memory into message and send back amount written */ - size_t sofar = vecs->out_vec[outvec].len; - memcpy(vecs->out_vec[outvec].base + sofar, - response.message_text.buf+(sizeof(size_t)*2), data_size); - INFO(" Data size is %lu", data_size); - vecs->out_vec[outvec].len += data_size; - - INFO(" Sending message of type %li", request.message_type); - - /* send response */ - if (msgsnd(*internal_server_qid, &request, sizeof(int) + data_size, 0) == -1) { - ERROR("Internal error: failed to respond to write request"); - } - break; - case SKIP_REQUEST: - memcpy(&invec, response.message_text.buf, sizeof(psa_status_t)); - memcpy(&data_size, response.message_text.buf+sizeof(size_t), sizeof(size_t)); - INFO(" Partition asked to skip %lu bytes in invec %d", data_size, invec); - assert(invec >= 0 && invec < PSA_MAX_IOVEC); - /* update invec base TODO: check me */ - invec_seek[invec] = invec_seek[invec] + data_size; - break; - - default: - FATAL(" ERROR: unknown internal message type: %ld", - response.message_type); - return ret; - } - } -} - -static psa_status_t send(int rx_qid, int server_qid, int *internal_server_qid, - int32_t type, uint32_t minor_version, vectors_t *vecs) -{ - { - psa_status_t ret = PSA_ERROR_CONNECTION_REFUSED; - size_t request_msg_size = (sizeof(int) + sizeof(long)); /* msg type plus queue id */ - struct message request; - request.message_type = 1; /* TODO: change this */ - request.message_text.psa_type = type; - vector_sizes_t vec_sizes; - - /* If the client is non-secure then set the NS bit */ - if (__psa_ff_client_security_state != 0) { - request.message_type |= NON_SECURE; - } - - assert(request.message_type >= 0); - - INFO("SEND: Sending message of type %ld with psa_type %d", request.message_type, type); - INFO(" internal_server_qid = %i", *internal_server_qid); - - request.message_text.qid = rx_qid; - - if (type == PSA_IPC_CONNECT) { - memcpy(request.message_text.buf, &minor_version, sizeof(minor_version)); - request_msg_size = request_msg_size + sizeof(minor_version); - INFO(" Request msg size is %lu", request_msg_size); - } else { - assert(internal_server_qid > 0); - } - - if (vecs != NULL && type >= PSA_IPC_CALL) { - - memset(&vec_sizes, 0, sizeof(vec_sizes)); - - /* Copy invec sizes */ - for (size_t i = 0; i < (vecs->in_len); i++) { - vec_sizes.invec_sizes[i] = vecs->in_vec[i].len; - INFO(" Client sending vector %lu: %lu", i, vec_sizes.invec_sizes[i]); - } - - /* Copy outvec sizes */ - for (size_t i = 0; i < (vecs->out_len); i++) { - vec_sizes.outvec_sizes[i] = vecs->out_vec[i].len; - - /* Reset to 0 since we need to eventually fill in with bytes written */ - vecs->out_vec[i].len = 0; - } - - memcpy(request.message_text.buf, &vec_sizes, sizeof(vec_sizes)); - request_msg_size = request_msg_size + sizeof(vec_sizes); - } - - INFO(" Sending and then waiting"); - - // send message to server - if (msgsnd(server_qid, &request, request_msg_size, 0) == -1) { - ERROR(" msgsnd failed"); - return ret; - } - - return process_response(rx_qid, vecs, type, internal_server_qid); - } -} - - -uint32_t psa_framework_version(void) -{ - return PSA_FRAMEWORK_VERSION; -} - -psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version) -{ - - int idx; - psa_status_t ret; - char pathname[PATHNAMESIZE] = { 0 }; - - idx = get_next_free_handle(); - - /* if there's a free handle available */ - if (idx >= 0) { - snprintf(pathname, PATHNAMESIZE - 1, TMP_FILE_BASE_PATH "psa_service_%u", sid); - INFO("Attempting to contact RoT service at %s", pathname); - - /* if communication is possible */ - if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) { - - ret = send(handles[idx].client_qid, - handles[idx].server_qid, - &handles[idx].internal_server_qid, - PSA_IPC_CONNECT, - minor_version, - NULL); - - /* if connection accepted by RoT service */ - if (ret >= 0) { - handles[idx].valid = 1; - return idx; - } else { - INFO("Server didn't like you"); - } - } else { - INFO("Couldn't contact RoT service. Does it exist?"); - - if (__psa_ff_client_security_state == 0) { - ERROR("Invalid SID"); - } - } - } - - INFO("Couldn't obtain a free handle"); - return PSA_ERROR_CONNECTION_REFUSED; -} - -uint32_t psa_version(uint32_t sid) -{ - int idx; - psa_status_t ret; - char pathname[PATHNAMESIZE] = { 0 }; - - idx = get_next_free_handle(); - - if (idx >= 0) { - snprintf(pathname, PATHNAMESIZE, TMP_FILE_BASE_PATH "psa_service_%u", sid); - if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) { - ret = send(handles[idx].client_qid, - handles[idx].server_qid, - &handles[idx].internal_server_qid, - VERSION_REQUEST, - 0, - NULL); - INFO("psa_version: Recieved from server %d", ret); - if (ret > 0) { - return ret; - } - } - } - INFO("psa_version failed: does the service exist?"); - return PSA_VERSION_NONE; -} - -psa_status_t psa_call(psa_handle_t handle, - int32_t type, - const psa_invec *in_vec, - size_t in_len, - psa_outvec *out_vec, - size_t out_len) -{ - - handle_is_valid(handle); - - if ((in_len + out_len) > PSA_MAX_IOVEC) { - ERROR("Too many iovecs: %lu + %lu", in_len, out_len); - } - - vectors_t vecs = { 0 }; - vecs.in_vec = in_vec; - vecs.in_len = in_len; - vecs.out_vec = out_vec; - vecs.out_len = out_len; - - return send(handles[handle].client_qid, - handles[handle].server_qid, - &handles[handle].internal_server_qid, - type, - 0, - &vecs); -} - -void psa_close(psa_handle_t handle) -{ - handle_is_valid(handle); - if (send(handles[handle].client_qid, handles[handle].server_qid, - &handles[handle].internal_server_qid, PSA_IPC_DISCONNECT, 0, NULL)) { - ERROR("ERROR: Couldn't send disconnect msg"); - } else { - if (msgctl(handles[handle].client_qid, IPC_RMID, NULL) != 0) { - ERROR("ERROR: Failed to delete msg queue"); - } - } - INFO("Closing handle %u", handle); - handles[handle].valid = 0; -} diff --git a/tests/psa-client-server/psasim/src/common.c b/tests/psa-client-server/psasim/src/common.c deleted file mode 100644 index 287bb504ae..0000000000 --- a/tests/psa-client-server/psasim/src/common.c +++ /dev/null @@ -1,8 +0,0 @@ -/* Common code between clients and services */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include "psa/common.h" diff --git a/tests/psa-client-server/psasim/test/manifest.json b/tests/psa-client-server/psasim/src/manifest.json similarity index 100% rename from tests/psa-client-server/psasim/test/manifest.json rename to tests/psa-client-server/psasim/src/manifest.json diff --git a/tests/psa-client-server/psasim/src/psa_ff_client.c b/tests/psa-client-server/psasim/src/psa_ff_client.c new file mode 100644 index 0000000000..bc2989ffae --- /dev/null +++ b/tests/psa-client-server/psasim/src/psa_ff_client.c @@ -0,0 +1,392 @@ +/* PSA firmware framework client API */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "client.h" +#include "common.h" +#include "error_ext.h" +#include "util.h" + +typedef struct internal_handle { + int server_qid; + int client_qid; + int internal_server_qid; + int valid; +} internal_handle_t; + +typedef struct vectors { + const psa_invec *in_vec; + size_t in_len; + psa_outvec *out_vec; + size_t out_len; +} vectors_t; + +/* Note that this implementation is functional and not secure */ +int __psa_ff_client_security_state = NON_SECURE; + +/* Access to this global is not thread safe */ +#define MAX_HANDLES 32 +static internal_handle_t handles[MAX_HANDLES] = { { 0 } }; + +static int get_next_free_handle() +{ + /* Never return handle 0 as it's a special null handle */ + for (int i = 1; i < MAX_HANDLES; i++) { + if (handles[i].valid == 0) { + return i; + } + } + return -1; +} + +static int handle_is_valid(psa_handle_t handle) +{ + if (handle > 0 && handle < MAX_HANDLES) { + if (handles[handle].valid == 1) { + return 1; + } + } + ERROR("ERROR: Invalid handle"); + return 0; +} + +static int get_queue_info(char *path, int *cqid, int *sqid) +{ + + key_t server_queue_key; + int rx_qid, server_qid; + + INFO("Attempting to contact a RoT service queue"); + + if ((rx_qid = msgget(IPC_PRIVATE, 0660)) == -1) { + ERROR("msgget: rx_qid"); + return -1; + } + + if ((server_queue_key = ftok(path, PROJECT_ID)) == -1) { + ERROR("ftok"); + return -2; + } + + if ((server_qid = msgget(server_queue_key, 0)) == -1) { + ERROR("msgget: server_qid"); + return -3; + } + + *cqid = rx_qid; + *sqid = server_qid; + + return 0; +} + +static psa_status_t process_response(int rx_qid, vectors_t *vecs, int type, + int *internal_server_qid) +{ + + struct message response, request; + psa_status_t ret = PSA_ERROR_CONNECTION_REFUSED; + size_t invec_seek[4] = { 0 }; + size_t data_size; + psa_status_t invec, outvec; /* TODO: Should these be size_t ? */ + + assert(internal_server_qid > 0); + + while (1) { + data_size = 0; + invec = 0; + outvec = 0; + + // read response from server + if (msgrcv(rx_qid, &response, sizeof(struct message_text), 0, 0) == -1) { + ERROR(" msgrcv failed"); + return ret; + } + + // process return message from server + switch (response.message_type) { + case PSA_REPLY: + memcpy(&ret, response.message_text.buf, sizeof(psa_status_t)); + INFO(" Message received from server: %d", ret); + if (type == PSA_IPC_CONNECT && ret > 0) { + *internal_server_qid = ret; + INFO(" ASSSIGNED q ID %d", *internal_server_qid); + ret = PSA_SUCCESS; + } + return ret; + break; + case READ_REQUEST: + /* read data request */ + request.message_type = READ_RESPONSE; + + assert(vecs != 0); + + memcpy(&invec, response.message_text.buf, sizeof(psa_status_t)); + memcpy(&data_size, response.message_text.buf+sizeof(size_t), sizeof(size_t)); + INFO(" Partition asked for %lu bytes from invec %d", data_size, invec); + + /* need to add more checks here */ + assert(invec >= 0 && invec < PSA_MAX_IOVEC); + + if (data_size > MAX_FRAGMENT_SIZE) { + data_size = MAX_FRAGMENT_SIZE; + } + + /* send response */ + INFO(" invec_seek[invec] is %lu", invec_seek[invec]); + INFO(" Reading from offset %p", vecs->in_vec[invec].base + invec_seek[invec]); + memcpy(request.message_text.buf, + (vecs->in_vec[invec].base + invec_seek[invec]), + data_size); + + /* update invec base TODO: check me */ + invec_seek[invec] = invec_seek[invec] + data_size; + + INFO(" Sending message of type %li", request.message_type); + INFO(" with content %s", request.message_text.buf); + + if (msgsnd(*internal_server_qid, &request, + sizeof(int) + sizeof(uint32_t) + data_size, 0) == -1) { + ERROR("Internal error: failed to respond to read request"); + } + break; + case WRITE_REQUEST: + assert(vecs != 0); + + request.message_type = WRITE_RESPONSE; + + memcpy(&outvec, response.message_text.buf, sizeof(psa_status_t)); + memcpy(&data_size, response.message_text.buf + sizeof(size_t), sizeof(size_t)); + INFO(" Partition wants to write %lu bytes to outvec %d", data_size, outvec); + + assert(outvec >= 0 && outvec < PSA_MAX_IOVEC); + + /* copy memory into message and send back amount written */ + size_t sofar = vecs->out_vec[outvec].len; + memcpy(vecs->out_vec[outvec].base + sofar, + response.message_text.buf+(sizeof(size_t)*2), data_size); + INFO(" Data size is %lu", data_size); + vecs->out_vec[outvec].len += data_size; + + INFO(" Sending message of type %li", request.message_type); + + /* send response */ + if (msgsnd(*internal_server_qid, &request, sizeof(int) + data_size, 0) == -1) { + ERROR("Internal error: failed to respond to write request"); + } + break; + case SKIP_REQUEST: + memcpy(&invec, response.message_text.buf, sizeof(psa_status_t)); + memcpy(&data_size, response.message_text.buf+sizeof(size_t), sizeof(size_t)); + INFO(" Partition asked to skip %lu bytes in invec %d", data_size, invec); + assert(invec >= 0 && invec < PSA_MAX_IOVEC); + /* update invec base TODO: check me */ + invec_seek[invec] = invec_seek[invec] + data_size; + break; + + default: + FATAL(" ERROR: unknown internal message type: %ld", + response.message_type); + return ret; + } + } +} + +static psa_status_t send(int rx_qid, int server_qid, int *internal_server_qid, + int32_t type, uint32_t minor_version, vectors_t *vecs) +{ + { + psa_status_t ret = PSA_ERROR_CONNECTION_REFUSED; + size_t request_msg_size = (sizeof(int) + sizeof(long)); /* msg type plus queue id */ + struct message request; + request.message_type = 1; /* TODO: change this */ + request.message_text.psa_type = type; + vector_sizes_t vec_sizes; + + /* If the client is non-secure then set the NS bit */ + if (__psa_ff_client_security_state != 0) { + request.message_type |= NON_SECURE; + } + + assert(request.message_type >= 0); + + INFO("SEND: Sending message of type %ld with psa_type %d", request.message_type, type); + INFO(" internal_server_qid = %i", *internal_server_qid); + + request.message_text.qid = rx_qid; + + if (type == PSA_IPC_CONNECT) { + memcpy(request.message_text.buf, &minor_version, sizeof(minor_version)); + request_msg_size = request_msg_size + sizeof(minor_version); + INFO(" Request msg size is %lu", request_msg_size); + } else { + assert(internal_server_qid > 0); + } + + if (vecs != NULL && type >= PSA_IPC_CALL) { + + memset(&vec_sizes, 0, sizeof(vec_sizes)); + + /* Copy invec sizes */ + for (size_t i = 0; i < (vecs->in_len); i++) { + vec_sizes.invec_sizes[i] = vecs->in_vec[i].len; + INFO(" Client sending vector %lu: %lu", i, vec_sizes.invec_sizes[i]); + } + + /* Copy outvec sizes */ + for (size_t i = 0; i < (vecs->out_len); i++) { + vec_sizes.outvec_sizes[i] = vecs->out_vec[i].len; + + /* Reset to 0 since we need to eventually fill in with bytes written */ + vecs->out_vec[i].len = 0; + } + + memcpy(request.message_text.buf, &vec_sizes, sizeof(vec_sizes)); + request_msg_size = request_msg_size + sizeof(vec_sizes); + } + + INFO(" Sending and then waiting"); + + // send message to server + if (msgsnd(server_qid, &request, request_msg_size, 0) == -1) { + ERROR(" msgsnd failed"); + return ret; + } + + return process_response(rx_qid, vecs, type, internal_server_qid); + } +} + + +uint32_t psa_framework_version(void) +{ + return PSA_FRAMEWORK_VERSION; +} + +psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version) +{ + + int idx; + psa_status_t ret; + char pathname[PATHNAMESIZE] = { 0 }; + + idx = get_next_free_handle(); + + /* if there's a free handle available */ + if (idx >= 0) { + snprintf(pathname, PATHNAMESIZE - 1, TMP_FILE_BASE_PATH "psa_service_%u", sid); + INFO("Attempting to contact RoT service at %s", pathname); + + /* if communication is possible */ + if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) { + + ret = send(handles[idx].client_qid, + handles[idx].server_qid, + &handles[idx].internal_server_qid, + PSA_IPC_CONNECT, + minor_version, + NULL); + + /* if connection accepted by RoT service */ + if (ret >= 0) { + handles[idx].valid = 1; + return idx; + } else { + INFO("Server didn't like you"); + } + } else { + INFO("Couldn't contact RoT service. Does it exist?"); + + if (__psa_ff_client_security_state == 0) { + ERROR("Invalid SID"); + } + } + } + + INFO("Couldn't obtain a free handle"); + return PSA_ERROR_CONNECTION_REFUSED; +} + +uint32_t psa_version(uint32_t sid) +{ + int idx; + psa_status_t ret; + char pathname[PATHNAMESIZE] = { 0 }; + + idx = get_next_free_handle(); + + if (idx >= 0) { + snprintf(pathname, PATHNAMESIZE, TMP_FILE_BASE_PATH "psa_service_%u", sid); + if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) { + ret = send(handles[idx].client_qid, + handles[idx].server_qid, + &handles[idx].internal_server_qid, + VERSION_REQUEST, + 0, + NULL); + INFO("psa_version: Recieved from server %d", ret); + if (ret > 0) { + return ret; + } + } + } + INFO("psa_version failed: does the service exist?"); + return PSA_VERSION_NONE; +} + +psa_status_t psa_call(psa_handle_t handle, + int32_t type, + const psa_invec *in_vec, + size_t in_len, + psa_outvec *out_vec, + size_t out_len) +{ + + handle_is_valid(handle); + + if ((in_len + out_len) > PSA_MAX_IOVEC) { + ERROR("Too many iovecs: %lu + %lu", in_len, out_len); + } + + vectors_t vecs = { 0 }; + vecs.in_vec = in_vec; + vecs.in_len = in_len; + vecs.out_vec = out_vec; + vecs.out_len = out_len; + + return send(handles[handle].client_qid, + handles[handle].server_qid, + &handles[handle].internal_server_qid, + type, + 0, + &vecs); +} + +void psa_close(psa_handle_t handle) +{ + handle_is_valid(handle); + if (send(handles[handle].client_qid, handles[handle].server_qid, + &handles[handle].internal_server_qid, PSA_IPC_DISCONNECT, 0, NULL)) { + ERROR("ERROR: Couldn't send disconnect msg"); + } else { + if (msgctl(handles[handle].client_qid, IPC_RMID, NULL) != 0) { + ERROR("ERROR: Failed to delete msg queue"); + } + } + INFO("Closing handle %u", handle); + handles[handle].valid = 0; +} diff --git a/tests/psa-client-server/psasim/src/service.c b/tests/psa-client-server/psasim/src/psa_ff_server.c similarity index 99% rename from tests/psa-client-server/psasim/src/service.c rename to tests/psa-client-server/psasim/src/psa_ff_server.c index 69c25a211a..ea797d8ced 100644 --- a/tests/psa-client-server/psasim/src/service.c +++ b/tests/psa-client-server/psasim/src/psa_ff_server.c @@ -16,11 +16,11 @@ #include #include -#include "psa/service.h" -#include "psasim/init.h" -#include "psa/error_ext.h" -#include "psa/common.h" -#include "psa/util.h" +#include "service.h" +#include "init.h" +#include "error_ext.h" +#include "common.h" +#include "util.h" #define MAX_CLIENTS 128 #define MAX_MESSAGES 32 @@ -34,7 +34,7 @@ struct connection { }; /* Note that this implementation is functional and not secure. */ -extern int __psa_ff_client_security_state; +int __psa_ff_client_security_state = NON_SECURE; static psa_msg_t messages[MAX_MESSAGES]; /* Message slots */ static uint8_t pending_message[MAX_MESSAGES] = { 0 }; /* Booleans indicating active message slots */ diff --git a/tests/psa-client-server/psasim/test/psa_functions_codes.h b/tests/psa-client-server/psasim/src/psa_functions_codes.h similarity index 100% rename from tests/psa-client-server/psasim/test/psa_functions_codes.h rename to tests/psa-client-server/psasim/src/psa_functions_codes.h diff --git a/tests/psa-client-server/psasim/test/server.c b/tests/psa-client-server/psasim/src/server.c similarity index 97% rename from tests/psa-client-server/psasim/test/server.c rename to tests/psa-client-server/psasim/src/server.c index b88a7ba8d4..630bd7392c 100644 --- a/tests/psa-client-server/psasim/test/server.c +++ b/tests/psa-client-server/psasim/src/server.c @@ -9,9 +9,9 @@ #include /* Includes from psasim */ -#include "psa/service.h" -#include "psa/error_ext.h" -#include "psa/util.h" +#include "service.h" +#include "error_ext.h" +#include "util.h" #include "psa_manifest/manifest.h" #include "psa_functions_codes.h" diff --git a/tests/psa-client-server/psasim/test/Makefile b/tests/psa-client-server/psasim/test/Makefile deleted file mode 100644 index 41f4bd47fc..0000000000 --- a/tests/psa-client-server/psasim/test/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -LIBPSASIM_PATH := .. -LIBPSACLIENT_PATH := ../../../libpsaclient -LIBPSASERVER_PATH := ../../../libpsaserver - -LIBPSASIM := -L$(LIBPSASIM_PATH)/src -lpsaff -LIBPSACLIENT := -L$(LIBPSACLIENT_PATH)/library -lmbedcrypto -lmbedx509 -lmbedtls -LIBPSASERVER := -L$(LIBPSASERVER_PATH)/library -lmbedcrypto - -LIBPSASIM_H := -I$(LIBPSASIM_PATH)/include -LIBPSACLIENT_H := -I$(LIBPSACLIENT_PATH)/include -LIBPSASERVER_H := -I$(LIBPSASERVER_PATH)/include - -COMMON_INCLUDE := $(LIBPSASIM_H) -I./psa_manifest - -TEST_BIN = psa_client \ - psa_partition - -GENERATED_H_FILES = psa_manifest/manifest.h \ - psa_manifest/pid.h \ - psa_manifest/sid.h - -PARTITION_SERVER_BOOTSTRAP = psa_ff_bootstrap_TEST_PARTITION.c - -.PHONY: all clean - -all: $(TEST_BIN) - -psa_client: client.c $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(LIBPSACLIENT_H) $(CFLAGS) $< $(LIBPSASIM) $(LIBPSACLIENT) $(LDFLAGS) -o $@ - -psa_partition: $(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(LIBPSASERVER_H) $(CFLAGS) $< $(LIBPSASIM) $(LIBPSASERVER) $(LDFLAGS) -o $@ - -$(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES): manifest.json server.c - ../tools/psa_autogen.py $< - -clean: - rm -f $(TEST_BIN) psa_ff_bootstrap_*.c - rm -f psa_notify_* psa_service_* - rm -f psa_manifest/* diff --git a/tests/psa-client-server/psasim/test/client.c b/tests/psa-client-server/psasim/test/client.c deleted file mode 100644 index 74e7bcb8d2..0000000000 --- a/tests/psa-client-server/psasim/test/client.c +++ /dev/null @@ -1,54 +0,0 @@ -/* psasim test client */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include -#include - -/* Includes from psasim */ -#include -#include -#include "psa_manifest/sid.h" -#include "psa_functions_codes.h" - -/* Includes from mbedtls */ -#include "mbedtls/version.h" -#include "psa/crypto.h" - -#define CLIENT_PRINT(fmt, ...) \ - PRINT("Client: " fmt, ##__VA_ARGS__) - -int main() -{ - char mbedtls_version[18]; - // psa_invec invecs[1]; - // psa_outvec outvecs[1]; - psa_status_t status; - - 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_SHA256_SID)); - psa_handle_t h = psa_connect(PSA_SID_SHA256_SID, 1); - - if (h < 0) { - CLIENT_PRINT("Couldn't connect %d", h); - return 1; - } - - status = psa_call(h, PSA_CRYPTO_INIT, NULL, 0, NULL, 0); - CLIENT_PRINT("PSA_CRYPTO_INIT returned: %d", status); - - CLIENT_PRINT("Closing handle"); - psa_close(h); - - if (status != PSA_SUCCESS) { - return 1; - } - return 0; -} diff --git a/tests/psa-client-server/psasim/tools/psa_autogen.py b/tests/psa-client-server/psasim/tools/psa_autogen.py index 53b1fea746..cece2b793e 100755 --- a/tests/psa-client-server/psasim/tools/psa_autogen.py +++ b/tests/psa-client-server/psasim/tools/psa_autogen.py @@ -15,6 +15,9 @@ if len(sys.argv) != 2: FILENAME = str(sys.argv[1]) +SCRIPT_PATH = os.path.dirname(__file__) +GENERATED_H_PATH = os.path.join(SCRIPT_PATH, "..", "include", "psa_manifest") +GENERATED_C_PATH = os.path.join(SCRIPT_PATH, "..", "src") with open(str(FILENAME), "r") as read_file: data = json.load(read_file) @@ -32,14 +35,14 @@ with open(str(FILENAME), "r") as read_file: irqs = [] try: - os.mkdir("psa_manifest") + os.mkdir(GENERATED_H_PATH) print("Generating psa_manifest directory") except OSError: print ("PSA manifest directory already exists") - man = open(str("psa_manifest/" + FILENAME + ".h"), "w") - pids = open("psa_manifest/pid.h", "a") - sids = open("psa_manifest/sid.h", "a") + man = open(os.path.join(GENERATED_H_PATH, FILENAME + ".h"), "w") + pids = open(os.path.join(GENERATED_H_PATH, "pid.h"), "a") + sids = open(os.path.join(GENERATED_H_PATH, "sid.h"), "a") if len(services) > 28: print ("Unsupported number of services") @@ -116,23 +119,20 @@ with open(str(FILENAME), "r") as read_file: man.close() symbols = [] - # Go through all the files in the current directory and look for the entrypoint - for root, directories, filenames in os.walk('.'): + # Go through source files and look for the entrypoint + for root, directories, filenames in os.walk(GENERATED_C_PATH): for filename in filenames: - if "psa_ff_bootstrap" in filename or filename == "psa_manifest": continue - try: fullpath = os.path.join(root,filename) with open(fullpath, encoding='utf-8') as currentFile: text = currentFile.read() if str(entry_point + "(") in text: - symbols.append(fullpath) + symbols.append(filename) except IOError: print("Couldn't open " + filename) - except UnicodeDecodeError: pass @@ -144,8 +144,9 @@ with open(str(FILENAME), "r") as read_file: print("Duplicate entrypoint symbol detected: " + str(symbols)) sys.exit(2) else: - bs = open(str("psa_ff_bootstrap_" + str(partition_name) + ".c"), "w") - bs.write("#include \n") + bs = open(os.path.join(GENERATED_C_PATH, "psa_ff_bootstrap_" + partition_name + ".c"), + "w") + bs.write("#include \n") bs.write("#include \"" + symbols[0] + "\"\n") bs.write("#include \n\n") bs.write(qcode)