From c57eaf2e6059d33f5f028c96541a83f46c3d6e0f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 3 May 2024 17:28:04 +0200 Subject: [PATCH 001/125] psa-client-server: move psasim from framework repo to the mbedtls one This is a temporary fix that will be reverted once the framework repository will have CI checks. Signed-off-by: Valerio Setti --- psasim/.gitignore | 12 + psasim/Makefile | 23 ++ psasim/README.md | 61 +++ psasim/include/psa/client.h | 73 ++++ psasim/include/psa/common.h | 53 +++ psasim/include/psa/error.h | 38 ++ psasim/include/psa/lifecycle.h | 17 + psasim/include/psa/service.h | 251 +++++++++++++ psasim/include/psa/util.h | 33 ++ psasim/include/psasim/init.h | 15 + psasim/src/Makefile | 17 + psasim/src/client.c | 392 +++++++++++++++++++ psasim/src/common.c | 8 + psasim/src/service.c | 668 +++++++++++++++++++++++++++++++++ psasim/test/Makefile | 29 ++ psasim/test/client.c | 48 +++ psasim/test/manifest.json | 29 ++ psasim/test/run_test.sh | 34 ++ psasim/test/server.c | 119 ++++++ psasim/tools/psa_autogen.py | 165 ++++++++ 20 files changed, 2085 insertions(+) create mode 100644 psasim/.gitignore create mode 100644 psasim/Makefile create mode 100644 psasim/README.md create mode 100644 psasim/include/psa/client.h create mode 100644 psasim/include/psa/common.h create mode 100644 psasim/include/psa/error.h create mode 100644 psasim/include/psa/lifecycle.h create mode 100644 psasim/include/psa/service.h create mode 100644 psasim/include/psa/util.h create mode 100644 psasim/include/psasim/init.h create mode 100644 psasim/src/Makefile create mode 100644 psasim/src/client.c create mode 100644 psasim/src/common.c create mode 100644 psasim/src/service.c create mode 100644 psasim/test/Makefile create mode 100644 psasim/test/client.c create mode 100644 psasim/test/manifest.json create mode 100755 psasim/test/run_test.sh create mode 100644 psasim/test/server.c create mode 100755 psasim/tools/psa_autogen.py diff --git a/psasim/.gitignore b/psasim/.gitignore new file mode 100644 index 0000000000..4065abf771 --- /dev/null +++ b/psasim/.gitignore @@ -0,0 +1,12 @@ +bin/* +*.o +*.so +test/psa_ff_bootstrap.c +test/psa_manifest/* +test/client +test/partition +cscope.out +*.orig +*.swp +*.DS_Store +*psa_ff_bootstrap_* diff --git a/psasim/Makefile b/psasim/Makefile new file mode 100644 index 0000000000..a84483c8f8 --- /dev/null +++ b/psasim/Makefile @@ -0,0 +1,23 @@ +CFLAGS ?= -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L + +ifeq ($(DEBUG),1) + CFLAGS += -DDEBUG -O0 -g +endif + +.PHONY: all lib test run + +all: lib test + +lib: + $(MAKE) -C src CFLAGS="$(CFLAGS)" + +test: lib + $(MAKE) -C test CFLAGS="$(CFLAGS)" + +clean: + rm -f $(PSA_LIB) $(PSA_LIB_OBJS) + $(MAKE) -C test clean + $(MAKE) -C src clean + +run: test + cd test && ./run_test.sh diff --git a/psasim/README.md b/psasim/README.md new file mode 100644 index 0000000000..1b950d6b1d --- /dev/null +++ b/psasim/README.md @@ -0,0 +1,61 @@ +# psasim + +This tool simulates a PSA Firmware Framework implementation. +It allows you to develop secure partitions and their clients on a desktop computer. +It should be able to run on all systems that support POSIX and System V IPC: +e.g. macOS, Linux, FreeBSD, and perhaps Windows 10 WSL2. + +Please note that the code in this directory is maintained by the Mbed TLS / PSA Crypto project solely for the purpose of testing the use of Mbed TLS with client/service separation. We do not recommend using this code for any other purpose. In particular: + +* This simulator is not intended to pass or demonstrate compliance. +* This code is only intended for simulation and does not have any security goals. It does not isolate services from clients. + +## Building + +To build and run the test program make sure you have `make`, `python` and a +C compiler installed and then enter the following commands: + +```sh +make run +``` + +Optionally the `DEBUG=1` command line option can be enabled to increase verbosity: + +```sh +make DEBUG=1 run +``` + +Once done with the test, it is possible to clean all the generated files with: + +```sh +make clean +``` + +## Features + +The implemented API is intended to be compliant with PSA-FF 1.0.0 with the exception of a couple of things that are a work in progress: + +* `psa_notify` support +* "strict" policy in manifest + +The only supported "interrupts" are POSIX signals, which act +as a "virtual interrupt". + +The standard PSA RoT APIs are not included (e.g. cryptography, attestation, lifecycle etc). + +## Design + +The code is designed to be readable rather than fast or secure. +In this implementation only one message is delivered to a +RoT service at a time. +The code is not thread-safe. + +## Unsupported features + +Because this is a simulator there are a few things that +can't be reasonably emulated: + +* Manifest MMIO regions are unsupported +* Manifest priority field is ignored +* Partition IDs are in fact POSIX `pid_t`, which are only assigned at runtime, + making it infeasible to populate pid.h with correct values. diff --git a/psasim/include/psa/client.h b/psasim/include/psa/client.h new file mode 100644 index 0000000000..d1af993f4f --- /dev/null +++ b/psasim/include/psa/client.h @@ -0,0 +1,73 @@ +/* PSA Firmware Framework client header for psasim. */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef __PSA_CLIENT_H__ +#define __PSA_CLIENT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "psa/error.h" +/*********************** PSA Client Macros and Types *************************/ + +#define PSA_FRAMEWORK_VERSION (0x0100) + +#define PSA_VERSION_NONE (0) + +/* PSA response types */ +#define PSA_CONNECTION_REFUSED PSA_ERROR_CONNECTION_REFUSED +#define PSA_CONNECTION_BUSY PSA_ERROR_CONNECTION_BUSY +#define PSA_DROP_CONNECTION PSA_ERROR_PROGRAMMER_ERROR + +/* PSA message handles */ +#define PSA_NULL_HANDLE ((psa_handle_t) 0) + +#define PSA_HANDLE_IS_VALID(handle) ((psa_handle_t) (handle) > 0) +#define PSA_HANDLE_TO_ERROR(handle) ((psa_status_t) (handle)) + +/** + * A read-only input memory region provided to an RoT Service. + */ +typedef struct psa_invec { + const void *base; + size_t len; +} psa_invec; + +/** + * A writable output memory region provided to an RoT Service. + */ +typedef struct psa_outvec { + void *base; + size_t len; +} psa_outvec; + +/*************************** PSA Client API **********************************/ + +uint32_t psa_framework_version(void); + +uint32_t psa_version(uint32_t sid); + +psa_handle_t psa_connect(uint32_t sid, uint32_t version); + +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); + +void psa_close(psa_handle_t handle); + +#ifdef __cplusplus +} +#endif + +#endif /* __PSA_CLIENT_H__ */ diff --git a/psasim/include/psa/common.h b/psasim/include/psa/common.h new file mode 100644 index 0000000000..d0205d291a --- /dev/null +++ b/psasim/include/psa/common.h @@ -0,0 +1,53 @@ +/* Common definitions used for clients and services */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include +#include + +/* Increasing this might break on some platforms */ +#define MAX_FRAGMENT_SIZE 200 + +#define CONNECT_REQUEST 1 +#define CALL_REQUEST 2 +#define CLOSE_REQUEST 3 +#define VERSION_REQUEST 4 +#define READ_REQUEST 5 +#define READ_RESPONSE 6 +#define WRITE_REQUEST 7 +#define WRITE_RESPONSE 8 +#define SKIP_REQUEST 9 +#define PSA_REPLY 10 + +#define NON_SECURE (1 << 30) + +typedef int32_t psa_status_t; +typedef int32_t psa_handle_t; + +#define PSA_MAX_IOVEC (4u) + +#define PSA_IPC_CALL (0) + +struct message_text { + int qid; + int32_t psa_type; + char buf[MAX_FRAGMENT_SIZE]; +}; + +struct message { + long message_type; + struct message_text message_text; +}; + +typedef struct vector_sizes { + size_t invec_sizes[PSA_MAX_IOVEC]; + size_t outvec_sizes[PSA_MAX_IOVEC]; +} vector_sizes_t; + +#endif /* _COMMON_H_ */ diff --git a/psasim/include/psa/error.h b/psasim/include/psa/error.h new file mode 100644 index 0000000000..44fc0b1cbf --- /dev/null +++ b/psasim/include/psa/error.h @@ -0,0 +1,38 @@ +/* PSA status codes used by psasim. */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef PSA_ERROR_H +#define PSA_ERROR_H + +#include + +#include "psa/common.h" + +#define PSA_SUCCESS ((psa_status_t) 0) + +#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t) -129) +#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t) -130) +#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t) -131) +#define PSA_ERROR_GENERIC_ERROR ((psa_status_t) -132) +#define PSA_ERROR_NOT_PERMITTED ((psa_status_t) -133) +#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t) -134) +#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t) -135) +#define PSA_ERROR_INVALID_HANDLE ((psa_status_t) -136) +#define PSA_ERROR_BAD_STATE ((psa_status_t) -137) +#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t) -138) +#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t) -139) +#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t) -140) +#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t) -141) +#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t) -142) +#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t) -143) +#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t) -144) +#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t) -145) +#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t) -146) +#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t) -147) +#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t) -149) + +#endif diff --git a/psasim/include/psa/lifecycle.h b/psasim/include/psa/lifecycle.h new file mode 100644 index 0000000000..1148397a88 --- /dev/null +++ b/psasim/include/psa/lifecycle.h @@ -0,0 +1,17 @@ +/* PSA lifecycle states used by psasim. */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#define PSA_LIFECYCLE_PSA_STATE_MASK (0xff00u) +#define PSA_LIFECYCLE_IMP_STATE_MASK (0x00ffu) +#define PSA_LIFECYCLE_UNKNOWN (0x0000u) +#define PSA_LIFECYCLE_ASSEMBLY_AND_TEST (0x1000u) +#define PSA_LIFECYCLE_PSA_ROT_PROVISIONING (0x2000u) +#define PSA_LIFECYCLE_SECURED (0x3000u) +#define PSA_LIFECYCLE_NON_PSA_ROT_DEBUG (0x4000u) +#define PSA_LIFECYCLE_RECOVERABLE_PSA_ROT_DEBUG (0x5000u) +#define PSA_LIFECYCLE_DECOMMISSIONED (0x6000u) +#define psa_rot_lifecycle_state(void) PSA_LIFECYCLE_UNKNOWN diff --git a/psasim/include/psa/service.h b/psasim/include/psa/service.h new file mode 100644 index 0000000000..c8c00245ae --- /dev/null +++ b/psasim/include/psa/service.h @@ -0,0 +1,251 @@ +/* PSA Firmware Framework service header for psasim. */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef __PSA_SERVICE_H__ +#define __PSA_SERVICE_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include + +#include "psa/common.h" + +/********************** PSA Secure Partition Macros and Types ****************/ + +/* PSA wait timeouts */ +#define PSA_POLL (0x00000000u) +#define PSA_BLOCK (0x80000000u) + +/* A mask value that includes all Secure Partition signals */ +#define PSA_WAIT_ANY (~0u) + +/* Doorbell signal */ +#define PSA_DOORBELL (0x00000008u) + +/* PSA message types */ +#define PSA_IPC_CONNECT (-1) +#define PSA_IPC_DISCONNECT (-2) + +/* Return code from psa_get() */ +#define PSA_ERR_NOMSG (INT32_MIN + 3) + +/* Store a set of one or more Secure Partition signals */ +typedef uint32_t psa_signal_t; + +/** + * Describe a message received by an RoT Service after calling \ref psa_get(). + */ +typedef struct psa_msg_t { + uint32_t type; /* One of the following values: + * \ref PSA_IPC_CONNECT + * \ref PSA_IPC_CALL + * \ref PSA_IPC_DISCONNECT + */ + psa_handle_t handle; /* A reference generated by the SPM to the + * message returned by psa_get(). + */ + int32_t client_id; /* Partition ID of the sender of the message */ + void *rhandle; /* Be useful for binding a connection to some + * application-specific data or function + * pointer within the RoT Service + * implementation. + */ + size_t in_size[PSA_MAX_IOVEC]; /* Provide the size of each client input + * vector in bytes. + */ + size_t out_size[PSA_MAX_IOVEC];/* Provide the size of each client output + * vector in bytes. + */ +} psa_msg_t; + +/************************* PSA Secure Partition API **************************/ + +/** + * \brief Return the Secure Partition interrupt signals that have been asserted + * from a subset of signals provided by the caller. + * + * \param[in] signal_mask A set of signals to query. Signals that are not + * in this set will be ignored. + * \param[in] timeout Specify either blocking \ref PSA_BLOCK or + * polling \ref PSA_POLL operation. + * + * \retval >0 At least one signal is asserted. + * \retval 0 No signals are asserted. This is only seen when + * a polling timeout is used. + */ +psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout); + +/** + * \brief Retrieve the message which corresponds to a given RoT Service signal + * and remove the message from the RoT Service queue. + * + * \param[in] signal The signal value for an asserted RoT Service. + * \param[out] msg Pointer to \ref psa_msg_t object for receiving + * the message. + * + * \retval PSA_SUCCESS Success, *msg will contain the delivered + * message. + * \retval PSA_ERR_NOMSG Message could not be delivered. + * \retval "Does not return" The call is invalid because one or more of the + * following are true: + * \arg signal has more than a single bit set. + * \arg signal does not correspond to an RoT Service. + * \arg The RoT Service signal is not currently + * asserted. + * \arg The msg pointer provided is not a valid memory + * reference. + */ +psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg); + +/** + * \brief Associate some RoT Service private data with a client connection. + * + * \param[in] msg_handle Handle for the client's message. + * \param[in] rhandle Reverse handle allocated by the RoT Service. + * + * \retval void Success, rhandle will be provided with all + * subsequent messages delivered on this + * connection. + * \retval "Does not return" msg_handle is invalid. + */ +void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle); + +/** + * \brief Read a message parameter or part of a message parameter from a client + * input vector. + * + * \param[in] msg_handle Handle for the client's message. + * \param[in] invec_idx Index of the input vector to read from. Must be + * less than \ref PSA_MAX_IOVEC. + * \param[out] buffer Buffer in the Secure Partition to copy the + * requested data to. + * \param[in] num_bytes Maximum number of bytes to be read from the + * client input vector. + * + * \retval >0 Number of bytes copied. + * \retval 0 There was no remaining data in this input + * vector. + * \retval "Does not return" The call is invalid, one or more of the + * following are true: + * \arg msg_handle is invalid. + * \arg msg_handle does not refer to a + * \ref PSA_IPC_CALL message. + * \arg invec_idx is equal to or greater than + * \ref PSA_MAX_IOVEC. + * \arg the memory reference for buffer is invalid or + * not writable. + */ +size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx, + void *buffer, size_t num_bytes); + +/** + * \brief Skip over part of a client input vector. + * + * \param[in] msg_handle Handle for the client's message. + * \param[in] invec_idx Index of input vector to skip from. Must be + * less than \ref PSA_MAX_IOVEC. + * \param[in] num_bytes Maximum number of bytes to skip in the client + * input vector. + * + * \retval >0 Number of bytes skipped. + * \retval 0 There was no remaining data in this input + * vector. + * \retval "Does not return" The call is invalid, one or more of the + * following are true: + * \arg msg_handle is invalid. + * \arg msg_handle does not refer to a + * \ref PSA_IPC_CALL message. + * \arg invec_idx is equal to or greater than + * \ref PSA_MAX_IOVEC. + */ +size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes); + +/** + * \brief Write a message response to a client output vector. + * + * \param[in] msg_handle Handle for the client's message. + * \param[out] outvec_idx Index of output vector in message to write to. + * Must be less than \ref PSA_MAX_IOVEC. + * \param[in] buffer Buffer with the data to write. + * \param[in] num_bytes Number of bytes to write to the client output + * vector. + * + * \retval void Success + * \retval "Does not return" The call is invalid, one or more of the + * following are true: + * \arg msg_handle is invalid. + * \arg msg_handle does not refer to a + * \ref PSA_IPC_CALL message. + * \arg outvec_idx is equal to or greater than + * \ref PSA_MAX_IOVEC. + * \arg The memory reference for buffer is invalid. + * \arg The call attempts to write data past the end + * of the client output vector. + */ +void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, + const void *buffer, size_t num_bytes); + +/** + * \brief Complete handling of a specific message and unblock the client. + * + * \param[in] msg_handle Handle for the client's message. + * \param[in] status Message result value to be reported to the + * client. + * + * \retval void Success. + * \retval "Does not return" The call is invalid, one or more of the + * following are true: + * \arg msg_handle is invalid. + * \arg An invalid status code is specified for the + * type of message. + */ +void psa_reply(psa_handle_t msg_handle, psa_status_t status); + +/** + * \brief Send a PSA_DOORBELL signal to a specific Secure Partition. + * + * \param[in] partition_id Secure Partition ID of the target partition. + * + * \retval void Success. + * \retval "Does not return" partition_id does not correspond to a Secure + * Partition. + */ +void psa_notify(int32_t partition_id); + +/** + * \brief Clear the PSA_DOORBELL signal. + * + * \retval void Success. + * \retval "Does not return" The Secure Partition's doorbell signal is not + * currently asserted. + */ +void psa_clear(void); + +/** + * \brief Inform the SPM that an interrupt has been handled (end of interrupt). + * + * \param[in] irq_signal The interrupt signal that has been processed. + * + * \retval void Success. + * \retval "Does not return" The call is invalid, one or more of the + * following are true: + * \arg irq_signal is not an interrupt signal. + * \arg irq_signal indicates more than one signal. + * \arg irq_signal is not currently asserted. + */ +void psa_eoi(psa_signal_t irq_signal); + +#define psa_panic(X) abort(); + +#ifdef __cplusplus +} +#endif + +#endif /* __PSA_SERVICE_H__ */ diff --git a/psasim/include/psa/util.h b/psasim/include/psa/util.h new file mode 100644 index 0000000000..c3669a125d --- /dev/null +++ b/psasim/include/psa/util.h @@ -0,0 +1,33 @@ +/* Common definitions used for clients and services */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa/service.h" + +#define PRINT(fmt, ...) \ + fprintf(stdout, fmt "\n", ##__VA_ARGS__) + +#if defined(DEBUG) +#define INFO(fmt, ...) \ + fprintf(stdout, "Info (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) + +#define ERROR(fmt, ...) \ + fprintf(stdout, "Error (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) + +#define FATAL(fmt, ...) \ + { \ + fprintf(stdout, "Fatal (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ + abort(); \ + } +#else /* DEBUG */ +#define INFO(...) +#define ERROR(...) +#define FATAL(...) +#endif /* DEBUG*/ + +#define PROJECT_ID 'M' +#define PATHNAMESIZE 256 +#define TMP_FILE_BASE_PATH "./" diff --git a/psasim/include/psasim/init.h b/psasim/include/psasim/init.h new file mode 100644 index 0000000000..9496fc2a1c --- /dev/null +++ b/psasim/include/psasim/init.h @@ -0,0 +1,15 @@ +/* Declarations of internal functions. */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include +#include +void raise_signal(psa_signal_t signal); +void __init_psasim(const char **array, + int size, + const int allow_ns_clients_array[32], + const uint32_t versions[32], + const int strict_policy_array[32]); diff --git a/psasim/src/Makefile b/psasim/src/Makefile new file mode 100644 index 0000000000..fc6ba25aab --- /dev/null +++ b/psasim/src/Makefile @@ -0,0 +1,17 @@ +INCLUDE = -I../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/psasim/src/client.c b/psasim/src/client.c new file mode 100644 index 0000000000..5a3986e32c --- /dev/null +++ b/psasim/src/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 "psa/client.h" +#include "psa/common.h" +#include "psa/error.h" +#include "psa/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/psasim/src/common.c b/psasim/src/common.c new file mode 100644 index 0000000000..287bb504ae --- /dev/null +++ b/psasim/src/common.c @@ -0,0 +1,8 @@ +/* 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/psasim/src/service.c b/psasim/src/service.c new file mode 100644 index 0000000000..b2b6a08f54 --- /dev/null +++ b/psasim/src/service.c @@ -0,0 +1,668 @@ +/* PSA Firmware Framework service 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 "psa/service.h" +#include "psasim/init.h" +#include "psa/error.h" +#include "psa/common.h" +#include "psa/util.h" + +#define MAX_CLIENTS 128 +#define MAX_MESSAGES 32 + +#define SLEEP_MS 50 + +struct connection { + uint32_t client; + void *rhandle; + int client_to_server_q; +}; + +/* Note that this implementation is functional and not secure. */ +extern int __psa_ff_client_security_state; + +static psa_msg_t messages[MAX_MESSAGES]; /* Message slots */ +static uint8_t pending_message[MAX_MESSAGES] = { 0 }; /* Booleans indicating active message slots */ +static uint32_t message_client[MAX_MESSAGES] = { 0 }; /* Each client's response queue */ +static int nsacl[32]; +static int strict_policy[32] = { 0 }; +static uint32_t rot_svc_versions[32]; +static int rot_svc_incoming_queue[32] = { -1 }; +static struct connection connections[MAX_CLIENTS] = { { 0 } }; + +static uint32_t exposed_signals = 0; + +void print_vectors(vector_sizes_t *sizes) +{ + INFO("Printing iovec sizes"); + for (int j = 0; j < PSA_MAX_IOVEC; j++) { + INFO("Invec %d: %lu", j, sizes->invec_sizes[j]); + } + + for (int j = 0; j < PSA_MAX_IOVEC; j++) { + INFO("Outvec %d: %lu", j, sizes->outvec_sizes[j]); + } +} + +int find_connection(uint32_t client) +{ + for (int i = 1; i < MAX_CLIENTS; i++) { + if (client == connections[i].client) { + return i; + } + } + return -1; +} + +void destroy_connection(uint32_t client) +{ + int idx = find_connection(client); + if (idx >= 0) { + connections[idx].client = 0; + connections[idx].rhandle = 0; + INFO("Destroying connection"); + } else { + ERROR("Couldn't destroy connection for %u", client); + } +} + +int find_free_connection() +{ + INFO("Allocating connection"); + return find_connection(0); +} + +static void reply(psa_handle_t msg_handle, psa_status_t status) +{ + pending_message[msg_handle] = 1; + psa_reply(msg_handle, status); + pending_message[msg_handle] = 0; +} + +psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout) +{ + psa_signal_t mask; + struct message msg; + vector_sizes_t sizes; + struct msqid_ds qinfo; + uint32_t requested_version; + ssize_t len; + int idx; +#if !defined(PSASIM_USE_USLEEP) + const struct timespec ts_delay = { .tv_sec = 0, .tv_nsec = SLEEP_MS * 1000000 }; +#endif + + if (timeout == PSA_POLL) { + INFO("psa_wait: Called in polling mode"); + } + + do { + mask = signal_mask; + + /* Check the status of each queue */ + for (int i = 0; i < 32; i++) { + if (mask & 0x1) { + if (i < 3) { + // do nothing (reserved) + } else if (i == 3) { + // this must be psa doorbell + } else { + /* Check if this signal corresponds to a queue */ + if (rot_svc_incoming_queue[i] >= 0 && (pending_message[i] == 0)) { + + /* AFAIK there is no "peek" method in SysV, so try to get a message */ + len = msgrcv(rot_svc_incoming_queue[i], + &msg, + sizeof(struct message_text), + 0, + IPC_NOWAIT); + if (len > 0) { + + INFO("Storing that QID in message_client[%d]", i); + INFO("The message handle will be %d", i); + + msgctl(rot_svc_incoming_queue[i], IPC_STAT, &qinfo); + messages[i].client_id = qinfo.msg_lspid; /* PID of last msgsnd(2) call */ + message_client[i] = msg.message_text.qid; + idx = find_connection(msg.message_text.qid); + + if (msg.message_type & NON_SECURE) { + /* This is a non-secure message */ + + /* Check if NS client is allowed for this RoT service */ + if (nsacl[i] <= 0) { +#if 0 + INFO( + "Rejecting non-secure client due to manifest security policy"); + reply(i, PSA_ERROR_CONNECTION_REFUSED); + continue; /* Skip to next signal */ +#endif + } + + msg.message_type &= ~(NON_SECURE); /* clear */ + messages[i].client_id = messages[i].client_id * -1; + } + + INFO("Got a message from client ID %d", messages[i].client_id); + INFO("Message type is %lu", msg.message_type); + INFO("PSA message type is %d", msg.message_text.psa_type); + + messages[i].handle = i; + + switch (msg.message_text.psa_type) { + case PSA_IPC_CONNECT: + + if (len >= 16) { + memcpy(&requested_version, msg.message_text.buf, + sizeof(requested_version)); + INFO("Requesting version %u", requested_version); + INFO("Implemented version %u", rot_svc_versions[i]); + /* TODO: need to check whether the policy is strict, + * and if so, then reject the client if the number doesn't match */ + + if (requested_version > rot_svc_versions[i]) { + INFO( + "Rejecting client because requested version that was too high"); + reply(i, PSA_ERROR_CONNECTION_REFUSED); + continue; /* Skip to next signal */ + } + + if (strict_policy[i] == 1 && + (requested_version != rot_svc_versions[i])) { + INFO( + "Rejecting client because enforcing a STRICT version policy"); + reply(i, PSA_ERROR_CONNECTION_REFUSED); + continue; /* Skip to next signal */ + } else { + INFO("Not rejecting client"); + } + } + + messages[i].type = PSA_IPC_CONNECT; + + if (idx < 0) { + idx = find_free_connection(); + } + + if (idx >= 0) { + connections[idx].client = msg.message_text.qid; + } else { + /* We've run out of system wide connections */ + reply(i, PSA_ERROR_CONNECTION_BUSY); + ERROR("Ran out of free connections"); + continue; + } + + break; + case PSA_IPC_DISCONNECT: + messages[i].type = PSA_IPC_DISCONNECT; + break; + case VERSION_REQUEST: + INFO("Got a version request"); + reply(i, rot_svc_versions[i]); + continue; /* Skip to next signal */ + break; + + default: + + /* PSA CALL */ + if (msg.message_text.psa_type >= 0) { + messages[i].type = msg.message_text.psa_type; + memcpy(&sizes, msg.message_text.buf, sizeof(sizes)); + print_vectors(&sizes); + memcpy(&messages[i].in_size, &sizes.invec_sizes, + (sizeof(size_t) * PSA_MAX_IOVEC)); + memcpy(&messages[i].out_size, &sizes.outvec_sizes, + (sizeof(size_t) * PSA_MAX_IOVEC)); + } else { + FATAL("UNKNOWN MESSAGE TYPE RECEIVED %li", + msg.message_type); + } + break; + } + messages[i].handle = i; + + /* Check if the client has a connection */ + if (idx >= 0) { + messages[i].rhandle = connections[idx].rhandle; + } else { + /* Client is begging for a programmer error */ + reply(i, PSA_ERROR_PROGRAMMER_ERROR); + continue; + } + + /* House keeping */ + pending_message[i] = 1; /* set message as pending */ + exposed_signals |= (0x1 << i); /* assert the signal */ + } + } + } + mask = mask >> 1; + } + } + + if ((timeout == PSA_BLOCK) && (exposed_signals > 0)) { + break; + } else { + /* There is no 'select' function in SysV to block on multiple queues, so busy-wait :( */ +#if defined(PSASIM_USE_USLEEP) + usleep(SLEEP_MS * 1000); +#else /* PSASIM_USE_USLEEP */ + nanosleep(&ts_delay, NULL); +#endif /* PSASIM_USE_USLEEP */ + } + } while (timeout == PSA_BLOCK); + + /* Assert signals */ + return signal_mask & exposed_signals; +} + +static int signal_to_index(psa_signal_t signal) +{ + int i; + int count = 0; + int ret = -1; + + for (i = 0; i < 32; i++) { + if (signal & 0x1) { + ret = i; + count++; + } + signal = signal >> 1; + } + + if (count > 1) { + ERROR("ERROR: Too many signals"); + return -1; /* Too many signals */ + } + return ret; +} + +static void clear_signal(psa_signal_t signal) +{ + exposed_signals = exposed_signals & ~signal; +} + +void raise_signal(psa_signal_t signal) +{ + exposed_signals |= signal; +} + +psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg) +{ + int index = signal_to_index(signal); + if (index < 0) { + ERROR("Bad signal"); + } + + clear_signal(signal); + + assert(messages[index].handle != 0); + + if (pending_message[index] == 1) { + INFO("There is a pending message!"); + memcpy(msg, &messages[index], sizeof(struct psa_msg_t)); + assert(msg->handle != 0); + return PSA_SUCCESS; + } else { + INFO("no pending message"); + } + + return PSA_ERROR_DOES_NOT_EXIST; +} + +static inline int is_valid_msg_handle(psa_handle_t h) +{ + if (h > 0 && h < MAX_MESSAGES) { + return 1; + } + ERROR("Not a valid message handle"); + return 0; +} + +static inline int is_call_msg(psa_handle_t h) +{ + assert(messages[h].type >= PSA_IPC_CALL); + return 1; +} + +void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle) +{ + is_valid_msg_handle(msg_handle); + int idx = find_connection(message_client[msg_handle]); + INFO("Setting rhandle to %p", rhandle); + assert(idx >= 0); + connections[idx].rhandle = rhandle; +} + +/* Sends a message from the server to the client. Does not wait for a response */ +static void send_msg(psa_handle_t msg_handle, + int ctrl_msg, + psa_status_t status, + size_t amount, + const void *data, + size_t data_amount) +{ + struct message response; + int flags = 0; + + assert(ctrl_msg > 0); /* According to System V, it must be greater than 0 */ + + response.message_type = ctrl_msg; + if (ctrl_msg == PSA_REPLY) { + memcpy(response.message_text.buf, &status, sizeof(psa_status_t)); + } else if (ctrl_msg == READ_REQUEST || ctrl_msg == WRITE_REQUEST || ctrl_msg == SKIP_REQUEST) { + memcpy(response.message_text.buf, &status, sizeof(psa_status_t)); + memcpy(response.message_text.buf+sizeof(size_t), &amount, sizeof(size_t)); + if (ctrl_msg == WRITE_REQUEST) { + /* TODO: Check if too big */ + memcpy(response.message_text.buf + (sizeof(size_t) * 2), data, data_amount); + } + } + + /* TODO: sizeof doesn't need to be so big here for small responses */ + if (msgsnd(message_client[msg_handle], &response, sizeof(response.message_text), flags) == -1) { + ERROR("Failed to reply"); + } +} + +static size_t skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes) +{ + if (num_bytes < (messages[msg_handle].in_size[invec_idx] - num_bytes)) { + messages[msg_handle].in_size[invec_idx] = messages[msg_handle].in_size[invec_idx] - + num_bytes; + return num_bytes; + } else { + if (num_bytes >= messages[msg_handle].in_size[invec_idx]) { + size_t ret = messages[msg_handle].in_size[invec_idx]; + messages[msg_handle].in_size[invec_idx] = 0; + return ret; + } else { + return num_bytes; + } + } +} + +size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx, + void *buffer, size_t num_bytes) +{ + size_t sofar = 0; + struct message msg = { 0 }; + int idx; + ssize_t len; + + is_valid_msg_handle(msg_handle); + is_call_msg(msg_handle); + + if (invec_idx >= PSA_MAX_IOVEC) { + ERROR("Invalid iovec number"); + } + + /* If user wants more data than what's available, truncate their request */ + if (num_bytes > messages[msg_handle].in_size[invec_idx]) { + num_bytes = messages[msg_handle].in_size[invec_idx]; + } + + while (sofar < num_bytes) { + INFO("Server: requesting %lu bytes from client", (num_bytes - sofar)); + send_msg(msg_handle, READ_REQUEST, invec_idx, (num_bytes - sofar), NULL, 0); + + idx = find_connection(message_client[msg_handle]); + assert(idx >= 0); + + len = msgrcv(connections[idx].client_to_server_q, &msg, sizeof(struct message_text), 0, 0); + len = (len - sizeof(msg.message_text.qid)); + + if (len < 0) { + FATAL("Internal error: failed to dispatch read request to the client"); + } + + if (len > (num_bytes - sofar)) { + if ((num_bytes - sofar) > 0) { + memcpy(buffer+sofar, msg.message_text.buf, (num_bytes - sofar)); + } + } else { + memcpy(buffer + sofar, msg.message_text.buf, len); + } + + INFO("Printing what i got so far: %s", msg.message_text.buf); + + sofar = sofar + len; + } + + /* Update the seek count */ + skip(msg_handle, invec_idx, num_bytes); + INFO("Finished psa_read"); + return sofar; +} + +void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, + const void *buffer, size_t num_bytes) +{ + + size_t sofar = 0; + struct message msg = { 0 }; + int idx; + ssize_t len; + + is_valid_msg_handle(msg_handle); + is_call_msg(msg_handle); + + if (outvec_idx >= PSA_MAX_IOVEC) { + ERROR("Invalid iovec number"); + } + + if (num_bytes > messages[msg_handle].out_size[outvec_idx]) { + ERROR("Program tried to write too much data %lu/%lu", num_bytes, + messages[msg_handle].out_size[outvec_idx]); + } + + while (sofar < num_bytes) { + size_t sending = (num_bytes - sofar); + if (sending >= MAX_FRAGMENT_SIZE) { + sending = MAX_FRAGMENT_SIZE - (sizeof(size_t) * 2); + } + + INFO("Server: sending %lu bytes to client", sending); + + send_msg(msg_handle, WRITE_REQUEST, outvec_idx, sending, buffer, sending); + + idx = find_connection(message_client[msg_handle]); + assert(idx >= 0); + + len = msgrcv(connections[idx].client_to_server_q, &msg, sizeof(struct message_text), 0, 0); + if (len < 1) { + FATAL("Client didn't give me a full response"); + } + sofar = sofar + len; + } + + /* Update the seek count */ + messages[msg_handle].out_size[outvec_idx] -= num_bytes; +} + +size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes) +{ + + is_valid_msg_handle(msg_handle); + is_call_msg(msg_handle); + + size_t ret = skip(msg_handle, invec_idx, num_bytes); + + /* notify client to skip */ + send_msg(msg_handle, SKIP_REQUEST, invec_idx, num_bytes, NULL, 0); + return ret; +} + +static void destroy_temporary_queue(int myqid) +{ + + if (msgctl(myqid, IPC_RMID, NULL) != 0) { + INFO("ERROR: Failed to delete msg queue %d", myqid); + } +} + +static int make_temporary_queue() +{ + int myqid; + if ((myqid = msgget(IPC_PRIVATE, 0660)) == -1) { + INFO("msgget: myqid"); + return -1; + } + return myqid; +} + +/** + * Assumes msg_handle is the index into the message array + */ +void psa_reply(psa_handle_t msg_handle, psa_status_t status) +{ + int idx, q; + is_valid_msg_handle(msg_handle); + + if (pending_message[msg_handle] != 1) { + ERROR("Not a valid message handle"); + } + + if (messages[msg_handle].type == PSA_IPC_CONNECT) { + switch (status) { + case PSA_SUCCESS: + idx = find_connection(message_client[msg_handle]); + q = make_temporary_queue(); + if (q > 0 && idx >= 0) { + connections[idx].client_to_server_q = q; + status = q; + } else { + FATAL("What happened?"); + } + break; + case PSA_ERROR_CONNECTION_REFUSED: + destroy_connection(message_client[msg_handle]); + break; + case PSA_ERROR_CONNECTION_BUSY: + destroy_connection(message_client[msg_handle]); + break; + case PSA_ERROR_PROGRAMMER_ERROR: + destroy_connection(message_client[msg_handle]); + break; + default: + ERROR("Not a valid reply %d", status); + } + } else if (messages[msg_handle].type == PSA_IPC_DISCONNECT) { + idx = find_connection(message_client[msg_handle]); + if (idx >= 0) { + destroy_temporary_queue(connections[idx].client_to_server_q); + } + destroy_connection(message_client[msg_handle]); + } + + send_msg(msg_handle, PSA_REPLY, status, 0, NULL, 0); + + pending_message[msg_handle] = 0; + message_client[msg_handle] = 0; +} + +/* TODO: make sure you only clear interrupt signals, and not others */ +void psa_eoi(psa_signal_t signal) +{ + int index = signal_to_index(signal); + if (index >= 0 && (rot_svc_incoming_queue[index] >= 0)) { + clear_signal(signal); + } else { + ERROR("Tried to EOI a signal that isn't an interrupt"); + } +} + +void psa_notify(int32_t partition_id) +{ + char pathname[PATHNAMESIZE] = { 0 }; + + if (partition_id < 0) { + ERROR("Not a valid secure partition"); + } + + snprintf(pathname, PATHNAMESIZE, "/tmp/psa_notify_%u", partition_id); + INFO("psa_notify: notifying partition %u using %s", + partition_id, pathname); + INFO("psa_notify is unimplemented"); +} + +void psa_clear(void) +{ + clear_signal(PSA_DOORBELL); +} + +void __init_psasim(const char **array, + int size, + const int allow_ns_clients_array[32], + const uint32_t versions[32], + const int strict_policy_array[32]) +{ + + static uint8_t library_initialised = 0; + key_t key; + int qid; + FILE *fp; + char doorbell_path[PATHNAMESIZE] = { 0 }; + char queue_path[PATHNAMESIZE]; + snprintf(doorbell_path, PATHNAMESIZE, TMP_FILE_BASE_PATH "psa_notify_%u", getpid()); + + if (library_initialised > 0) { + return; + } else { + library_initialised = 1; + } + + if (size != 32) { + FATAL("Unsupported value. Aborting."); + } + + array[3] = doorbell_path; + + for (int i = 0; i < 32; i++) { + if (strncmp(array[i], "", 1) != 0) { + INFO("Setting up %s", array[i]); + memset(queue_path, 0, sizeof(queue_path)); + sprintf(queue_path, "%s%s", TMP_FILE_BASE_PATH, array[i]); + + /* Create file if doesn't exist */ + fp = fopen(queue_path, "ab+"); + if (fp) { + fclose(fp); + } + + if ((key = ftok(queue_path, PROJECT_ID)) == -1) { + FATAL("Error finding message queue during initialisation"); + } + + /* TODO: Investigate. Permissions are likely to be too relaxed */ + if ((qid = msgget(key, IPC_CREAT | 0660)) == -1) { + FATAL("Error opening message queue during initialisation"); + } else { + rot_svc_incoming_queue[i] = qid; + } + } + } + + memcpy(nsacl, allow_ns_clients_array, sizeof(int) * 32); + memcpy(strict_policy, strict_policy_array, sizeof(int) * 32); + memcpy(rot_svc_versions, versions, sizeof(uint32_t) * 32); + memset(&connections, 0, sizeof(struct connection) * MAX_CLIENTS); + + __psa_ff_client_security_state = 0; /* Set the client status to SECURE */ +} diff --git a/psasim/test/Makefile b/psasim/test/Makefile new file mode 100644 index 0000000000..34b86b616c --- /dev/null +++ b/psasim/test/Makefile @@ -0,0 +1,29 @@ +INCLUDE := -I../include/ -I./psa_manifest +LIB := -L../src -lpsaff + +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) $(INCLUDE) $(CFLAGS) $< $(LIB) -o $@ + +psa_partition: $(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES) + $(CC) $(INCLUDE) $(CFLAGS) $< $(LIB) -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/psasim/test/client.c b/psasim/test/client.c new file mode 100644 index 0000000000..5bde82fa22 --- /dev/null +++ b/psasim/test/client.c @@ -0,0 +1,48 @@ +/* psasim test client */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include +#include +#include "psa_manifest/sid.h" +#include +#include + +#define CLIENT_PRINT(fmt, ...) \ + PRINT("Client: " fmt, ##__VA_ARGS__) + +int main() +{ + const char *text = "FOOBARCOOL!!"; + char output[100] = { 0 }; + 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; + } else { + int type = 2; + CLIENT_PRINT("psa_call() w/o invec returned: %d", psa_call(h, type, NULL, 0, NULL, 0)); + psa_invec invecs[1]; + psa_outvec outvecs[1]; + invecs[0].base = text; + invecs[0].len = sizeof(text); + outvecs[0].base = output; + outvecs[0].len = sizeof(output); + + CLIENT_PRINT("invec len: %lu", invecs[0].len); + CLIENT_PRINT("psa_call() w/ invec returned: %d", psa_call(h, type, invecs, 1, outvecs, 1)); + CLIENT_PRINT("Received payload len: %ld", outvecs[0].len); + CLIENT_PRINT("Received payload content: %s", output); + CLIENT_PRINT("Closing handle"); + psa_close(h); + } + + return 0; +} diff --git a/psasim/test/manifest.json b/psasim/test/manifest.json new file mode 100644 index 0000000000..0ab83ef907 --- /dev/null +++ b/psasim/test/manifest.json @@ -0,0 +1,29 @@ +{ + "psa_framework_version":1.0, + "name":"TEST_PARTITION", + "type":"PSA-ROT", + "priority":"LOW", + "entry_point":"psa_sha256_main", + "stack_size":"0x400", + "heap_size":"0x100", + "services":[ + { + "name":"PSA_SID_SHA256", + "sid":"0x0000F000", + "signal":"PSA_SHA256", + "non_secure_clients": "true", + "minor_version":1, + "minor_policy":"STRICT" + } + ], + "irqs": [ + { + "source": "SIGINT", + "signal": "SIGINT_SIG" + }, + { + "source": "SIGTSTP", + "signal": "SIGSTP_SIG" + } + ] +} diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh new file mode 100755 index 0000000000..f0e7a62f1a --- /dev/null +++ b/psasim/test/run_test.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# This is a simple bash script that tests psa_client/psa_server interaction. +# This script is automatically executed when "make run" is launched by the +# "psasim" root folder. The script can also be launched manually once +# binary files are built (i.e. after "make test" is executed from the "psasim" +# root folder). +# +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +set -e + +function clean_run() { + pkill psa_partition || true + pkill psa_client || true + ipcs | grep q | awk '{ printf " -q " $$2 }' | xargs ipcrm > /dev/null 2>&1 || true +} + +# The server creates some local files when it starts up so we can wait for this +# event as signal that the server is ready so that we can start client(s). +function wait_for_server_startup() { + while [ ! -f ./psa_notify_* ]; do + sleep 0.1 + done +} + +clean_run + +./psa_partition -k & +SERV_PID=$! +wait_for_server_startup +./psa_client +wait $SERV_PID diff --git a/psasim/test/server.c b/psasim/test/server.c new file mode 100644 index 0000000000..c4b6d9c9a2 --- /dev/null +++ b/psasim/test/server.c @@ -0,0 +1,119 @@ +/* psasim test server */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include +#include + +#include "psa/service.h" +#include "psa/error.h" +#include "psa/util.h" +#include "psa_manifest/manifest.h" + +#define SERVER_PRINT(fmt, ...) \ + PRINT("Server: " fmt, ##__VA_ARGS__) + +#define BUF_SIZE 25 + +static int kill_on_disconnect = 0; /* Kill the server on client disconnection. */ + +void parse_input_args(int argc, char *argv[]) +{ + int opt; + + while ((opt = getopt(argc, argv, "k")) != -1) { + switch (opt) { + case 'k': + kill_on_disconnect = 1; + break; + default: + fprintf(stderr, "Usage: %s [-k]\n", argv[0]); + exit(EXIT_FAILURE); + } + } +} + +int psa_sha256_main(int argc, char *argv[]) +{ + psa_status_t ret = PSA_ERROR_PROGRAMMER_ERROR; + psa_msg_t msg = { -1 }; + char foo[BUF_SIZE] = { 0 }; + const int magic_num = 66; + int client_disconnected = 0; + + parse_input_args(argc, argv); + SERVER_PRINT("Starting"); + + while (!(kill_on_disconnect && client_disconnected)) { + psa_signal_t signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK); + + if (signals > 0) { + SERVER_PRINT("Signals: 0x%08x", signals); + } + + if (signals & PSA_SHA256_SIGNAL) { + if (PSA_SUCCESS == psa_get(PSA_SHA256_SIGNAL, &msg)) { + SERVER_PRINT("My handle is %d", msg.handle); + SERVER_PRINT("My rhandle is %p", (int *) msg.rhandle); + switch (msg.type) { + case PSA_IPC_CONNECT: + SERVER_PRINT("Got a connection message"); + psa_set_rhandle(msg.handle, (void *) &magic_num); + ret = PSA_SUCCESS; + break; + case PSA_IPC_DISCONNECT: + SERVER_PRINT("Got a disconnection message"); + ret = PSA_SUCCESS; + client_disconnected = 1; + break; + + default: + SERVER_PRINT("Got an IPC call of type %d", msg.type); + ret = 42; + size_t size = msg.in_size[0]; + + if ((size > 0) && (size <= sizeof(foo))) { + psa_read(msg.handle, 0, foo, 6); + foo[(BUF_SIZE-1)] = '\0'; + SERVER_PRINT("Reading payload: %s", foo); + psa_read(msg.handle, 0, foo+6, 6); + foo[(BUF_SIZE-1)] = '\0'; + SERVER_PRINT("Reading payload: %s", foo); + } + + size = msg.out_size[0]; + if ((size > 0)) { + SERVER_PRINT("Writing response"); + psa_write(msg.handle, 0, "RESP", 4); + psa_write(msg.handle, 0, "ONSE", 4); + } + + if (msg.client_id > 0) { + psa_notify(msg.client_id); + } else { + SERVER_PRINT("Client is non-secure, so won't notify"); + } + + } + + psa_reply(msg.handle, ret); + } else { + SERVER_PRINT("Failed to retrieve message"); + } + } else if (SIGSTP_SIG & signals) { + SERVER_PRINT("Recieved SIGSTP signal. Gonna EOI it."); + psa_eoi(SIGSTP_SIG); + } else if (SIGINT_SIG & signals) { + SERVER_PRINT("Handling interrupt!"); + SERVER_PRINT("Gracefully quitting"); + psa_panic(); + } else { + SERVER_PRINT("No signal asserted"); + } + } + + return 0; +} diff --git a/psasim/tools/psa_autogen.py b/psasim/tools/psa_autogen.py new file mode 100755 index 0000000000..53b1fea746 --- /dev/null +++ b/psasim/tools/psa_autogen.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +"""This hacky script generates a partition from a manifest file""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import json +import os +import sys +from os import listdir + +if len(sys.argv) != 2: + print("Usage: psa_autogen ") + sys.exit(1) + +FILENAME = str(sys.argv[1]) + + +with open(str(FILENAME), "r") as read_file: + data = json.load(read_file) + FILENAME = os.path.basename(FILENAME) + FILENAME = FILENAME.split('.')[0] + print("Base filename is " + str(FILENAME)) + + if str(data['psa_framework_version'] == "1.0"): + entry_point = str(data['entry_point']) + partition_name = str(data['name']) + services = data['services'] + try: + irqs = data['irqs'] + except KeyError: + irqs = [] + + try: + os.mkdir("psa_manifest") + 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") + + if len(services) > 28: + print ("Unsupported number of services") + + count = 4 # For creating SID array + nsacl = "const int ns_allowed[32] = { " + policy = "const int strict_policy[32] = { " + qcode = "const char *psa_queues[] = { " + versions = "const uint32_t versions[32] = { " + queue_path = "psa_service_" + start = False + + for x in range(0, count): + qcode = qcode + "\"\", " + nsacl = nsacl + "0, " + policy = policy + "0, " + versions = versions + "0, " + + # Go through all the services to make sid.h and pid.h + for svc in services: + man.write("#define {}_SIGNAL 0x{:08x}\n".format(svc['signal'], 2**count)) + sids.write("#define {}_SID {}\n".format(svc['name'], svc['sid'])) + qcode = qcode + "\"" + queue_path + str(int(svc['sid'], 16)) + "\"," + ns_clients = svc['non_secure_clients'] + print(str(svc)) + if ns_clients == "true": + nsacl = nsacl + "1, " + else: + nsacl = nsacl + "0, " + try: + versions = versions + str(svc['minor_version']) + ", " + except KeyError: + versions = versions + "1, " + + strict = 0 + try: + if str(svc['minor_policy']).lower() == "strict": + strict = 1 + policy = policy + "1, " + else: + policy = policy + "0, " + except KeyError: + strict = 0 + policy = policy + "0, " + + count = count+1 + + sigcode = "" + handlercode = "void __sig_handler(int signo) {\n" + irqcount = count + for irq in irqs: + man.write("#define {} 0x{:08x}\n".format(irq['signal'], 2**irqcount)) + sigcode = sigcode + " signal({}, __sig_handler);\n".format(irq['source']) + handlercode = handlercode + \ + " if (signo == {}) {{ raise_signal(0x{:08x}); }};\n".format(irq['source'], 2**irqcount) + irqcount = irqcount+1 + + handlercode = handlercode + "}\n" + + while (count < 32): + qcode = qcode + "\"\", " + nsacl = nsacl + "0, " + versions = versions + "0, " + policy = policy + "0, " + count = count + 1 + + qcode = qcode + "};\n" + nsacl = nsacl + "};\n" + versions = versions + "};\n" + policy = policy + "};\n" + + pids.close() + sids.close() + man.close() + + symbols = [] + # Go through all the files in the current directory and look for the entrypoint + + for root, directories, filenames in os.walk('.'): + 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) + except IOError: + print("Couldn't open " + filename) + + except UnicodeDecodeError: + pass + + print(str("Number of entrypoints detected: " + str(len(symbols)))) + if len(symbols) < 1: + print("Couldn't find function " + entry_point) + sys.exit(1) + elif len(symbols) > 1: + 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.write("#include \"" + symbols[0] + "\"\n") + bs.write("#include \n\n") + bs.write(qcode) + bs.write(nsacl) + bs.write(policy) + bs.write(versions) + bs.write("\n") + bs.write(handlercode) + bs.write("\n") + bs.write("int main(int argc, char *argv[]) {\n") + bs.write(" (void) argc;\n") + bs.write(sigcode) + bs.write(" __init_psasim(psa_queues, 32, ns_allowed, versions, strict_policy);\n") + bs.write(" " + entry_point + "(argc, argv);\n}\n") + bs.close() + + print("Success") From 3da878a1cd36e121781edb488f4decbe97a5df2a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 7 May 2024 16:00:21 +0200 Subject: [PATCH 002/125] crypto-client test: add mechanism to build crypto library for client and server It includes changes to: - tests/Makefile: build the library for client and server in different folders. It mimica the libtestdriver1 behavior (without functions renaming though). - tests/scripts/all.sh: helper function to build for client and server with some default configuration for each of them. - crypto_spe.h: this is dummy file taken from the already existing tests. It's just meant to pacify the compiler, not to provide something useful. It will likely be changed in the future. Signed-off-by: Valerio Setti --- psasim/include/crypto_spe.h | 131 ++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 psasim/include/crypto_spe.h diff --git a/psasim/include/crypto_spe.h b/psasim/include/crypto_spe.h new file mode 100644 index 0000000000..fdf3a2db5a --- /dev/null +++ b/psasim/include/crypto_spe.h @@ -0,0 +1,131 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + * + */ + +/** + * \file crypto_spe.h + * + * \brief When Mbed TLS is built with the MBEDTLS_PSA_CRYPTO_SPM option + * enabled, this header is included by all .c files in Mbed TLS that + * use PSA Crypto function names. This avoids duplication of symbols + * between TF-M and Mbed TLS. + * + * \note This file should be included before including any PSA Crypto headers + * from Mbed TLS. + */ + +#ifndef CRYPTO_SPE_H +#define CRYPTO_SPE_H + +#define PSA_FUNCTION_NAME(x) mbedcrypto__ ## x + +#define psa_crypto_init \ + PSA_FUNCTION_NAME(psa_crypto_init) +#define psa_key_derivation_get_capacity \ + PSA_FUNCTION_NAME(psa_key_derivation_get_capacity) +#define psa_key_derivation_set_capacity \ + PSA_FUNCTION_NAME(psa_key_derivation_set_capacity) +#define psa_key_derivation_input_bytes \ + PSA_FUNCTION_NAME(psa_key_derivation_input_bytes) +#define psa_key_derivation_output_bytes \ + PSA_FUNCTION_NAME(psa_key_derivation_output_bytes) +#define psa_key_derivation_input_key \ + PSA_FUNCTION_NAME(psa_key_derivation_input_key) +#define psa_key_derivation_output_key \ + PSA_FUNCTION_NAME(psa_key_derivation_output_key) +#define psa_key_derivation_setup \ + PSA_FUNCTION_NAME(psa_key_derivation_setup) +#define psa_key_derivation_abort \ + PSA_FUNCTION_NAME(psa_key_derivation_abort) +#define psa_key_derivation_key_agreement \ + PSA_FUNCTION_NAME(psa_key_derivation_key_agreement) +#define psa_raw_key_agreement \ + PSA_FUNCTION_NAME(psa_raw_key_agreement) +#define psa_generate_random \ + PSA_FUNCTION_NAME(psa_generate_random) +#define psa_aead_encrypt \ + PSA_FUNCTION_NAME(psa_aead_encrypt) +#define psa_aead_decrypt \ + PSA_FUNCTION_NAME(psa_aead_decrypt) +#define psa_open_key \ + PSA_FUNCTION_NAME(psa_open_key) +#define psa_close_key \ + PSA_FUNCTION_NAME(psa_close_key) +#define psa_import_key \ + PSA_FUNCTION_NAME(psa_import_key) +#define psa_destroy_key \ + PSA_FUNCTION_NAME(psa_destroy_key) +#define psa_get_key_attributes \ + PSA_FUNCTION_NAME(psa_get_key_attributes) +#define psa_reset_key_attributes \ + PSA_FUNCTION_NAME(psa_reset_key_attributes) +#define psa_export_key \ + PSA_FUNCTION_NAME(psa_export_key) +#define psa_export_public_key \ + PSA_FUNCTION_NAME(psa_export_public_key) +#define psa_purge_key \ + PSA_FUNCTION_NAME(psa_purge_key) +#define psa_copy_key \ + PSA_FUNCTION_NAME(psa_copy_key) +#define psa_cipher_operation_init \ + PSA_FUNCTION_NAME(psa_cipher_operation_init) +#define psa_cipher_generate_iv \ + PSA_FUNCTION_NAME(psa_cipher_generate_iv) +#define psa_cipher_set_iv \ + PSA_FUNCTION_NAME(psa_cipher_set_iv) +#define psa_cipher_encrypt_setup \ + PSA_FUNCTION_NAME(psa_cipher_encrypt_setup) +#define psa_cipher_decrypt_setup \ + PSA_FUNCTION_NAME(psa_cipher_decrypt_setup) +#define psa_cipher_update \ + PSA_FUNCTION_NAME(psa_cipher_update) +#define psa_cipher_finish \ + PSA_FUNCTION_NAME(psa_cipher_finish) +#define psa_cipher_abort \ + PSA_FUNCTION_NAME(psa_cipher_abort) +#define psa_hash_operation_init \ + PSA_FUNCTION_NAME(psa_hash_operation_init) +#define psa_hash_setup \ + PSA_FUNCTION_NAME(psa_hash_setup) +#define psa_hash_update \ + PSA_FUNCTION_NAME(psa_hash_update) +#define psa_hash_finish \ + PSA_FUNCTION_NAME(psa_hash_finish) +#define psa_hash_verify \ + PSA_FUNCTION_NAME(psa_hash_verify) +#define psa_hash_abort \ + PSA_FUNCTION_NAME(psa_hash_abort) +#define psa_hash_clone \ + PSA_FUNCTION_NAME(psa_hash_clone) +#define psa_hash_compute \ + PSA_FUNCTION_NAME(psa_hash_compute) +#define psa_hash_compare \ + PSA_FUNCTION_NAME(psa_hash_compare) +#define psa_mac_operation_init \ + PSA_FUNCTION_NAME(psa_mac_operation_init) +#define psa_mac_sign_setup \ + PSA_FUNCTION_NAME(psa_mac_sign_setup) +#define psa_mac_verify_setup \ + PSA_FUNCTION_NAME(psa_mac_verify_setup) +#define psa_mac_update \ + PSA_FUNCTION_NAME(psa_mac_update) +#define psa_mac_sign_finish \ + PSA_FUNCTION_NAME(psa_mac_sign_finish) +#define psa_mac_verify_finish \ + PSA_FUNCTION_NAME(psa_mac_verify_finish) +#define psa_mac_abort \ + PSA_FUNCTION_NAME(psa_mac_abort) +#define psa_sign_hash \ + PSA_FUNCTION_NAME(psa_sign_hash) +#define psa_verify_hash \ + PSA_FUNCTION_NAME(psa_verify_hash) +#define psa_asymmetric_encrypt \ + PSA_FUNCTION_NAME(psa_asymmetric_encrypt) +#define psa_asymmetric_decrypt \ + PSA_FUNCTION_NAME(psa_asymmetric_decrypt) +#define psa_generate_key \ + PSA_FUNCTION_NAME(psa_generate_key) + +#endif /* CRYPTO_SPE_H */ From 7238f3d8a396701dde569c757663912f797fdfd0 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 9 May 2024 09:15:39 +0200 Subject: [PATCH 003/125] crypto-client test: ensure that client/server are linked against proper MbedTLS libraries Ensure that both server and client can call mbedtls_version_get_string_full() to verify that they are linked against proper libraries. Note: each side (client/server) performs the call against its own MbedTLS library. There is no IPC communication involved in this test. Client/server communication will come later. Signed-off-by: Valerio Setti --- psasim/Makefile | 6 +++--- psasim/test/Makefile | 19 +++++++++++++++---- psasim/test/client.c | 12 ++++++++++-- psasim/test/run_test.sh | 4 ++-- psasim/test/server.c | 6 ++++++ 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/psasim/Makefile b/psasim/Makefile index a84483c8f8..50fd0ad11b 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -1,4 +1,4 @@ -CFLAGS ?= -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L +CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L ifeq ($(DEBUG),1) CFLAGS += -DDEBUG -O0 -g @@ -9,10 +9,10 @@ endif all: lib test lib: - $(MAKE) -C src CFLAGS="$(CFLAGS)" + $(MAKE) -C src CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" test: lib - $(MAKE) -C test CFLAGS="$(CFLAGS)" + $(MAKE) -C test CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" clean: rm -f $(PSA_LIB) $(PSA_LIB_OBJS) diff --git a/psasim/test/Makefile b/psasim/test/Makefile index 34b86b616c..5afc8f58a2 100644 --- a/psasim/test/Makefile +++ b/psasim/test/Makefile @@ -1,5 +1,16 @@ -INCLUDE := -I../include/ -I./psa_manifest -LIB := -L../src -lpsaff +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 @@ -15,10 +26,10 @@ PARTITION_SERVER_BOOTSTRAP = psa_ff_bootstrap_TEST_PARTITION.c all: $(TEST_BIN) psa_client: client.c $(GENERATED_H_FILES) - $(CC) $(INCLUDE) $(CFLAGS) $< $(LIB) -o $@ + $(CC) $(COMMON_INCLUDE) $(LIBPSACLIENT_H) $(CFLAGS) $< $(LIBPSASIM) $(LIBPSACLIENT) -o $@ psa_partition: $(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES) - $(CC) $(INCLUDE) $(CFLAGS) $< $(LIB) -o $@ + $(CC) $(COMMON_INCLUDE) $(LIBPSASERVER_H) $(CFLAGS) $< $(LIBPSASIM) $(LIBPSASERVER) -o $@ $(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES): manifest.json server.c ../tools/psa_autogen.py $< diff --git a/psasim/test/client.c b/psasim/test/client.c index 5bde82fa22..3c61120a11 100644 --- a/psasim/test/client.c +++ b/psasim/test/client.c @@ -5,19 +5,27 @@ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ +#include +#include + #include #include #include "psa_manifest/sid.h" -#include -#include + +#include "mbedtls/version.h" #define CLIENT_PRINT(fmt, ...) \ PRINT("Client: " fmt, ##__VA_ARGS__) int main() { + char mbedtls_version[18]; const char *text = "FOOBARCOOL!!"; char output[100] = { 0 }; + + 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)); diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh index f0e7a62f1a..0ffaaea794 100755 --- a/psasim/test/run_test.sh +++ b/psasim/test/run_test.sh @@ -27,8 +27,8 @@ function wait_for_server_startup() { clean_run -./psa_partition -k & +./psa_partition -k > psa_partition.log 2>&1 & SERV_PID=$! wait_for_server_startup -./psa_client +./psa_client > psa_client.log 2>&1 wait $SERV_PID diff --git a/psasim/test/server.c b/psasim/test/server.c index c4b6d9c9a2..1c873c6c06 100644 --- a/psasim/test/server.c +++ b/psasim/test/server.c @@ -13,6 +13,8 @@ #include "psa/util.h" #include "psa_manifest/manifest.h" +#include "mbedtls/version.h" + #define SERVER_PRINT(fmt, ...) \ PRINT("Server: " fmt, ##__VA_ARGS__) @@ -43,6 +45,10 @@ int psa_sha256_main(int argc, char *argv[]) char foo[BUF_SIZE] = { 0 }; const int magic_num = 66; int client_disconnected = 0; + char mbedtls_version[18]; + + mbedtls_version_get_string_full(mbedtls_version); + SERVER_PRINT("%s", mbedtls_version); parse_input_args(argc, argv); SERVER_PRINT("Starting"); From 306d9e68bb2db5be15a54044738afcde8f658710 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 9 May 2024 12:20:40 +0200 Subject: [PATCH 004/125] crypto-client test: implement the first IPC call for psa_crypto_init() This commit implements the first useful IPC communication between the client and the server. The implemented command is simple, psa_crypto_init(), and its return value is sent back to the client. Note: the newly added file psa_functions_codes.h is temporary and it's probably the one that needs to be automatically generated by a python script to support all crypto functions. Signed-off-by: Valerio Setti --- psasim/include/psa/client.h | 4 ++- psasim/include/psa/common.h | 1 - psasim/include/psa/error.h | 38 --------------------------- psasim/include/psa/error_ext.h | 19 ++++++++++++++ psasim/include/psa/service.h | 2 ++ psasim/src/Makefile | 4 ++- psasim/src/client.c | 2 +- psasim/src/service.c | 2 +- psasim/test/Makefile | 4 +-- psasim/test/client.c | 34 ++++++++++++------------ psasim/test/manifest.json | 4 +-- psasim/test/psa_functions_codes.h | 9 +++++++ psasim/test/run_test.sh | 5 +++- psasim/test/server.c | 43 ++++++++++++------------------- 14 files changed, 79 insertions(+), 92 deletions(-) delete mode 100644 psasim/include/psa/error.h create mode 100644 psasim/include/psa/error_ext.h create mode 100644 psasim/test/psa_functions_codes.h diff --git a/psasim/include/psa/client.h b/psasim/include/psa/client.h index d1af993f4f..1044c84bbd 100644 --- a/psasim/include/psa/client.h +++ b/psasim/include/psa/client.h @@ -15,7 +15,9 @@ extern "C" { #include #include -#include "psa/error.h" +#include "psa/crypto.h" + +#include "psa/error_ext.h" /*********************** PSA Client Macros and Types *************************/ #define PSA_FRAMEWORK_VERSION (0x0100) diff --git a/psasim/include/psa/common.h b/psasim/include/psa/common.h index d0205d291a..ee5b5a3789 100644 --- a/psasim/include/psa/common.h +++ b/psasim/include/psa/common.h @@ -27,7 +27,6 @@ #define NON_SECURE (1 << 30) -typedef int32_t psa_status_t; typedef int32_t psa_handle_t; #define PSA_MAX_IOVEC (4u) diff --git a/psasim/include/psa/error.h b/psasim/include/psa/error.h deleted file mode 100644 index 44fc0b1cbf..0000000000 --- a/psasim/include/psa/error.h +++ /dev/null @@ -1,38 +0,0 @@ -/* PSA status codes used by psasim. */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_ERROR_H -#define PSA_ERROR_H - -#include - -#include "psa/common.h" - -#define PSA_SUCCESS ((psa_status_t) 0) - -#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t) -129) -#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t) -130) -#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t) -131) -#define PSA_ERROR_GENERIC_ERROR ((psa_status_t) -132) -#define PSA_ERROR_NOT_PERMITTED ((psa_status_t) -133) -#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t) -134) -#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t) -135) -#define PSA_ERROR_INVALID_HANDLE ((psa_status_t) -136) -#define PSA_ERROR_BAD_STATE ((psa_status_t) -137) -#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t) -138) -#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t) -139) -#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t) -140) -#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t) -141) -#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t) -142) -#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t) -143) -#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t) -144) -#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t) -145) -#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t) -146) -#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t) -147) -#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t) -149) - -#endif diff --git a/psasim/include/psa/error_ext.h b/psasim/include/psa/error_ext.h new file mode 100644 index 0000000000..efbba864fc --- /dev/null +++ b/psasim/include/psa/error_ext.h @@ -0,0 +1,19 @@ +/* PSA status codes used by psasim. */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef PSA_ERROR_H +#define PSA_ERROR_H + +#include + +#include "psa/common.h" + +#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t) -129) +#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t) -130) +#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t) -131) + +#endif diff --git a/psasim/include/psa/service.h b/psasim/include/psa/service.h index c8c00245ae..b6c968427a 100644 --- a/psasim/include/psa/service.h +++ b/psasim/include/psa/service.h @@ -17,6 +17,8 @@ extern "C" { #include "psa/common.h" +#include "psa/crypto.h" + /********************** PSA Secure Partition Macros and Types ****************/ /* PSA wait timeouts */ diff --git a/psasim/src/Makefile b/psasim/src/Makefile index fc6ba25aab..119971b084 100644 --- a/psasim/src/Makefile +++ b/psasim/src/Makefile @@ -1,4 +1,6 @@ -INCLUDE = -I../include/ +# 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 diff --git a/psasim/src/client.c b/psasim/src/client.c index 5a3986e32c..bd1d5d8813 100644 --- a/psasim/src/client.c +++ b/psasim/src/client.c @@ -19,7 +19,7 @@ #include "psa/client.h" #include "psa/common.h" -#include "psa/error.h" +#include "psa/error_ext.h" #include "psa/util.h" typedef struct internal_handle { diff --git a/psasim/src/service.c b/psasim/src/service.c index b2b6a08f54..69c25a211a 100644 --- a/psasim/src/service.c +++ b/psasim/src/service.c @@ -18,7 +18,7 @@ #include "psa/service.h" #include "psasim/init.h" -#include "psa/error.h" +#include "psa/error_ext.h" #include "psa/common.h" #include "psa/util.h" diff --git a/psasim/test/Makefile b/psasim/test/Makefile index 5afc8f58a2..41f4bd47fc 100644 --- a/psasim/test/Makefile +++ b/psasim/test/Makefile @@ -26,10 +26,10 @@ PARTITION_SERVER_BOOTSTRAP = psa_ff_bootstrap_TEST_PARTITION.c all: $(TEST_BIN) psa_client: client.c $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(LIBPSACLIENT_H) $(CFLAGS) $< $(LIBPSASIM) $(LIBPSACLIENT) -o $@ + $(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) -o $@ + $(CC) $(COMMON_INCLUDE) $(LIBPSASERVER_H) $(CFLAGS) $< $(LIBPSASIM) $(LIBPSASERVER) $(LDFLAGS) -o $@ $(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES): manifest.json server.c ../tools/psa_autogen.py $< diff --git a/psasim/test/client.c b/psasim/test/client.c index 3c61120a11..74e7bcb8d2 100644 --- a/psasim/test/client.c +++ b/psasim/test/client.c @@ -8,11 +8,15 @@ #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__) @@ -20,8 +24,9 @@ int main() { char mbedtls_version[18]; - const char *text = "FOOBARCOOL!!"; - char output[100] = { 0 }; + // psa_invec invecs[1]; + // psa_outvec outvecs[1]; + psa_status_t status; mbedtls_version_get_string_full(mbedtls_version); CLIENT_PRINT("%s", mbedtls_version); @@ -34,23 +39,16 @@ int main() if (h < 0) { CLIENT_PRINT("Couldn't connect %d", h); return 1; - } else { - int type = 2; - CLIENT_PRINT("psa_call() w/o invec returned: %d", psa_call(h, type, NULL, 0, NULL, 0)); - psa_invec invecs[1]; - psa_outvec outvecs[1]; - invecs[0].base = text; - invecs[0].len = sizeof(text); - outvecs[0].base = output; - outvecs[0].len = sizeof(output); - - CLIENT_PRINT("invec len: %lu", invecs[0].len); - CLIENT_PRINT("psa_call() w/ invec returned: %d", psa_call(h, type, invecs, 1, outvecs, 1)); - CLIENT_PRINT("Received payload len: %ld", outvecs[0].len); - CLIENT_PRINT("Received payload content: %s", output); - CLIENT_PRINT("Closing handle"); - psa_close(h); } + 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/psasim/test/manifest.json b/psasim/test/manifest.json index 0ab83ef907..d90c7edbbf 100644 --- a/psasim/test/manifest.json +++ b/psasim/test/manifest.json @@ -3,14 +3,14 @@ "name":"TEST_PARTITION", "type":"PSA-ROT", "priority":"LOW", - "entry_point":"psa_sha256_main", + "entry_point":"psa_server_main", "stack_size":"0x400", "heap_size":"0x100", "services":[ { "name":"PSA_SID_SHA256", "sid":"0x0000F000", - "signal":"PSA_SHA256", + "signal":"PSA_CRYPTO", "non_secure_clients": "true", "minor_version":1, "minor_policy":"STRICT" diff --git a/psasim/test/psa_functions_codes.h b/psasim/test/psa_functions_codes.h new file mode 100644 index 0000000000..34897b91be --- /dev/null +++ b/psasim/test/psa_functions_codes.h @@ -0,0 +1,9 @@ +#ifndef _PSA_FUNCTIONS_CODES_H_ +#define _PSA_FUNCTIONS_CODES_H_ + +enum { + PSA_CRYPTO_INIT = 0x00, + /* Add other PSA functions here */ +}; + +#endif /* _PSA_FUNCTIONS_CODES_H_ */ diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh index 0ffaaea794..6a5605ff5a 100755 --- a/psasim/test/run_test.sh +++ b/psasim/test/run_test.sh @@ -11,7 +11,10 @@ set -e +cd "$(dirname "$0")" + function clean_run() { + rm -f psa_notify_* pkill psa_partition || true pkill psa_client || true ipcs | grep q | awk '{ printf " -q " $$2 }' | xargs ipcrm > /dev/null 2>&1 || true @@ -21,7 +24,7 @@ function clean_run() { # event as signal that the server is ready so that we can start client(s). function wait_for_server_startup() { while [ ! -f ./psa_notify_* ]; do - sleep 0.1 + sleep 0.1 done } diff --git a/psasim/test/server.c b/psasim/test/server.c index 1c873c6c06..b88a7ba8d4 100644 --- a/psasim/test/server.c +++ b/psasim/test/server.c @@ -8,12 +8,16 @@ #include #include +/* Includes from psasim */ #include "psa/service.h" -#include "psa/error.h" +#include "psa/error_ext.h" #include "psa/util.h" #include "psa_manifest/manifest.h" +#include "psa_functions_codes.h" +/* Includes from mbedtls */ #include "mbedtls/version.h" +#include "psa/crypto.h" #define SERVER_PRINT(fmt, ...) \ PRINT("Server: " fmt, ##__VA_ARGS__) @@ -38,11 +42,10 @@ void parse_input_args(int argc, char *argv[]) } } -int psa_sha256_main(int argc, char *argv[]) +int psa_server_main(int argc, char *argv[]) { psa_status_t ret = PSA_ERROR_PROGRAMMER_ERROR; psa_msg_t msg = { -1 }; - char foo[BUF_SIZE] = { 0 }; const int magic_num = 66; int client_disconnected = 0; char mbedtls_version[18]; @@ -60,10 +63,9 @@ int psa_sha256_main(int argc, char *argv[]) SERVER_PRINT("Signals: 0x%08x", signals); } - if (signals & PSA_SHA256_SIGNAL) { - if (PSA_SUCCESS == psa_get(PSA_SHA256_SIGNAL, &msg)) { - SERVER_PRINT("My handle is %d", msg.handle); - SERVER_PRINT("My rhandle is %p", (int *) msg.rhandle); + if (signals & PSA_CRYPTO_SIGNAL) { + if (PSA_SUCCESS == psa_get(PSA_CRYPTO_SIGNAL, &msg)) { + SERVER_PRINT("handle: %d - rhandle: %p", msg.handle, (int *) msg.rhandle); switch (msg.type) { case PSA_IPC_CONNECT: SERVER_PRINT("Got a connection message"); @@ -75,34 +77,23 @@ int psa_sha256_main(int argc, char *argv[]) ret = PSA_SUCCESS; client_disconnected = 1; break; - default: SERVER_PRINT("Got an IPC call of type %d", msg.type); - ret = 42; - size_t size = msg.in_size[0]; - - if ((size > 0) && (size <= sizeof(foo))) { - psa_read(msg.handle, 0, foo, 6); - foo[(BUF_SIZE-1)] = '\0'; - SERVER_PRINT("Reading payload: %s", foo); - psa_read(msg.handle, 0, foo+6, 6); - foo[(BUF_SIZE-1)] = '\0'; - SERVER_PRINT("Reading payload: %s", foo); - } - - size = msg.out_size[0]; - if ((size > 0)) { - SERVER_PRINT("Writing response"); - psa_write(msg.handle, 0, "RESP", 4); - psa_write(msg.handle, 0, "ONSE", 4); + switch (msg.type) { + case PSA_CRYPTO_INIT: + ret = psa_crypto_init(); + break; + default: + SERVER_PRINT("Unknown PSA function code"); + break; } + SERVER_PRINT("Internal function call returned %d", ret); if (msg.client_id > 0) { psa_notify(msg.client_id); } else { SERVER_PRINT("Client is non-secure, so won't notify"); } - } psa_reply(msg.handle, ret); From 2dd47882b9db90c60b328135573ab20d8485f108 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 10 May 2024 06:51:16 +0200 Subject: [PATCH 005/125] crypto-client: reorganize source files/folders The goal is to keep psasim as simple as possible: - do not build a separate lib for psa-ff; build those source files as part of server or client - do not have lot of different makefiles: just 1 that does all we need - do not have several subfolders for headers: only 1 is enough for this kind of project Signed-off-by: Valerio Setti --- psasim/Makefile | 52 ++- psasim/include/{psa => }/client.h | 2 +- psasim/include/{psa => }/common.h | 0 psasim/include/{psa => }/error_ext.h | 2 +- psasim/include/{psasim => }/init.h | 2 +- psasim/include/{psa => }/lifecycle.h | 0 psasim/include/{psa => }/service.h | 2 +- psasim/include/{psa => }/util.h | 2 +- psasim/src/Makefile | 19 - psasim/src/client.c | 402 ++------------------- psasim/src/common.c | 8 - psasim/{test => src}/manifest.json | 0 psasim/src/psa_ff_client.c | 392 ++++++++++++++++++++ psasim/src/{service.c => psa_ff_server.c} | 12 +- psasim/{test => src}/psa_functions_codes.h | 0 psasim/{test => src}/server.c | 6 +- psasim/test/Makefile | 40 -- psasim/test/client.c | 54 --- psasim/tools/psa_autogen.py | 25 +- 19 files changed, 491 insertions(+), 529 deletions(-) rename psasim/include/{psa => }/client.h (98%) rename psasim/include/{psa => }/common.h (100%) rename psasim/include/{psa => }/error_ext.h (94%) rename psasim/include/{psasim => }/init.h (94%) rename psasim/include/{psa => }/lifecycle.h (100%) rename psasim/include/{psa => }/service.h (99%) rename psasim/include/{psa => }/util.h (97%) delete mode 100644 psasim/src/Makefile delete mode 100644 psasim/src/common.c rename psasim/{test => src}/manifest.json (100%) create mode 100644 psasim/src/psa_ff_client.c rename psasim/src/{service.c => psa_ff_server.c} (99%) rename psasim/{test => src}/psa_functions_codes.h (100%) rename psasim/{test => src}/server.c (97%) delete mode 100644 psasim/test/Makefile delete mode 100644 psasim/test/client.c diff --git a/psasim/Makefile b/psasim/Makefile index 50fd0ad11b..45b31960ee 100644 --- a/psasim/Makefile +++ b/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/psasim/include/psa/client.h b/psasim/include/client.h similarity index 98% rename from psasim/include/psa/client.h rename to psasim/include/client.h index 1044c84bbd..d48498e682 100644 --- a/psasim/include/psa/client.h +++ b/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/psasim/include/psa/common.h b/psasim/include/common.h similarity index 100% rename from psasim/include/psa/common.h rename to psasim/include/common.h diff --git a/psasim/include/psa/error_ext.h b/psasim/include/error_ext.h similarity index 94% rename from psasim/include/psa/error_ext.h rename to psasim/include/error_ext.h index efbba864fc..6c82b8a72f 100644 --- a/psasim/include/psa/error_ext.h +++ b/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/psasim/include/psasim/init.h b/psasim/include/init.h similarity index 94% rename from psasim/include/psasim/init.h rename to psasim/include/init.h index 9496fc2a1c..de95d905c7 100644 --- a/psasim/include/psasim/init.h +++ b/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/psasim/include/psa/lifecycle.h b/psasim/include/lifecycle.h similarity index 100% rename from psasim/include/psa/lifecycle.h rename to psasim/include/lifecycle.h diff --git a/psasim/include/psa/service.h b/psasim/include/service.h similarity index 99% rename from psasim/include/psa/service.h rename to psasim/include/service.h index b6c968427a..cbcb918cb2 100644 --- a/psasim/include/psa/service.h +++ b/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/psasim/include/psa/util.h b/psasim/include/util.h similarity index 97% rename from psasim/include/psa/util.h rename to psasim/include/util.h index c3669a125d..558149fe2b 100644 --- a/psasim/include/psa/util.h +++ b/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/psasim/src/Makefile b/psasim/src/Makefile deleted file mode 100644 index 119971b084..0000000000 --- a/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/psasim/src/client.c b/psasim/src/client.c index bd1d5d8813..e8f370d97d 100644 --- a/psasim/src/client.c +++ b/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() -{ - /* 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) +int main() { - { - 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]); - } + char mbedtls_version[18]; + // psa_invec invecs[1]; + // psa_outvec outvecs[1]; + psa_status_t status; - /* Copy outvec sizes */ - for (size_t i = 0; i < (vecs->out_len); i++) { - vec_sizes.outvec_sizes[i] = vecs->out_vec[i].len; + mbedtls_version_get_string_full(mbedtls_version); + CLIENT_PRINT("%s", mbedtls_version); - /* Reset to 0 since we need to eventually fill in with bytes written */ - vecs->out_vec[i].len = 0; - } + CLIENT_PRINT("My PID: %d", getpid()); - memcpy(request.message_text.buf, &vec_sizes, sizeof(vec_sizes)); - request_msg_size = request_msg_size + sizeof(vec_sizes); - } + CLIENT_PRINT("PSA version: %u", psa_version(PSA_SID_SHA256_SID)); + psa_handle_t h = psa_connect(PSA_SID_SHA256_SID, 1); - 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); + if (h < 0) { + CLIENT_PRINT("Couldn't connect %d", h); + return 1; } -} - - -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); + status = psa_call(h, PSA_CRYPTO_INIT, NULL, 0, NULL, 0); + CLIENT_PRINT("PSA_CRYPTO_INIT returned: %d", status); - /* if communication is possible */ - if (get_queue_info(pathname, &handles[idx].client_qid, &handles[idx].server_qid) >= 0) { + CLIENT_PRINT("Closing handle"); + psa_close(h); - 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); + if (status != PSA_SUCCESS) { + return 1; } - - 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; + return 0; } diff --git a/psasim/src/common.c b/psasim/src/common.c deleted file mode 100644 index 287bb504ae..0000000000 --- a/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/psasim/test/manifest.json b/psasim/src/manifest.json similarity index 100% rename from psasim/test/manifest.json rename to psasim/src/manifest.json diff --git a/psasim/src/psa_ff_client.c b/psasim/src/psa_ff_client.c new file mode 100644 index 0000000000..bc2989ffae --- /dev/null +++ b/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/psasim/src/service.c b/psasim/src/psa_ff_server.c similarity index 99% rename from psasim/src/service.c rename to psasim/src/psa_ff_server.c index 69c25a211a..ea797d8ced 100644 --- a/psasim/src/service.c +++ b/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/psasim/test/psa_functions_codes.h b/psasim/src/psa_functions_codes.h similarity index 100% rename from psasim/test/psa_functions_codes.h rename to psasim/src/psa_functions_codes.h diff --git a/psasim/test/server.c b/psasim/src/server.c similarity index 97% rename from psasim/test/server.c rename to psasim/src/server.c index b88a7ba8d4..630bd7392c 100644 --- a/psasim/test/server.c +++ b/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/psasim/test/Makefile b/psasim/test/Makefile deleted file mode 100644 index 41f4bd47fc..0000000000 --- a/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/psasim/test/client.c b/psasim/test/client.c deleted file mode 100644 index 74e7bcb8d2..0000000000 --- a/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/psasim/tools/psa_autogen.py b/psasim/tools/psa_autogen.py index 53b1fea746..cece2b793e 100755 --- a/psasim/tools/psa_autogen.py +++ b/psasim/tools/psa_autogen.py @@ -15,6 +15,9 @@ 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 @@ 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 @@ 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 @@ 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) From e1f5632986d28613c1bed838f8138f97e9563274 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 10 May 2024 11:21:04 +0200 Subject: [PATCH 006/125] crypto-client: simplify build of mbedtls static libraries Instead of copying the entire library & include folders twice to build libraries for client and server: - change the main config file (mbedtls_config.h) - build in the root library folder - move the generated library in the psasim folder - use those library for linking the client/server binaries Signed-off-by: Valerio Setti --- psasim/Makefile | 31 +++++---- psasim/include/crypto_spe.h | 131 ------------------------------------ 2 files changed, 19 insertions(+), 143 deletions(-) delete mode 100644 psasim/include/crypto_spe.h diff --git a/psasim/Makefile b/psasim/Makefile index 45b31960ee..29afca16df 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -4,16 +4,11 @@ ifeq ($(DEBUG),1) CFLAGS += -DDEBUG endif -LIBPSACLIENT_PATH := ../../libpsaclient -LIBPSASERVER_PATH := ../../libpsaserver +LIBPSACLIENT := -Llibpsaclient/ -lmbedcrypto -lmbedx509 -lmbedtls +LIBPSASERVER := -Llibpsaserver/ -lmbedcrypto -LIBPSACLIENT := -L$(LIBPSACLIENT_PATH)/library -lmbedcrypto -lmbedx509 -lmbedtls -LIBPSASERVER := -L$(LIBPSASERVER_PATH)/library -lmbedcrypto - -LIBPSACLIENT_H := -I$(LIBPSACLIENT_PATH)/include -LIBPSASERVER_H := -I$(LIBPSASERVER_PATH)/include - -COMMON_INCLUDE := -I./include +MBEDTLS_ROOT_PATH = ../../.. +COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include TEST_BIN = test/psa_client \ test/psa_partition @@ -30,22 +25,34 @@ PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ src/psa_ff_server.c -.PHONY: all clean +.PHONY: all clean libpsaclient libpsaserver all: $(TEST_BIN) test/psa_client: $(PSA_CLIENT_SRC) $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(LIBPSACLIENT_H) $(CFLAGS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ + $(CC) $(COMMON_INCLUDE) $(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 $@ + $(CC) $(COMMON_INCLUDE) $(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 +# Build MbedTLS libraries (crypto, x509 and tls) and copy them locally to +# build client/server applications. +# +# Note: these rules assume that mbedtls_config.h is already configured by all.sh. +# If not using all.sh then the user must do it manually. +libpsaclient libpsaserver: + $(MAKE) -C $(MBEDTLS_ROOT_PATH)/library CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" libmbedcrypto.a libmbedx509.a libmbedtls.a + mkdir -p $@ + cp $(MBEDTLS_ROOT_PATH)/library/libmbed*.a $@/ + $(MAKE) -C $(MBEDTLS_ROOT_PATH) clean + clean: rm -f $(TEST_BIN) rm -f $(PARTITION_SERVER_BOOTSTRAP) + rm -rf libpsaclient libpsaserver rm -rf include/psa_manifest rm -f test/psa_service_* test/psa_notify_* diff --git a/psasim/include/crypto_spe.h b/psasim/include/crypto_spe.h deleted file mode 100644 index fdf3a2db5a..0000000000 --- a/psasim/include/crypto_spe.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - */ - -/** - * \file crypto_spe.h - * - * \brief When Mbed TLS is built with the MBEDTLS_PSA_CRYPTO_SPM option - * enabled, this header is included by all .c files in Mbed TLS that - * use PSA Crypto function names. This avoids duplication of symbols - * between TF-M and Mbed TLS. - * - * \note This file should be included before including any PSA Crypto headers - * from Mbed TLS. - */ - -#ifndef CRYPTO_SPE_H -#define CRYPTO_SPE_H - -#define PSA_FUNCTION_NAME(x) mbedcrypto__ ## x - -#define psa_crypto_init \ - PSA_FUNCTION_NAME(psa_crypto_init) -#define psa_key_derivation_get_capacity \ - PSA_FUNCTION_NAME(psa_key_derivation_get_capacity) -#define psa_key_derivation_set_capacity \ - PSA_FUNCTION_NAME(psa_key_derivation_set_capacity) -#define psa_key_derivation_input_bytes \ - PSA_FUNCTION_NAME(psa_key_derivation_input_bytes) -#define psa_key_derivation_output_bytes \ - PSA_FUNCTION_NAME(psa_key_derivation_output_bytes) -#define psa_key_derivation_input_key \ - PSA_FUNCTION_NAME(psa_key_derivation_input_key) -#define psa_key_derivation_output_key \ - PSA_FUNCTION_NAME(psa_key_derivation_output_key) -#define psa_key_derivation_setup \ - PSA_FUNCTION_NAME(psa_key_derivation_setup) -#define psa_key_derivation_abort \ - PSA_FUNCTION_NAME(psa_key_derivation_abort) -#define psa_key_derivation_key_agreement \ - PSA_FUNCTION_NAME(psa_key_derivation_key_agreement) -#define psa_raw_key_agreement \ - PSA_FUNCTION_NAME(psa_raw_key_agreement) -#define psa_generate_random \ - PSA_FUNCTION_NAME(psa_generate_random) -#define psa_aead_encrypt \ - PSA_FUNCTION_NAME(psa_aead_encrypt) -#define psa_aead_decrypt \ - PSA_FUNCTION_NAME(psa_aead_decrypt) -#define psa_open_key \ - PSA_FUNCTION_NAME(psa_open_key) -#define psa_close_key \ - PSA_FUNCTION_NAME(psa_close_key) -#define psa_import_key \ - PSA_FUNCTION_NAME(psa_import_key) -#define psa_destroy_key \ - PSA_FUNCTION_NAME(psa_destroy_key) -#define psa_get_key_attributes \ - PSA_FUNCTION_NAME(psa_get_key_attributes) -#define psa_reset_key_attributes \ - PSA_FUNCTION_NAME(psa_reset_key_attributes) -#define psa_export_key \ - PSA_FUNCTION_NAME(psa_export_key) -#define psa_export_public_key \ - PSA_FUNCTION_NAME(psa_export_public_key) -#define psa_purge_key \ - PSA_FUNCTION_NAME(psa_purge_key) -#define psa_copy_key \ - PSA_FUNCTION_NAME(psa_copy_key) -#define psa_cipher_operation_init \ - PSA_FUNCTION_NAME(psa_cipher_operation_init) -#define psa_cipher_generate_iv \ - PSA_FUNCTION_NAME(psa_cipher_generate_iv) -#define psa_cipher_set_iv \ - PSA_FUNCTION_NAME(psa_cipher_set_iv) -#define psa_cipher_encrypt_setup \ - PSA_FUNCTION_NAME(psa_cipher_encrypt_setup) -#define psa_cipher_decrypt_setup \ - PSA_FUNCTION_NAME(psa_cipher_decrypt_setup) -#define psa_cipher_update \ - PSA_FUNCTION_NAME(psa_cipher_update) -#define psa_cipher_finish \ - PSA_FUNCTION_NAME(psa_cipher_finish) -#define psa_cipher_abort \ - PSA_FUNCTION_NAME(psa_cipher_abort) -#define psa_hash_operation_init \ - PSA_FUNCTION_NAME(psa_hash_operation_init) -#define psa_hash_setup \ - PSA_FUNCTION_NAME(psa_hash_setup) -#define psa_hash_update \ - PSA_FUNCTION_NAME(psa_hash_update) -#define psa_hash_finish \ - PSA_FUNCTION_NAME(psa_hash_finish) -#define psa_hash_verify \ - PSA_FUNCTION_NAME(psa_hash_verify) -#define psa_hash_abort \ - PSA_FUNCTION_NAME(psa_hash_abort) -#define psa_hash_clone \ - PSA_FUNCTION_NAME(psa_hash_clone) -#define psa_hash_compute \ - PSA_FUNCTION_NAME(psa_hash_compute) -#define psa_hash_compare \ - PSA_FUNCTION_NAME(psa_hash_compare) -#define psa_mac_operation_init \ - PSA_FUNCTION_NAME(psa_mac_operation_init) -#define psa_mac_sign_setup \ - PSA_FUNCTION_NAME(psa_mac_sign_setup) -#define psa_mac_verify_setup \ - PSA_FUNCTION_NAME(psa_mac_verify_setup) -#define psa_mac_update \ - PSA_FUNCTION_NAME(psa_mac_update) -#define psa_mac_sign_finish \ - PSA_FUNCTION_NAME(psa_mac_sign_finish) -#define psa_mac_verify_finish \ - PSA_FUNCTION_NAME(psa_mac_verify_finish) -#define psa_mac_abort \ - PSA_FUNCTION_NAME(psa_mac_abort) -#define psa_sign_hash \ - PSA_FUNCTION_NAME(psa_sign_hash) -#define psa_verify_hash \ - PSA_FUNCTION_NAME(psa_verify_hash) -#define psa_asymmetric_encrypt \ - PSA_FUNCTION_NAME(psa_asymmetric_encrypt) -#define psa_asymmetric_decrypt \ - PSA_FUNCTION_NAME(psa_asymmetric_decrypt) -#define psa_generate_key \ - PSA_FUNCTION_NAME(psa_generate_key) - -#endif /* CRYPTO_SPE_H */ From 9ce819382cf08f9682ec5691801dc53634952c28 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 10 May 2024 12:31:41 +0200 Subject: [PATCH 007/125] crypto-client: fix the SID Signed-off-by: Valerio Setti --- psasim/src/client.c | 4 ++-- psasim/src/manifest.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/psasim/src/client.c b/psasim/src/client.c index e8f370d97d..550a6e869d 100644 --- a/psasim/src/client.c +++ b/psasim/src/client.c @@ -33,8 +33,8 @@ int main() 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); + CLIENT_PRINT("PSA version: %u", psa_version(PSA_SID_CRYPTO_SID)); + psa_handle_t h = psa_connect(PSA_SID_CRYPTO_SID, 1); if (h < 0) { CLIENT_PRINT("Couldn't connect %d", h); diff --git a/psasim/src/manifest.json b/psasim/src/manifest.json index d90c7edbbf..e67b636c17 100644 --- a/psasim/src/manifest.json +++ b/psasim/src/manifest.json @@ -8,7 +8,7 @@ "heap_size":"0x100", "services":[ { - "name":"PSA_SID_SHA256", + "name":"PSA_SID_CRYPTO", "sid":"0x0000F000", "signal":"PSA_CRYPTO", "non_secure_clients": "true", From 977ba09dc247bb07d51e85982248ec49c972aaca Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 10 May 2024 12:32:10 +0200 Subject: [PATCH 008/125] crypto-client: remove log files on "make clean" Signed-off-by: Valerio Setti --- psasim/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/psasim/Makefile b/psasim/Makefile index 29afca16df..583f1b9b70 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -55,4 +55,5 @@ clean: rm -rf libpsaclient libpsaserver rm -rf include/psa_manifest rm -f test/psa_service_* test/psa_notify_* + rm -r test/*.log From e8c8fc6ef09dadfea423efa72fdd9123c396b45a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 10 May 2024 15:53:40 +0200 Subject: [PATCH 009/125] crypto-client: allow debug build of libraries and test binaries Add DEBUG=1 in test_psasim() to helpers and final make to build the libraries and the final binaries with debug symbols enabled. Signed-off-by: Valerio Setti --- psasim/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/Makefile b/psasim/Makefile index 583f1b9b70..01e3486b65 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -1,7 +1,7 @@ CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L ifeq ($(DEBUG),1) - CFLAGS += -DDEBUG +CFLAGS += -DDEBUG -O0 -g endif LIBPSACLIENT := -Llibpsaclient/ -lmbedcrypto -lmbedx509 -lmbedtls From f917802a044e5933d8ac7fd5760cf7723437e905 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 14 May 2024 10:43:14 +0200 Subject: [PATCH 010/125] psa_ff_client: fix typos and useless blank lines Signed-off-by: Valerio Setti --- psasim/src/psa_ff_client.c | 98 ++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 52 deletions(-) diff --git a/psasim/src/psa_ff_client.c b/psasim/src/psa_ff_client.c index bc2989ffae..21a43b39dd 100644 --- a/psasim/src/psa_ff_client.c +++ b/psasim/src/psa_ff_client.c @@ -67,7 +67,6 @@ static int handle_is_valid(psa_handle_t handle) static int get_queue_info(char *path, int *cqid, int *sqid) { - key_t server_queue_key; int rx_qid, server_qid; @@ -97,7 +96,6 @@ static int get_queue_info(char *path, int *cqid, int *sqid) 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 }; @@ -111,13 +109,13 @@ static psa_status_t process_response(int rx_qid, vectors_t *vecs, int type, invec = 0; outvec = 0; - // read response from server + /* 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 + /* process return message from server */ switch (response.message_type) { case PSA_REPLY: memcpy(&ret, response.message_text.buf, sizeof(psa_status_t)); @@ -209,66 +207,64 @@ static psa_status_t process_response(int rx_qid, vectors_t *vecs, int type, 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; - } + 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); + 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); + 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; + 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 (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) { + if (vecs != NULL && type >= PSA_IPC_CALL) { - memset(&vec_sizes, 0, sizeof(vec_sizes)); + 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; + /* 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]); + } - /* Reset to 0 since we need to eventually fill in with bytes written */ - vecs->out_vec[i].len = 0; - } + /* Copy outvec sizes */ + for (size_t i = 0; i < (vecs->out_len); i++) { + vec_sizes.outvec_sizes[i] = vecs->out_vec[i].len; - memcpy(request.message_text.buf, &vec_sizes, sizeof(vec_sizes)); - request_msg_size = request_msg_size + sizeof(vec_sizes); + /* Reset to 0 since we need to eventually fill in with bytes written */ + vecs->out_vec[i].len = 0; } - INFO(" Sending and then waiting"); + memcpy(request.message_text.buf, &vec_sizes, sizeof(vec_sizes)); + request_msg_size = request_msg_size + sizeof(vec_sizes); + } - // send message to server - if (msgsnd(server_qid, &request, request_msg_size, 0) == -1) { - ERROR(" msgsnd failed"); - return ret; - } + INFO(" Sending and then waiting"); - return process_response(rx_qid, vecs, type, internal_server_qid); + /* 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); } @@ -279,7 +275,6 @@ uint32_t psa_framework_version(void) psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version) { - int idx; psa_status_t ret; char pathname[PATHNAMESIZE] = { 0 }; @@ -355,7 +350,6 @@ psa_status_t psa_call(psa_handle_t handle, psa_outvec *out_vec, size_t out_len) { - handle_is_valid(handle); if ((in_len + out_len) > PSA_MAX_IOVEC) { From 3ccf2b81b94b7810df1c934ef7cf9b22cc491aef Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 14 May 2024 10:57:35 +0200 Subject: [PATCH 011/125] psasim: create a seedfile to be used for the crypto server This allows to re-enable MBEDTLS_ENTROPY_NV_SEED since the seedfile is correctly found in the "test" folder at runtime. Signed-off-by: Valerio Setti --- psasim/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/psasim/Makefile b/psasim/Makefile index 01e3486b65..396f5ad3f0 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -29,10 +29,13 @@ PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ all: $(TEST_BIN) +test/seedfile: + dd if=/dev/urandom of=./test/seedfile bs=64 count=1 + test/psa_client: $(PSA_CLIENT_SRC) $(GENERATED_H_FILES) $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ -test/psa_partition: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) +test/psa_partition: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) test/seedfile $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_SERVER_SRC) $(LIBPSASERVER) $(LDFLAGS) -o $@ $(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES): src/manifest.json src/server.c @@ -56,4 +59,5 @@ clean: rm -rf include/psa_manifest rm -f test/psa_service_* test/psa_notify_* rm -r test/*.log + rm test/seedfile From f048bb74644a74e846abd5219747a683e0e1176a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 15 May 2024 07:29:51 +0200 Subject: [PATCH 012/125] psa_autogen.py: improve management of output files While at this, fix also Makefile so that "make clean" does not complain if some of the files to be cancelled do not exist. Signed-off-by: Valerio Setti --- psasim/Makefile | 5 ++- psasim/tools/psa_autogen.py | 64 +++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/psasim/Makefile b/psasim/Makefile index 396f5ad3f0..db0c4127f4 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -58,6 +58,5 @@ clean: rm -rf libpsaclient libpsaserver rm -rf include/psa_manifest rm -f test/psa_service_* test/psa_notify_* - rm -r test/*.log - rm test/seedfile - + rm -f test/*.log + rm -f test/seedfile diff --git a/psasim/tools/psa_autogen.py b/psasim/tools/psa_autogen.py index cece2b793e..fbc98060fe 100755 --- a/psasim/tools/psa_autogen.py +++ b/psasim/tools/psa_autogen.py @@ -19,6 +19,10 @@ GENERATED_H_PATH = os.path.join(SCRIPT_PATH, "..", "include", "psa_manifest") GENERATED_C_PATH = os.path.join(SCRIPT_PATH, "..", "src") +MANIFEST_FILE = os.path.join(GENERATED_H_PATH, "manifest.h") +PID_FILE = os.path.join(GENERATED_H_PATH, "pid.h") +SID_FILE = os.path.join(GENERATED_H_PATH, "sid.h") + with open(str(FILENAME), "r") as read_file: data = json.load(read_file) FILENAME = os.path.basename(FILENAME) @@ -38,11 +42,11 @@ os.mkdir(GENERATED_H_PATH) print("Generating psa_manifest directory") except OSError: - print ("PSA manifest directory already exists") + print("PSA manifest directory already exists") - 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") + manifest_content = [] + pids_content = [] + sids_content = [] if len(services) > 28: print ("Unsupported number of services") @@ -63,8 +67,8 @@ # Go through all the services to make sid.h and pid.h for svc in services: - man.write("#define {}_SIGNAL 0x{:08x}\n".format(svc['signal'], 2**count)) - sids.write("#define {}_SID {}\n".format(svc['name'], svc['sid'])) + manifest_content.append("#define {}_SIGNAL 0x{:08x}".format(svc['signal'], 2**count)) + sids_content.append("#define {}_SID {}".format(svc['name'], svc['sid'])) qcode = qcode + "\"" + queue_path + str(int(svc['sid'], 16)) + "\"," ns_clients = svc['non_secure_clients'] print(str(svc)) @@ -94,7 +98,7 @@ handlercode = "void __sig_handler(int signo) {\n" irqcount = count for irq in irqs: - man.write("#define {} 0x{:08x}\n".format(irq['signal'], 2**irqcount)) + manifest_content.append("#define {} 0x{:08x}".format(irq['signal'], 2**irqcount)) sigcode = sigcode + " signal({}, __sig_handler);\n".format(irq['source']) handlercode = handlercode + \ " if (signo == {}) {{ raise_signal(0x{:08x}); }};\n".format(irq['source'], 2**irqcount) @@ -114,9 +118,12 @@ versions = versions + "};\n" policy = policy + "};\n" - pids.close() - sids.close() - man.close() + with open(MANIFEST_FILE, "wt") as output: + output.write("\n".join(manifest_content)) + with open(SID_FILE, "wt") as output: + output.write("\n".join(sids_content)) + with open(PID_FILE, "wt") as output: + output.write("\n".join(pids_content)) symbols = [] @@ -144,23 +151,24 @@ print("Duplicate entrypoint symbol detected: " + str(symbols)) sys.exit(2) else: - 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) - bs.write(nsacl) - bs.write(policy) - bs.write(versions) - bs.write("\n") - bs.write(handlercode) - bs.write("\n") - bs.write("int main(int argc, char *argv[]) {\n") - bs.write(" (void) argc;\n") - bs.write(sigcode) - bs.write(" __init_psasim(psa_queues, 32, ns_allowed, versions, strict_policy);\n") - bs.write(" " + entry_point + "(argc, argv);\n}\n") - bs.close() + C_FILENAME = os.path.join(GENERATED_C_PATH, "psa_ff_bootstrap_" + partition_name + ".c") + c_content = [] + c_content.append("#include ") + c_content.append("#include \"" + symbols[0] + "\"") + c_content.append("#include ") + c_content.append(qcode) + c_content.append(nsacl) + c_content.append(policy) + c_content.append(versions) + c_content.append(handlercode) + c_content.append("int main(int argc, char *argv[]) {") + c_content.append(" (void) argc;") + c_content.append(sigcode) + c_content.append(" __init_psasim(psa_queues, 32, ns_allowed, versions," + "strict_policy);") + c_content.append(" " + entry_point + "(argc, argv);") + c_content.append("}") + with open(C_FILENAME, "wt") as output: + output.write("\n".join(c_content)) print("Success") From 1bd3e3b6b767429b9cbe109a4576625617807473 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 27 May 2024 10:08:34 +0300 Subject: [PATCH 013/125] Replace final sprintf() with snprintf() in psa_ff_server.c Signed-off-by: Tom Cosgrove --- psasim/src/psa_ff_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index ea797d8ced..7c72ee7022 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -638,7 +638,7 @@ void __init_psasim(const char **array, if (strncmp(array[i], "", 1) != 0) { INFO("Setting up %s", array[i]); memset(queue_path, 0, sizeof(queue_path)); - sprintf(queue_path, "%s%s", TMP_FILE_BASE_PATH, array[i]); + snprintf(queue_path, sizeof(queue_path), "%s%s", TMP_FILE_BASE_PATH, array[i]); /* Create file if doesn't exist */ fp = fopen(queue_path, "ab+"); From 2f29f2735cb34e725a00f19e6bf5453ae0a44322 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 27 May 2024 19:29:16 +0300 Subject: [PATCH 014/125] Fix psa_ff_server.c to calculate the amount of data from client correctly Signed-off-by: Tom Cosgrove --- psasim/src/psa_ff_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index 7c72ee7022..9a457f469e 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -426,7 +427,7 @@ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx, assert(idx >= 0); len = msgrcv(connections[idx].client_to_server_q, &msg, sizeof(struct message_text), 0, 0); - len = (len - sizeof(msg.message_text.qid)); + len = (len - offsetof(struct message_text, buf)); if (len < 0) { FATAL("Internal error: failed to dispatch read request to the client"); From e0d0940ae21139ea1d44464f67fd26e419079261 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 27 May 2024 23:55:43 +0300 Subject: [PATCH 015/125] Fix PSA sim test awk script by removing extra $ Signed-off-by: Tom Cosgrove --- psasim/test/run_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh index 6a5605ff5a..06bcc93a82 100755 --- a/psasim/test/run_test.sh +++ b/psasim/test/run_test.sh @@ -17,7 +17,7 @@ function clean_run() { rm -f psa_notify_* pkill psa_partition || true pkill psa_client || true - ipcs | grep q | awk '{ printf " -q " $$2 }' | xargs ipcrm > /dev/null 2>&1 || true + ipcs | grep q | awk '{ printf " -q " $2 }' | xargs ipcrm > /dev/null 2>&1 || true } # The server creates some local files when it starts up so we can wait for this From c4cc08d8443e12bc12c486542f4855fb6db3c342 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 28 May 2024 14:01:04 +0300 Subject: [PATCH 016/125] Fix sending a response of more than 184 bytes in psa_ff_server.c:psa_write() Signed-off-by: Tom Cosgrove --- psasim/src/psa_ff_server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index 9a457f469e..75a8af5e74 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -479,9 +479,9 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, sending = MAX_FRAGMENT_SIZE - (sizeof(size_t) * 2); } - INFO("Server: sending %lu bytes to client", sending); + INFO("Server: sending %lu bytes to client, sofar = %lu", sending, (long)sofar); - send_msg(msg_handle, WRITE_REQUEST, outvec_idx, sending, buffer, sending); + send_msg(msg_handle, WRITE_REQUEST, outvec_idx, sending, buffer + sofar, sending); idx = find_connection(message_client[msg_handle]); assert(idx >= 0); @@ -490,7 +490,7 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, if (len < 1) { FATAL("Client didn't give me a full response"); } - sofar = sofar + len; + sofar = sofar + sending; } /* Update the seek count */ From 1bb0751492a142f248834f8168a1ef819b7d41a8 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 28 May 2024 14:07:10 +0300 Subject: [PATCH 017/125] Only print PSA crypto sim server messages when DEBUG defined Signed-off-by: Tom Cosgrove --- psasim/src/server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/psasim/src/server.c b/psasim/src/server.c index 630bd7392c..21b65c709e 100644 --- a/psasim/src/server.c +++ b/psasim/src/server.c @@ -19,8 +19,12 @@ #include "mbedtls/version.h" #include "psa/crypto.h" +#ifdef DEBUG #define SERVER_PRINT(fmt, ...) \ PRINT("Server: " fmt, ##__VA_ARGS__) +#else +#define SERVER_PRINT(...) +#endif #define BUF_SIZE 25 From 04a8773c09ab1ac102306c87b5e1e0350b4708b1 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 28 May 2024 14:15:16 +0300 Subject: [PATCH 018/125] Remove unnecessary blank lines at top of functions in psa_ff_server.c Signed-off-by: Tom Cosgrove --- psasim/src/psa_ff_server.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index 75a8af5e74..16e6058f3b 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -455,7 +455,6 @@ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx, void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, const void *buffer, size_t num_bytes) { - size_t sofar = 0; struct message msg = { 0 }; int idx; @@ -499,7 +498,6 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes) { - is_valid_msg_handle(msg_handle); is_call_msg(msg_handle); @@ -512,7 +510,6 @@ size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes) static void destroy_temporary_queue(int myqid) { - if (msgctl(myqid, IPC_RMID, NULL) != 0) { INFO("ERROR: Failed to delete msg queue %d", myqid); } @@ -614,7 +611,6 @@ void __init_psasim(const char **array, const uint32_t versions[32], const int strict_policy_array[32]) { - static uint8_t library_initialised = 0; key_t key; int qid; From 10e0b2d7498471e25c79ff4603e1027b185cb96e Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 09:58:56 +0100 Subject: [PATCH 019/125] Fix code style in psa_ff_server.c Signed-off-by: Tom Cosgrove --- psasim/src/psa_ff_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index 16e6058f3b..219722ad61 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -478,7 +478,7 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, sending = MAX_FRAGMENT_SIZE - (sizeof(size_t) * 2); } - INFO("Server: sending %lu bytes to client, sofar = %lu", sending, (long)sofar); + INFO("Server: sending %lu bytes to client, sofar = %lu", sending, (long) sofar); send_msg(msg_handle, WRITE_REQUEST, outvec_idx, sending, buffer + sofar, sending); From 161e759e7de68e558edc4e79d35df6d45df904e3 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 10:03:06 +0100 Subject: [PATCH 020/125] Add PSA crypto sim serialisation functions for basic types Not hooked into the build yet Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_serialise.c | 321 +++++++++++++++ psasim/src/psa_sim_serialise.h | 272 +++++++++++++ psasim/src/psa_sim_serialise.pl | 682 ++++++++++++++++++++++++++++++++ 3 files changed, 1275 insertions(+) create mode 100644 psasim/src/psa_sim_serialise.c create mode 100644 psasim/src/psa_sim_serialise.h create mode 100644 psasim/src/psa_sim_serialise.pl diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c new file mode 100644 index 0000000000..7caf4e595e --- /dev/null +++ b/psasim/src/psa_sim_serialise.c @@ -0,0 +1,321 @@ +/** + * \file psa_sim_serialise.c + * + * \brief Rough-and-ready serialisation and deserialisation for the PSA Crypto simulator + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa_sim_serialise.h" +#include +#include + +/* Basic idea: + * + * All arguments to a function will be serialised into a single buffer to + * be sent to the server with the PSA crypto function to be called. + * + * All returned data (the function's return value and any values returned + * via `out` parameters) will similarly be serialised into a buffer to be + * sent back to the client from the server. + * + * For each data type foo (e.g. int, size_t, psa_algorithm_t, but also "buffer" + * where "buffer" is a (uint8_t *, size_t) pair, we have a pair of functions, + * psasim_serialise_foo() and psasim_deserialise_foo(). + * + * We also have psasim_serialise_foo_needs() functions, which return a + * size_t giving the number of bytes that serialising that instance of that + * type will need. This allows callers to size buffers for serialisation. + * + * Each serialised buffer starts with a version byte, bytes that indicate + * the size of basic C types, and four bytes that indicate the endianness + * (to avoid incompatibilities if we ever run this over a network - we are + * not aiming for universality, just for correctness and simplicity). + * + * Most types are serialised as a fixed-size (per type) octet string, with + * no type indication. This is acceptable as (a) this is for the test PSA crypto + * simulator only, not production, and (b) these functions are called by + * code that itself is written by script. + * + * We also want to keep serialised data reasonably compact as communication + * between client and server goes in messages of less than 200 bytes each. + * + * Many serialisation functions can be created by a script; an exemplar Perl + * script is included. It is not hooked into the build and so must be run + * manually, but is expected to be replaced by a Python script in due course. + * Types that can have their functions created by script include plain old C + * data types (e.g. int), types typedef'd to those, and even structures that + * don't contain pointers. + */ + +size_t psasim_serialise_begin_needs(void) +{ + /* The serialisation buffer will + * start with a byte of 0 to indicate version 0, + * then have 1 byte each for length of int, long, void *, + * then have 4 bytes to indicate endianness. */ + return 4 + sizeof(uint32_t); +} + +int psasim_serialise_begin(uint8_t **pos, size_t *remaining) +{ + uint32_t endian = 0x1234; + + if (*remaining < 4 + sizeof(endian)) { + return 0; + } + + *(*pos)++ = 0; /* version */ + *(*pos)++ = (uint8_t) sizeof(int); + *(*pos)++ = (uint8_t) sizeof(long); + *(*pos)++ = (uint8_t) sizeof(void *); + + memcpy(*pos, &endian, sizeof(endian)); + + *pos += sizeof(endian); + + return 1; +} + +int psasim_deserialise_begin(uint8_t **pos, size_t *remaining) +{ + uint8_t version = 255; + uint8_t int_size = 0; + uint8_t long_size = 0; + uint8_t ptr_size = 0; + uint32_t endian; + + if (*remaining < 4 + sizeof(endian)) { + return 0; + } + + memcpy(&version, (*pos)++, sizeof(version)); + if (version != 0) { + return 0; + } + + memcpy(&int_size, (*pos)++, sizeof(int_size)); + if (int_size != sizeof(int)) { + return 0; + } + + memcpy(&long_size, (*pos)++, sizeof(long_size)); + if (long_size != sizeof(long)) { + return 0; + } + + memcpy(&ptr_size, (*pos)++, sizeof(ptr_size)); + if (ptr_size != sizeof(void *)) { + return 0; + } + + *remaining -= 4; + + memcpy(&endian, *pos, sizeof(endian)); + if (endian != 0x1234) { + return 0; + } + + *pos += sizeof(endian); + *remaining -= sizeof(endian); + + return 1; +} + +size_t psasim_serialise_unsigned_int_needs(unsigned int value) +{ + return sizeof(value); +} + +int psasim_serialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_serialise_int_needs(int value) +{ + return sizeof(value); +} + +int psasim_serialise_int(uint8_t **pos, size_t *remaining, int value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_int(uint8_t **pos, size_t *remaining, int *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_serialise_size_t_needs(size_t value) +{ + return sizeof(value); +} + +int psasim_serialise_size_t(uint8_t **pos, size_t *remaining, size_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_size_t(uint8_t **pos, size_t *remaining, size_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_serialise_buffer_needs(const uint8_t *buffer, size_t buffer_size) +{ + (void) buffer; + return sizeof(buffer_size) + buffer_size; +} + +int psasim_serialise_buffer(uint8_t **pos, + size_t *remaining, + const uint8_t *buffer, + size_t buffer_length) +{ + if (*remaining < sizeof(buffer_length) + buffer_length) { + return 0; + } + + memcpy(*pos, &buffer_length, sizeof(buffer_length)); + *pos += sizeof(buffer_length); + + if (buffer_length > 0) { // To be able to serialise (NULL, 0) + memcpy(*pos, buffer, buffer_length); + *pos += buffer_length; + } + + return 1; +} + +int psasim_deserialise_buffer(uint8_t **pos, + size_t *remaining, + uint8_t **buffer, + size_t *buffer_length) +{ + if (*remaining < sizeof(*buffer_length)) { + return 0; + } + + memcpy(buffer_length, *pos, sizeof(*buffer_length)); + + *pos += sizeof(buffer_length); + *remaining -= sizeof(buffer_length); + + if (*buffer_length == 0) { // Deserialise (NULL, 0) + *buffer = NULL; + return 1; + } + + if (*remaining < *buffer_length) { + return 0; + } + + uint8_t *data = malloc(*buffer_length); + if (data == NULL) { + return 0; + } + + memcpy(data, *pos, *buffer_length); + *pos += *buffer_length; + *remaining -= *buffer_length; + + *buffer = data; + + return 1; +} + +/* When the client is deserialising a buffer returned from the server, it needs + * to use this function to deserialised the returned buffer. It should use the + * usual \c psasim_serialise_buffer() function to serialise the outbound + * buffer. */ +int psasim_deserialise_return_buffer(uint8_t **pos, + size_t *remaining, + uint8_t *buffer, + size_t buffer_length) +{ + if (*remaining < sizeof(buffer_length)) { + return 0; + } + + size_t length_check; + + memcpy(&length_check, *pos, sizeof(buffer_length)); + + *pos += sizeof(buffer_length); + *remaining -= sizeof(buffer_length); + + if (buffer_length != length_check) { // Make sure we're sent back the same we sent to the server + return 0; + } + + if (length_check == 0) { // Deserialise (NULL, 0) + return 1; + } + + if (*remaining < buffer_length) { + return 0; + } + + memcpy(buffer, *pos, buffer_length); + *pos += buffer_length; + *remaining -= buffer_length; + + return 1; +} diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h new file mode 100644 index 0000000000..4ae0253f4a --- /dev/null +++ b/psasim/src/psa_sim_serialise.h @@ -0,0 +1,272 @@ +/** + * \file psa_sim_serialise.h + * + * \brief Rough-and-ready serialisation and deserialisation for the PSA Crypto simulator + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include +#include + +#include "psa/crypto.h" +#include "psa/crypto_types.h" +#include "psa/crypto_values.h" + +/* Basic idea: + * + * All arguments to a function will be serialised into a single buffer to + * be sent to the server with the PSA crypto function to be called. + * + * All returned data (the function's return value and any values returned + * via `out` parameters) will similarly be serialised into a buffer to be + * sent back to the client from the server. + * + * For each data type foo (e.g. int, size_t, psa_algorithm_t, but also "buffer" + * where "buffer" is a (uint8_t *, size_t) pair, we have a pair of functions, + * psasim_serialise_foo() and psasim_deserialise_foo(). + * + * We also have psasim_serialise_foo_needs() functions, which return a + * size_t giving the number of bytes that serialising that instance of that + * type will need. This allows callers to size buffers for serialisation. + * + * Each serialised buffer starts with a version byte, bytes that indicate + * the size of basic C types, and four bytes that indicate the endianness + * (to avoid incompatibilities if we ever run this over a network - we are + * not aiming for universality, just for correctness and simplicity). + * + * Most types are serialised as a fixed-size (per type) octet string, with + * no type indication. This is acceptable as (a) this is for the test PSA crypto + * simulator only, not production, and (b) these functions are called by + * code that itself is written by script. + * + * We also want to keep serialised data reasonably compact as communication + * between client and server goes in messages of less than 200 bytes each. + * + * Many serialisation functions can be created by a script; an exemplar Perl + * script is included. It is not hooked into the build and so must be run + * manually, but is expected to be replaced by a Python script in due course. + * Types that can have their functions created by script include plain old C + * data types (e.g. int), types typedef'd to those, and even structures that + * don't contain pointers. + */ + +/** Return how much buffer space is needed by \c psasim_serialise_begin(). + * + * \return The number of bytes needed in the buffer for + * \c psasim_serialise_begin()'s output. + */ +size_t psasim_serialise_begin_needs(void); + +/** Begin serialisation into a buffer. + * + * This must be the first serialisation API called + * on a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error (likely + * no space). + */ +int psasim_serialise_begin(uint8_t **pos, size_t *remaining); + +/** Begin deserialisation of a buffer. + * + * This must be the first deserialisation API called + * on a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_begin(uint8_t **pos, size_t *remaining); + +/** Return how much buffer space is needed by \c psasim_serialise_unsigned_int() + * to serialise an `unsigned int`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_unsigned_int() to serialise + * the given value. + */ +size_t psasim_serialise_unsigned_int_needs(unsigned int value); + +/** Serialise an `unsigned int` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int value); + +/** Deserialise an `unsigned int` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to an `unsigned int` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int *value); + +/** Return how much buffer space is needed by \c psasim_serialise_int() + * to serialise an `int`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_int() to serialise + * the given value. + */ +size_t psasim_serialise_int_needs(int value); + +/** Serialise an `int` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_int(uint8_t **pos, size_t *remaining, int value); + +/** Deserialise an `int` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to an `int` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_int(uint8_t **pos, size_t *remaining, int *value); + +/** Return how much buffer space is needed by \c psasim_serialise_size_t() + * to serialise a `size_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_size_t() to serialise + * the given value. + */ +size_t psasim_serialise_size_t_needs(size_t value); + +/** Serialise a `size_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_size_t(uint8_t **pos, size_t *remaining, size_t value); + +/** Deserialise a `size_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `size_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_size_t(uint8_t **pos, size_t *remaining, size_t *value); + +/** Return how much space is needed by \c psasim_serialise_buffer() + * to serialise a buffer: a (`uint8_t *`, `size_t`) pair. + * + * \param buffer Pointer to the buffer to be serialised + * (needed in case some serialisations are value- + * dependent). + * \param buffer_size Number of bytes in the buffer to be serialised. + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_buffer() to serialise + * the specified buffer. + */ +size_t psasim_serialise_buffer_needs(const uint8_t *buffer, size_t buffer_size); + +/** Serialise a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param buffer Pointer to the buffer to be serialised. + * \param buffer_length Number of bytes in the buffer to be serialised. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_buffer(uint8_t **pos, size_t *remaining, + const uint8_t *buffer, size_t buffer_length); + +/** Deserialise a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the serialisation buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the serialisation buffer. + * \param buffer Pointer to a `uint8_t *` to receive the address + * of a newly-allocated buffer, which the caller + * must `free()`. + * \param buffer_length Pointer to a `size_t` to receive the number of + * bytes in the deserialised buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_buffer(uint8_t **pos, size_t *remaining, + uint8_t **buffer, size_t *buffer_length); + +/** Deserialise a buffer returned from the server. + * + * When the client is deserialising a buffer returned from the server, it needs + * to use this function to deserialised the returned buffer. It should use the + * usual \c psasim_serialise_buffer() function to serialise the outbound + * buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the serialisation buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the serialisation buffer. + * \param buffer Pointer to a `uint8_t *` to receive the address + * of a newly-allocated buffer, which the caller + * must `free()`. + * \param buffer_length Pointer to a `size_t` to receive the number of + * bytes in the deserialised buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_return_buffer(uint8_t **pos, size_t *remaining, + uint8_t *buffer, size_t buffer_length); diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl new file mode 100644 index 0000000000..092a448ba7 --- /dev/null +++ b/psasim/src/psa_sim_serialise.pl @@ -0,0 +1,682 @@ +#!/usr/bin/env perl +# +# psa_sim_serialise.pl - Sample Perl script to show how many serialisation +# functions can be created by templated scripting. +# +# This is an example only, and is expected to be replaced by a Python script +# for production use. It is not hooked into the build: it needs to be run +# manually: +# +# perl psa_sim_serialise.pl h > psa_sim_serialise.h +# perl psa_sim_serialise.pl c > psa_sim_serialise.c +# +use strict; + +my $usage = "$0: usage: $0 c|h\n"; +my $which = lc(shift) || die($usage); +die($usage) unless $which eq "c" || $which eq "h"; + +# Most types are serialised as a fixed-size (per type) octet string, with +# no type indication. This is acceptable as (a) this is for the test PSA crypto +# simulator only, not production, and (b) these functions are called by +# code that itself is written by script. +# +# We also want to keep serialised data reasonably compact as communication +# between client and server goes in messages of less than 200 bytes each. +# +# This script is able to create serialisation functions for plain old C data +# types (e.g. unsigned int), types typedef'd to those, and even structures +# that don't contain pointers. +# +# Structures that contain pointers will need to have their serialisation and +# deserialisation functions written manually (like those for the "buffer" type +# are). +# +my @types = qw(unsigned-int int size_t buffer); +grep(s/-/ /g, @types); + +# IS-A: Some data types are typedef'd; we serialise them as the other type +my %isa = ( + # e.g. "psa_status_t" => "int", but nothing for now +); + +if ($which eq "h") { + + print h_header(); + + for my $type (@types) { + if ($type eq "buffer") { + print declare_buffer_functions(); + } else { + print declare_needs($type); + print declare_serialise($type); + print declare_deserialise($type); + } + } + +} elsif ($which eq "c") { + + print c_header(); + + for my $type (@types) { + if ($type eq "buffer") { + print define_buffer_functions(); + } elsif (exists($isa{$type})) { + print define_needs_isa($type, $isa{$type}); + print define_serialise_isa($type, $isa{$type}); + print define_deserialise_isa($type, $isa{$type}); + } else { + print define_needs($type); + print define_serialise($type); + print define_deserialise($type); + } + } + +} else { + die("internal error - shouldn't happen"); +} + +sub declare_needs +{ + my ($type) = @_; + + my $an = ($type =~ /^[ui]/) ? "an" : "a"; + my $type_d = $type; + $type_d =~ s/ /_/g; + + return < +#include + +#include "psa/crypto.h" +#include "psa/crypto_types.h" +#include "psa/crypto_values.h" + +/* Basic idea: + * + * All arguments to a function will be serialised into a single buffer to + * be sent to the server with the PSA crypto function to be called. + * + * All returned data (the function's return value and any values returned + * via `out` parameters) will similarly be serialised into a buffer to be + * sent back to the client from the server. + * + * For each data type foo (e.g. int, size_t, psa_algorithm_t, but also "buffer" + * where "buffer" is a (uint8_t *, size_t) pair, we have a pair of functions, + * psasim_serialise_foo() and psasim_deserialise_foo(). + * + * We also have psasim_serialise_foo_needs() functions, which return a + * size_t giving the number of bytes that serialising that instance of that + * type will need. This allows callers to size buffers for serialisation. + * + * Each serialised buffer starts with a version byte, bytes that indicate + * the size of basic C types, and four bytes that indicate the endianness + * (to avoid incompatibilities if we ever run this over a network - we are + * not aiming for universality, just for correctness and simplicity). + * + * Most types are serialised as a fixed-size (per type) octet string, with + * no type indication. This is acceptable as (a) this is for the test PSA crypto + * simulator only, not production, and (b) these functions are called by + * code that itself is written by script. + * + * We also want to keep serialised data reasonably compact as communication + * between client and server goes in messages of less than 200 bytes each. + * + * Many serialisation functions can be created by a script; an exemplar Perl + * script is included. It is not hooked into the build and so must be run + * manually, but is expected to be replaced by a Python script in due course. + * Types that can have their functions created by script include plain old C + * data types (e.g. int), types typedef'd to those, and even structures that + * don't contain pointers. + */ + +/** Return how much buffer space is needed by \c psasim_serialise_begin(). + * + * \return The number of bytes needed in the buffer for + * \c psasim_serialise_begin()'s output. + */ +size_t psasim_serialise_begin_needs(void); + +/** Begin serialisation into a buffer. + * + * This must be the first serialisation API called + * on a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error (likely + * no space). + */ +int psasim_serialise_begin(uint8_t **pos, size_t *remaining); + +/** Begin deserialisation of a buffer. + * + * This must be the first deserialisation API called + * on a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_begin(uint8_t **pos, size_t *remaining); +EOF +} + +sub define_needs +{ + my ($type) = @_; + + my $type_d = $type; + $type_d =~ s/ /_/g; + + return < 0) { // To be able to serialise (NULL, 0) + memcpy(*pos, buffer, buffer_length); + *pos += buffer_length; + } + + return 1; +} + +int psasim_deserialise_buffer(uint8_t **pos, + size_t *remaining, + uint8_t **buffer, + size_t *buffer_length) +{ + if (*remaining < sizeof(*buffer_length)) { + return 0; + } + + memcpy(buffer_length, *pos, sizeof(*buffer_length)); + + *pos += sizeof(buffer_length); + *remaining -= sizeof(buffer_length); + + if (*buffer_length == 0) { // Deserialise (NULL, 0) + *buffer = NULL; + return 1; + } + + if (*remaining < *buffer_length) { + return 0; + } + + uint8_t *data = malloc(*buffer_length); + if (data == NULL) { + return 0; + } + + memcpy(data, *pos, *buffer_length); + *pos += *buffer_length; + *remaining -= *buffer_length; + + *buffer = data; + + return 1; +} + +/* When the client is deserialising a buffer returned from the server, it needs + * to use this function to deserialised the returned buffer. It should use the + * usual \c psasim_serialise_buffer() function to serialise the outbound + * buffer. */ +int psasim_deserialise_return_buffer(uint8_t **pos, + size_t *remaining, + uint8_t *buffer, + size_t buffer_length) +{ + if (*remaining < sizeof(buffer_length)) { + return 0; + } + + size_t length_check; + + memcpy(&length_check, *pos, sizeof(buffer_length)); + + *pos += sizeof(buffer_length); + *remaining -= sizeof(buffer_length); + + if (buffer_length != length_check) { // Make sure we're sent back the same we sent to the server + return 0; + } + + if (length_check == 0) { // Deserialise (NULL, 0) + return 1; + } + + if (*remaining < buffer_length) { + return 0; + } + + memcpy(buffer, *pos, buffer_length); + *pos += buffer_length; + *remaining -= buffer_length; + + return 1; +} +EOF +} + +sub c_header +{ + return <<'EOF'; +/** + * \file psa_sim_serialise.c + * + * \brief Rough-and-ready serialisation and deserialisation for the PSA Crypto simulator + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa_sim_serialise.h" +#include +#include + +/* Basic idea: + * + * All arguments to a function will be serialised into a single buffer to + * be sent to the server with the PSA crypto function to be called. + * + * All returned data (the function's return value and any values returned + * via `out` parameters) will similarly be serialised into a buffer to be + * sent back to the client from the server. + * + * For each data type foo (e.g. int, size_t, psa_algorithm_t, but also "buffer" + * where "buffer" is a (uint8_t *, size_t) pair, we have a pair of functions, + * psasim_serialise_foo() and psasim_deserialise_foo(). + * + * We also have psasim_serialise_foo_needs() functions, which return a + * size_t giving the number of bytes that serialising that instance of that + * type will need. This allows callers to size buffers for serialisation. + * + * Each serialised buffer starts with a version byte, bytes that indicate + * the size of basic C types, and four bytes that indicate the endianness + * (to avoid incompatibilities if we ever run this over a network - we are + * not aiming for universality, just for correctness and simplicity). + * + * Most types are serialised as a fixed-size (per type) octet string, with + * no type indication. This is acceptable as (a) this is for the test PSA crypto + * simulator only, not production, and (b) these functions are called by + * code that itself is written by script. + * + * We also want to keep serialised data reasonably compact as communication + * between client and server goes in messages of less than 200 bytes each. + * + * Many serialisation functions can be created by a script; an exemplar Perl + * script is included. It is not hooked into the build and so must be run + * manually, but is expected to be replaced by a Python script in due course. + * Types that can have their functions created by script include plain old C + * data types (e.g. int), types typedef'd to those, and even structures that + * don't contain pointers. + */ + +size_t psasim_serialise_begin_needs(void) +{ + /* The serialisation buffer will + * start with a byte of 0 to indicate version 0, + * then have 1 byte each for length of int, long, void *, + * then have 4 bytes to indicate endianness. */ + return 4 + sizeof(uint32_t); +} + +int psasim_serialise_begin(uint8_t **pos, size_t *remaining) +{ + uint32_t endian = 0x1234; + + if (*remaining < 4 + sizeof(endian)) { + return 0; + } + + *(*pos)++ = 0; /* version */ + *(*pos)++ = (uint8_t) sizeof(int); + *(*pos)++ = (uint8_t) sizeof(long); + *(*pos)++ = (uint8_t) sizeof(void *); + + memcpy(*pos, &endian, sizeof(endian)); + + *pos += sizeof(endian); + + return 1; +} + +int psasim_deserialise_begin(uint8_t **pos, size_t *remaining) +{ + uint8_t version = 255; + uint8_t int_size = 0; + uint8_t long_size = 0; + uint8_t ptr_size = 0; + uint32_t endian; + + if (*remaining < 4 + sizeof(endian)) { + return 0; + } + + memcpy(&version, (*pos)++, sizeof(version)); + if (version != 0) { + return 0; + } + + memcpy(&int_size, (*pos)++, sizeof(int_size)); + if (int_size != sizeof(int)) { + return 0; + } + + memcpy(&long_size, (*pos)++, sizeof(long_size)); + if (long_size != sizeof(long)) { + return 0; + } + + memcpy(&ptr_size, (*pos)++, sizeof(ptr_size)); + if (ptr_size != sizeof(void *)) { + return 0; + } + + *remaining -= 4; + + memcpy(&endian, *pos, sizeof(endian)); + if (endian != 0x1234) { + return 0; + } + + *pos += sizeof(endian); + *remaining -= sizeof(endian); + + return 1; +} +EOF +} From 386add51c0240f1274a83027d7d83a651fcacbb2 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 10:04:14 +0100 Subject: [PATCH 021/125] Add PSA crypto sim serialisation functions for rest of types needed for psa_hash_compute() Still not used Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_serialise.c | 30 +++++++++++++ psasim/src/psa_sim_serialise.h | 76 +++++++++++++++++++++++++++++++++ psasim/src/psa_sim_serialise.pl | 5 ++- 3 files changed, 109 insertions(+), 2 deletions(-) diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 7caf4e595e..264509cdf1 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -319,3 +319,33 @@ int psasim_deserialise_return_buffer(uint8_t **pos, return 1; } + +size_t psasim_serialise_psa_status_t_needs(psa_status_t value) +{ + return psasim_serialise_int_needs(value); +} + +int psasim_serialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t value) +{ + return psasim_serialise_int(pos, remaining, value); +} + +int psasim_deserialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t *value) +{ + return psasim_deserialise_int(pos, remaining, value); +} + +size_t psasim_serialise_psa_algorithm_t_needs(psa_algorithm_t value) +{ + return psasim_serialise_unsigned_int_needs(value); +} + +int psasim_serialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t value) +{ + return psasim_serialise_unsigned_int(pos, remaining, value); +} + +int psasim_deserialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t *value) +{ + return psasim_deserialise_unsigned_int(pos, remaining, value); +} diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 4ae0253f4a..9cca7d8c65 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -270,3 +270,79 @@ int psasim_deserialise_buffer(uint8_t **pos, size_t *remaining, */ int psasim_deserialise_return_buffer(uint8_t **pos, size_t *remaining, uint8_t *buffer, size_t buffer_length); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_status_t() + * to serialise a `psa_status_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_status_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_status_t_needs(psa_status_t value); + +/** Serialise a `psa_status_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t value); + +/** Deserialise a `psa_status_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_status_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t *value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_algorithm_t() + * to serialise a `psa_algorithm_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_algorithm_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_algorithm_t_needs(psa_algorithm_t value); + +/** Serialise a `psa_algorithm_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t value); + +/** Deserialise a `psa_algorithm_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_algorithm_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t *value); diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 092a448ba7..2a6c3885b7 100644 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -32,12 +32,13 @@ # deserialisation functions written manually (like those for the "buffer" type # are). # -my @types = qw(unsigned-int int size_t buffer); +my @types = qw(unsigned-int int size_t buffer psa_status_t psa_algorithm_t); grep(s/-/ /g, @types); # IS-A: Some data types are typedef'd; we serialise them as the other type my %isa = ( - # e.g. "psa_status_t" => "int", but nothing for now + "psa_status_t" => "int", + "psa_algorithm_t" => "unsigned int", ); if ($which eq "h") { From d726062aa0563c1f530995e3e5cecdb1ffd0244d Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 10:27:01 +0100 Subject: [PATCH 022/125] 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 --- psasim/src/psa_functions_codes.h | 13 +- psasim/src/psa_sim_crypto_client.c | 207 +++++ psasim/src/psa_sim_crypto_server.c | 225 ++++++ psasim/src/psa_sim_generate.pl | 1130 ++++++++++++++++++++++++++++ 4 files changed, 1573 insertions(+), 2 deletions(-) create mode 100644 psasim/src/psa_sim_crypto_client.c create mode 100644 psasim/src/psa_sim_crypto_server.c create mode 100644 psasim/src/psa_sim_generate.pl diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 34897b91be..9306be95a1 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -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_ */ diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c new file mode 100644 index 0000000000..85c8a3c036 --- /dev/null +++ b/psasim/src/psa_sim_crypto_client.c @@ -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 +#include + +/* Includes from psasim */ +#include +#include +#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; +} diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c new file mode 100644 index 0000000000..c15b2b0c82 --- /dev/null +++ b/psasim/src/psa_sim_crypto_server.c @@ -0,0 +1,225 @@ +/* THIS FILE WAS AUTO-GENERATED BY psa_sim_generate.pl. DO NOT EDIT!! */ + +/* server implementations */ + +#include +#include + +#include + +#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; +} diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl new file mode 100644 index 0000000000..62c1a893b7 --- /dev/null +++ b/psasim/src/psa_sim_generate.pl @@ -0,0 +1,1130 @@ +#!/usr/bin/env perl +# +# This is a proof-of-concept script to show that the client and server wrappers +# can be created by a script. It is not hooked into the build, so is run +# manually and the output files are what are to be reviewed. In due course +# this will be replaced by a Python script. +# +use strict; +use Data::Dumper; +use JSON qw(encode_json); + +my $debug = 0; + +# Globals (sorry!) +my %functions = get_functions(); +my @functions = sort keys %functions; + +# get_functions(), called above, returns a data structure for each function +# that we need to create client and server stubs for. In this example Perl script, +# the function declarations we want are in the data section (after __END__ at +# the bottom of this file), but a production Python version should process +# psa_crypto.h. +# +# In this script, the data for psa_crypto_init() looks like: +# +# "psa_crypto_init": { +# "return": { # Info on return type +# "type": "psa_status_t", # Return type +# "name": "status", # Name to be used for this in C code +# "default": "PSA_ERROR_CORRUPTION_DETECTED" # Default value +# }, +# "args": [], # void function, so args empty +# } +# +# The data for psa_hash_compute() looks like: +# +# "psa_hash_compute": { +# "return": { # Information on return type +# "type": "psa_status_t", +# "name": "status", +# "default": "PSA_ERROR_CORRUPTION_DETECTED" +# }, +# "args": [{ +# "type": "psa_algorithm_t", # Type of first argument +# "ctypename": "psa_algorithm_t ", # C type with trailing spaces +# # (so that e.g. `char *` looks ok) +# "name": "alg", +# "is_output": 0 +# }, { +# "type": "const buffer", # Specially created +# "ctypename": "", # (so no C type) +# "name": "input, input_length", # A pair of arguments +# "is_output": 0 # const, so not an output argument +# }, { +# "type": "buffer", # Specially created +# "ctypename": "", +# "name": "hash, hash_size", +# "is_output": 1 # Not const, so output argument +# }, { +# "type": "size_t", # size_t *hash_length +# "ctypename": "size_t ", +# "name": "*hash_length", # * comes into the name +# "is_output": 1 +# } +# ], +# }, +# +# It's possible that a production version might not need both type and ctypename; +# that was done for convenience and future-proofing during development. + +# We'll do psa_crypto_init() first +put_crypto_init_first(\@functions); + +write_function_codes("psa_functions_codes.h"); + +write_client_calls("psa_sim_crypto_client.c"); + +write_server_implementations("psa_sim_crypto_server.c"); + +sub write_function_codes +{ + my ($file) = @_; + + open(my $fh, ">", $file) || die("$0: $file: $!\n"); + + # NOTE: psa_crypto_init() is written manually + + print $fh <", $file) || die("$0: $file: $!\n"); + + print $fh client_calls_header(); + + for my $function (@functions) { + # psa_crypto_init() is hand written to establish connection to server + if ($function ne "psa_crypto_init") { + my $f = $functions{$function}; + output_client($fh, $f, $function); + } + } + + close($fh); +} + +sub write_server_implementations +{ + my ($file) = @_; + + open(my $fh, ">", $file) || die("$0: $file: $!\n"); + + print $fh server_implementations_header(); + + print $fh debug_functions() if $debug; + + for my $function (@functions) { + my $f = $functions{$function}; + output_server_wrapper($fh, $f, $function); + } + + # Now output a switch statement that calls each of the wrappers + + print $fh < 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; +} +EOF + + close($fh); +} + +sub server_implementations_header +{ + return <<'EOF'; +/* THIS FILE WAS AUTO-GENERATED BY psa_sim_generate.pl. DO NOT EDIT!! */ + +/* server implementations */ + +#include +#include + +#include + +#include "psa_functions_codes.h" +#include "psa_sim_serialise.h" + +#include "service.h" +EOF +} + +sub client_calls_header +{ + my $code = <<'EOF'; +/* 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 +#include + +/* Includes from psasim */ +#include +#include +#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; +EOF + + $code .= debug_functions() if $debug; + + $code .= <<'EOF'; + +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; +} +EOF +} + +sub debug_functions +{ + return <> 4); + p[1] = hex_digit(b & 0x0F); + + return 2; +} + +int hex_uint16(char *p, uint16_t b) +{ + hex_byte(p, b >> 8); + hex_byte(p + 2, b & 0xFF); + + return 4; +} + +char human_char(uint8_t c) +{ + return (c >= ' ' && c <= '~') ? (char)c : '.'; +} + +void dump_buffer(const uint8_t *buffer, size_t len) +{ + char line[80]; + + const uint8_t *p = buffer; + + size_t max = (len > 0xFFFF) ? 0xFFFF : len; + + for (size_t i = 0; i < max; i += 16) { + + char *q = line; + + q += hex_uint16(q, (uint16_t)i); + *q++ = ' '; + *q++ = ' '; + + size_t ll = (i + 16 > max) ? (max % 16) : 16; + + size_t j; + for (j = 0; j < ll; j++) { + q += hex_byte(q, p[i + j]); + *q++ = ' '; + } + + while (j++ < 16) { + *q++ = ' '; + *q++ = ' '; + *q++ = ' '; + } + + *q++ = ' '; + + for (j = 0; j < ll; j++) { + *q++ = human_char(p[i + j]); + } + + *q = '\\0'; + + printf("%s\\n", line); + } +} + +void hex_dump(uint8_t *p, size_t n) +{ + for (size_t i = 0; i < n; i++) { + printf("0x%02X ", p[i]); + } + printf("\\n"); +} +EOF +} + +sub output_server_wrapper +{ + my ($fh, $f, $name) = @_; + + my $ret_type = $f->{return}->{type}; + my $ret_name = $f->{return}->{name}; + my $ret_default = $f->{return}->{default}; + + print $fh <{args}; + + for my $i (0 .. $#$args) { + my $arg = $args->[$i]; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $argname = $arg->{name}; + $argtype =~ s/^const //; + + if ($argtype =~ /^(const )?buffer$/) { + my ($n1, $n2) = split(/,\s*/, $argname); + print $fh <= 0) { # If we have any args (>= 0) + print $fh <= 0) { # If we have any args (>= 0) + print $fh <[$i]; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $argname = $arg->{name}; + my $sep = ($i == $#$args) ? ";" : " +"; + $argtype =~ s/^const //; + + if ($argtype =~ /^(const )?buffer$/) { + my ($n1, $n2) = split(/,\s*/, $argname); + print $fh <{is_output}, @$args); + + my $sep1 = ($ret_type eq "void") ? ";" : " +"; + + print $fh <{is_output}; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $argname = $arg->{name}; + my $sep = ($i == $#outputs) ? ";" : " +"; + $argtype =~ s/^const //; + $argname =~ s/^\*//; # Remove any leading * + + print $fh <{is_output}, @$args); + + for my $i (0 .. $#outputs) { + my $arg = $outputs[$i]; + die("$i: this should have been filtered out by grep") unless $arg->{is_output}; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $argname = $arg->{name}; + my $sep = ($i == $#outputs) ? ";" : " +"; + $argtype =~ s/^const //; + + if ($argtype eq "buffer") { + print $fh <{return}->{type}; + my $ret_name = $f->{return}->{name}; + my $ret_default = $f->{return}->{default}; + + print $fh <{args}; + + for my $i (0 .. $#$args) { + my $arg = $args->[$i]; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $argname = $arg->{name}; + my $sep = ($i == $#$args) ? ";" : " +"; + $argtype =~ s/^const //; + + print $fh <[$i]; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $argname = $arg->{name}; + my $sep = ($i == $#$args) ? ";" : " +"; + $argtype =~ s/^const //; + + print $fh <{is_output}, @$args); + + for my $i (0 .. $#outputs) { + my $arg = $outputs[$i]; + die("$i: this should have been filtered out by grep") unless $arg->{is_output}; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $argname = $arg->{name}; + my $sep = ($i == $#outputs) ? ";" : " +"; + $argtype =~ s/^const //; + + if ($argtype eq "buffer") { + print $fh <{return}->{name}; + my $args = $f->{args}; + + print $fh "\n $ret_name = $name(\n"; + + print $fh " );\n" if $#$args < 0; # If no arguments, empty arg list + + for my $i (0 .. $#$args) { + my $arg = $args->[$i]; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $argname = $arg->{name}; + + if ($argtype =~ /^(const )?buffer$/) { + my ($n1, $n2) = split(/,\s*/, $argname); + print $fh " $n1, $n2"; + } else { + $argname =~ s/^\*/\&/; # Replace leading * with & + print $fh " $argname"; + } + my $sep = ($i == $#$args) ? "\n );" : ","; + print $fh "$sep\n"; + } +} + +sub output_signature +{ + my ($fh, $f, $name, $what) = @_; + + my $ret_type = $f->{return}->{type}; + my $args = $f->{args}; + + my $final_sep = ($what eq "declaration") ? "\n);" : "\n )"; + + print $fh "\n$ret_type $name(\n"; + + print $fh " void\n)\n" if $#$args < 0; # No arguments + + for my $i (0 .. $#$args) { + my $arg = $args->[$i]; + my $argtype = $arg->{type}; # e.g. int, psa_algorithm_t, or "buffer" + my $ctypename = $arg->{ctypename}; # e.g. "int ", "char *"; empty for buffer + my $argname = $arg->{name}; + + if ($argtype =~ /^(const )?buffer$/) { + my $const = length($1) ? "const " : ""; + my ($n1, $n2) = split(/,/, $argname); + print $fh " ${const}uint8_t *$n1, size_t $n2"; + } else { + print $fh " $ctypename$argname"; + } + my $sep = ($i == $#$args) ? $final_sep : ","; + print $fh "$sep\n"; + } +} + +sub get_functions +{ + my $src = ""; + while () { + chomp; + s/\/\/.*//; + s/\s+^//; + s/\s+/ /g; + $_ .= "\n"; + $src .= $_; + } + + $src =~ s/\/\*.*?\*\///gs; + + my @src = split(/\n+/, $src); + + my @rebuild = (); + my %funcs = (); + for (my $i = 0; $i <= $#src; $i++) { + my $line = $src[$i]; + if ($line =~ /^psa_status_t (psa_\w*)\(/) { # begin function definition + #print "have one $line\n"; + while ($line !~ /;/) { + $line .= $src[$i + 1]; + $i++; + } + $line =~ s/\s+/ /g; + if ($line =~ /(\w+)\s+\b(\w+)\s*\(\s*(.*\S)\s*\)\s*[;{]/s) { + my ($ret_type, $func, $args) = ($1, $2, $3); + my $copy = $line; + $copy =~ s/{$//; + my $f = { + "orig" => $copy, + }; + + my @args = split(/\s*,\s*/, $args); + + my $ret_name = ""; + $ret_name = "status" if $ret_type eq "psa_status_t"; + die("ret_name for $ret_type?") unless length($ret_name); + my $ret_default = ""; + $ret_default = "PSA_ERROR_CORRUPTION_DETECTED" if $ret_type eq "psa_status_t"; + die("ret_default for $ret_type?") unless length($ret_default); + + #print "FUNC $func RET_NAME $ret_name RET_TYPE $ret_type ARGS (", join("; ", @args), ")\n"; + + $f->{return} = { + "type" => $ret_type, + "default" => $ret_default, + "name" => $ret_name, + }; + $f->{args} = []; + # psa_algorithm_t alg; const uint8_t *input; size_t input_length; uint8_t *hash; size_t hash_size; size_t *hash_length + for (my $i = 0; $i <= $#args; $i++) { + my $arg = $args[$i]; + # "type" => "psa_algorithm_t", + # "ctypename" => "psa_algorithm_t ", + # "name" => "alg", + # "is_output" => 0, + my ($type, $ctype, $name, $is_output); + if ($arg =~ /^(\w+)\s+(\w+)$/) { # e.g. psa_algorithm_t alg + ($type, $name) = ($1, $2); + $ctype = $type . " "; + $is_output = 0; + } elsif ($arg =~ /^((const)\s+)?uint8_t\s*\*\s*(\w+)$/) { + $type = "buffer"; + $is_output = (length($1) == 0) ? 1 : 0; + $type = "const buffer" if !$is_output; + $ctype = ""; + $name = $3; + #print("$arg: $name: might be a buffer?\n"); + die("$arg: not a buffer 1!\n") if $i == $#args; + my $next = $args[$i + 1]; + die("$arg: not a buffer 2!\n") if $next !~ /^size_t\s+(${name}_\w+)$/; + $i++; # We're using the next param here + my $nname = $1; + $name .= ", " . $nname; + } elsif ($arg =~ /^((const)\s+)?(\w+)\s*\*(\w+)$/) { + ($type, $name) = ($3, "*" . $4); + $ctype = $1 . $type . " "; + $is_output = (length($1) == 0) ? 1 : 0; + } elsif ($arg eq "void") { + # we'll just ignore this one + } else { + die("ARG HELP $arg\n"); + } + #print "$arg => <$type><$ctype><$name><$is_output>\n"; + if ($arg ne "void") { + push(@{$f->{args}}, { + "type" => $type, + "ctypename" => $ctype, + "name" => $name, + "is_output" => $is_output, + }); + } + } + $funcs{$func} = $f; + } else { + die("FAILED"); + } + push(@rebuild, $line); + } elsif ($line =~ /^static psa_\w+_t (psa_\w*)\(/) { # begin function definition + # IGNORE static functions + } else { + if ($line =~ /psa_/) { + print "NOT PARSED: $line\n"; + } + push(@rebuild, $line); + } + } + + #print ::Dumper(\%funcs); + #exit; + + return %funcs; +} + +sub put_crypto_init_first +{ + my ($functions) = @_; + + my $want_first = "psa_crypto_init"; + + my $idx = undef; + for my $i (0 .. $#$functions) { + if ($functions->[$i] eq $want_first) { + $idx = $i; + last; + } + } + + if (defined($idx) && $idx != 0) { # Do nothing if already first + splice(@$functions, $idx, 1); + unshift(@$functions, $want_first); + } +} + +__END__ +/** + * \brief Library initialization. + * + * Applications must call this function before calling any other + * function in this module. + * + * Applications may call this function more than once. Once a call + * succeeds, subsequent calls are guaranteed to succeed. + * + * If the application calls other functions before calling psa_crypto_init(), + * the behavior is undefined. Implementations are encouraged to either perform + * the operation as if the library had been initialized or to return + * #PSA_ERROR_BAD_STATE or some other applicable error. In particular, + * implementations should not return a success status if the lack of + * initialization may have security implications, for example due to improper + * seeding of the random number generator. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + */ +psa_status_t psa_crypto_init(void); + +/** Calculate the hash (digest) of a message. + * + * \note To verify the hash of a message against an + * expected value, use psa_hash_compare() instead. + * + * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_HASH(\p alg) is true). + * \param[in] input Buffer containing the message to hash. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] hash Buffer where the hash is to be written. + * \param hash_size Size of the \p hash buffer in bytes. + * \param[out] hash_length On success, the number of bytes + * that make up the hash value. This is always + * #PSA_HASH_LENGTH(\p alg). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a hash algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p hash_size is too small + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +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); From f2d96a7f8fbc45b829eba0301e6a39d34bd3c49e Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 10:28:08 +0100 Subject: [PATCH 023/125] The PSA sim logs aren't very many lines, so show them during tests Signed-off-by: Tom Cosgrove --- psasim/test/run_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh index 06bcc93a82..31429c8bb5 100755 --- a/psasim/test/run_test.sh +++ b/psasim/test/run_test.sh @@ -30,8 +30,8 @@ function wait_for_server_startup() { clean_run -./psa_partition -k > psa_partition.log 2>&1 & +./psa_partition -k & SERV_PID=$! wait_for_server_startup -./psa_client > psa_client.log 2>&1 +./psa_client wait $SERV_PID From c6bc912d04ab7c675f94c519df0b839606900a21 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 10:29:39 +0100 Subject: [PATCH 024/125] Hook the new psa_sim_crypto_{client,server} into the build and tests - smoke test client.c becomes a trivial call to psa_crypto_init() - server.c now uses psa_sim_crypto_server.c's psa_crypto_call() - Makefile is updated to build all the modules, and allow a different MAIN - all.sh's test_psasim now tests the simulation of psa_hash_compute() too Signed-off-by: Tom Cosgrove --- psasim/Makefile | 10 ++- psasim/src/aut_psa_hash_compute.c | 112 ++++++++++++++++++++++++++++++ psasim/src/client.c | 41 ++--------- psasim/src/server.c | 10 +-- 4 files changed, 126 insertions(+), 47 deletions(-) create mode 100644 psasim/src/aut_psa_hash_compute.c diff --git a/psasim/Makefile b/psasim/Makefile index db0c4127f4..45ec45820e 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -1,3 +1,5 @@ +MAIN ?= client.c + CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L ifeq ($(DEBUG),1) @@ -18,12 +20,16 @@ GENERATED_H_FILES = include/psa_manifest/manifest.h \ include/psa_manifest/sid.h PSA_CLIENT_SRC = src/psa_ff_client.c \ - src/client.c + src/$(MAIN) \ + src/psa_sim_crypto_client.c \ + src/psa_sim_serialise.c PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ - src/psa_ff_server.c + src/psa_ff_server.c \ + src/psa_sim_crypto_server.c \ + src/psa_sim_serialise.c .PHONY: all clean libpsaclient libpsaserver diff --git a/psasim/src/aut_psa_hash_compute.c b/psasim/src/aut_psa_hash_compute.c new file mode 100644 index 0000000000..519c0721f7 --- /dev/null +++ b/psasim/src/aut_psa_hash_compute.c @@ -0,0 +1,112 @@ +/* + * API(s) under test: psa_hash_compute() + * + * Taken from programs/psa/psa_hash.c, and calls to all hash APIs + * but psa_hash_compute() removed. + * + * Example computing a SHA-256 hash using the PSA Crypto API + * + * The example computes the SHA-256 hash of a test string using the + * one-shot API call psa_hash_compute(). + * + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa/crypto.h" +#include +#include +#include + +#include "mbedtls/build_info.h" +#include "mbedtls/platform.h" + +/* Information about hashing with the PSA API can be + * found here: + * https://arm-software.github.io/psa-api/crypto/1.1/api/ops/hashes.html + * + * The algorithm used by this demo is SHA 256. + * Please see include/psa/crypto_values.h to see the other + * algorithms that are supported by Mbed TLS. + * If you switch to a different algorithm you will need to update + * the hash data in the EXAMPLE_HASH_VALUE macro below. */ + +#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256) +int main(void) +{ + mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256" + "not defined.\r\n"); + return EXIT_SUCCESS; +} +#else + +#define HASH_ALG PSA_ALG_SHA_256 + +const uint8_t sample_message[] = "Hello World!"; +/* sample_message is terminated with a null byte which is not part of + * the message itself so we make sure to subtract it in order to get + * the message length. */ +const size_t sample_message_length = sizeof(sample_message) - 1; + +#define EXPECTED_HASH_VALUE { \ + 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \ + 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, \ + 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \ +} + +const uint8_t expected_hash[] = EXPECTED_HASH_VALUE; +const size_t expected_hash_len = sizeof(expected_hash); + +int main(void) +{ + psa_status_t status; + uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)]; + size_t hash_length; + + mbedtls_printf("PSA Crypto API: SHA-256 example\n\n"); + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + /* Clear local variables prior to one-shot hash demo */ + memset(hash, 0, sizeof(hash)); + hash_length = 0; + + /* Compute hash using one-shot function call */ + status = psa_hash_compute(HASH_ALG, + sample_message, sample_message_length, + hash, sizeof(hash), + &hash_length); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_compute failed\n"); + goto cleanup; + } + + if (hash_length != expected_hash_len || + (memcmp(hash, expected_hash, expected_hash_len) != 0)) { + mbedtls_printf("One-shot hash operation gave the wrong result!\n\n"); + goto cleanup; + } + + mbedtls_printf("One-shot hash operation successful!\n\n"); + + /* Print out result */ + mbedtls_printf("The SHA-256( '%s' ) is: ", sample_message); + + for (size_t j = 0; j < expected_hash_len; j++) { + mbedtls_printf("%02x", hash[j]); + } + + mbedtls_printf("\n"); + + mbedtls_psa_crypto_free(); + return EXIT_SUCCESS; + +cleanup: + return EXIT_FAILURE; +} +#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */ diff --git a/psasim/src/client.c b/psasim/src/client.c index 550a6e869d..a8c9e08f3e 100644 --- a/psasim/src/client.c +++ b/psasim/src/client.c @@ -5,50 +5,17 @@ * 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_CRYPTO_SID)); - psa_handle_t h = psa_connect(PSA_SID_CRYPTO_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); - + /* psa_crypto_init() connects to the server */ + psa_status_t status = psa_crypto_init(); if (status != PSA_SUCCESS) { return 1; } + + mbedtls_psa_crypto_free(); return 0; } diff --git a/psasim/src/server.c b/psasim/src/server.c index 21b65c709e..77ce2694e3 100644 --- a/psasim/src/server.c +++ b/psasim/src/server.c @@ -53,6 +53,7 @@ int psa_server_main(int argc, char *argv[]) const int magic_num = 66; int client_disconnected = 0; char mbedtls_version[18]; + extern psa_status_t psa_crypto_call(psa_msg_t msg); mbedtls_version_get_string_full(mbedtls_version); SERVER_PRINT("%s", mbedtls_version); @@ -83,14 +84,7 @@ int psa_server_main(int argc, char *argv[]) break; default: SERVER_PRINT("Got an IPC call of type %d", msg.type); - switch (msg.type) { - case PSA_CRYPTO_INIT: - ret = psa_crypto_init(); - break; - default: - SERVER_PRINT("Unknown PSA function code"); - break; - } + ret = psa_crypto_call(msg); SERVER_PRINT("Internal function call returned %d", ret); if (msg.client_id > 0) { From b4adef825befd8e8aa9c1d550e3c3e51a77637e8 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 12:26:53 +0100 Subject: [PATCH 025/125] Add PSA crypto sim serialisation functions needed for the remaining PSA hash APIs Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_serialise.c | 75 ++++++++++++++++++++++++---- psasim/src/psa_sim_serialise.h | 82 +++++++++++++++++++++++++++---- psasim/src/psa_sim_serialise.pl | 87 ++++++++++++++++++++++++++++----- 3 files changed, 211 insertions(+), 33 deletions(-) diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 264509cdf1..78ae9d65d7 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -130,7 +130,9 @@ size_t psasim_serialise_unsigned_int_needs(unsigned int value) return sizeof(value); } -int psasim_serialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int value) +int psasim_serialise_unsigned_int(uint8_t **pos, + size_t *remaining, + unsigned int value) { if (*remaining < sizeof(value)) { return 0; @@ -142,7 +144,9 @@ int psasim_serialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int return 1; } -int psasim_deserialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int *value) +int psasim_deserialise_unsigned_int(uint8_t **pos, + size_t *remaining, + unsigned int *value) { if (*remaining < sizeof(*value)) { return 0; @@ -161,7 +165,9 @@ size_t psasim_serialise_int_needs(int value) return sizeof(value); } -int psasim_serialise_int(uint8_t **pos, size_t *remaining, int value) +int psasim_serialise_int(uint8_t **pos, + size_t *remaining, + int value) { if (*remaining < sizeof(value)) { return 0; @@ -173,7 +179,9 @@ int psasim_serialise_int(uint8_t **pos, size_t *remaining, int value) return 1; } -int psasim_deserialise_int(uint8_t **pos, size_t *remaining, int *value) +int psasim_deserialise_int(uint8_t **pos, + size_t *remaining, + int *value) { if (*remaining < sizeof(*value)) { return 0; @@ -192,7 +200,9 @@ size_t psasim_serialise_size_t_needs(size_t value) return sizeof(value); } -int psasim_serialise_size_t(uint8_t **pos, size_t *remaining, size_t value) +int psasim_serialise_size_t(uint8_t **pos, + size_t *remaining, + size_t value) { if (*remaining < sizeof(value)) { return 0; @@ -204,7 +214,9 @@ int psasim_serialise_size_t(uint8_t **pos, size_t *remaining, size_t value) return 1; } -int psasim_deserialise_size_t(uint8_t **pos, size_t *remaining, size_t *value) +int psasim_deserialise_size_t(uint8_t **pos, + size_t *remaining, + size_t *value) { if (*remaining < sizeof(*value)) { return 0; @@ -325,12 +337,16 @@ size_t psasim_serialise_psa_status_t_needs(psa_status_t value) return psasim_serialise_int_needs(value); } -int psasim_serialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t value) +int psasim_serialise_psa_status_t(uint8_t **pos, + size_t *remaining, + psa_status_t value) { return psasim_serialise_int(pos, remaining, value); } -int psasim_deserialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t *value) +int psasim_deserialise_psa_status_t(uint8_t **pos, + size_t *remaining, + psa_status_t *value) { return psasim_deserialise_int(pos, remaining, value); } @@ -340,12 +356,51 @@ size_t psasim_serialise_psa_algorithm_t_needs(psa_algorithm_t value) return psasim_serialise_unsigned_int_needs(value); } -int psasim_serialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t value) +int psasim_serialise_psa_algorithm_t(uint8_t **pos, + size_t *remaining, + psa_algorithm_t value) { return psasim_serialise_unsigned_int(pos, remaining, value); } -int psasim_deserialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t *value) +int psasim_deserialise_psa_algorithm_t(uint8_t **pos, + size_t *remaining, + psa_algorithm_t *value) { return psasim_deserialise_unsigned_int(pos, remaining, value); } + +size_t psasim_serialise_psa_hash_operation_t_needs(psa_hash_operation_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_hash_operation_t(uint8_t **pos, + size_t *remaining, + psa_hash_operation_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_hash_operation_t(uint8_t **pos, + size_t *remaining, + psa_hash_operation_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 9cca7d8c65..d5eaccf482 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -113,7 +113,9 @@ size_t psasim_serialise_unsigned_int_needs(unsigned int value); * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_serialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int value); +int psasim_serialise_unsigned_int(uint8_t **pos, + size_t *remaining, + unsigned int value); /** Deserialise an `unsigned int` from a buffer. * @@ -126,7 +128,9 @@ int psasim_serialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_deserialise_unsigned_int(uint8_t **pos, size_t *remaining, unsigned int *value); +int psasim_deserialise_unsigned_int(uint8_t **pos, + size_t *remaining, + unsigned int *value); /** Return how much buffer space is needed by \c psasim_serialise_int() * to serialise an `int`. @@ -151,7 +155,9 @@ size_t psasim_serialise_int_needs(int value); * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_serialise_int(uint8_t **pos, size_t *remaining, int value); +int psasim_serialise_int(uint8_t **pos, + size_t *remaining, + int value); /** Deserialise an `int` from a buffer. * @@ -164,7 +170,9 @@ int psasim_serialise_int(uint8_t **pos, size_t *remaining, int value); * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_deserialise_int(uint8_t **pos, size_t *remaining, int *value); +int psasim_deserialise_int(uint8_t **pos, + size_t *remaining, + int *value); /** Return how much buffer space is needed by \c psasim_serialise_size_t() * to serialise a `size_t`. @@ -189,7 +197,9 @@ size_t psasim_serialise_size_t_needs(size_t value); * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_serialise_size_t(uint8_t **pos, size_t *remaining, size_t value); +int psasim_serialise_size_t(uint8_t **pos, + size_t *remaining, + size_t value); /** Deserialise a `size_t` from a buffer. * @@ -202,7 +212,9 @@ int psasim_serialise_size_t(uint8_t **pos, size_t *remaining, size_t value); * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_deserialise_size_t(uint8_t **pos, size_t *remaining, size_t *value); +int psasim_deserialise_size_t(uint8_t **pos, + size_t *remaining, + size_t *value); /** Return how much space is needed by \c psasim_serialise_buffer() * to serialise a buffer: a (`uint8_t *`, `size_t`) pair. @@ -294,7 +306,9 @@ size_t psasim_serialise_psa_status_t_needs(psa_status_t value); * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_serialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t value); +int psasim_serialise_psa_status_t(uint8_t **pos, + size_t *remaining, + psa_status_t value); /** Deserialise a `psa_status_t` from a buffer. * @@ -307,7 +321,9 @@ int psasim_serialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_deserialise_psa_status_t(uint8_t **pos, size_t *remaining, psa_status_t *value); +int psasim_deserialise_psa_status_t(uint8_t **pos, + size_t *remaining, + psa_status_t *value); /** Return how much buffer space is needed by \c psasim_serialise_psa_algorithm_t() * to serialise a `psa_algorithm_t`. @@ -332,7 +348,9 @@ size_t psasim_serialise_psa_algorithm_t_needs(psa_algorithm_t value); * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_serialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t value); +int psasim_serialise_psa_algorithm_t(uint8_t **pos, + size_t *remaining, + psa_algorithm_t value); /** Deserialise a `psa_algorithm_t` from a buffer. * @@ -345,4 +363,48 @@ int psasim_serialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algor * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_deserialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t *value); +int psasim_deserialise_psa_algorithm_t(uint8_t **pos, + size_t *remaining, + psa_algorithm_t *value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_hash_operation_t() + * to serialise a `psa_hash_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_hash_operation_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_hash_operation_t_needs(psa_hash_operation_t value); + +/** Serialise a `psa_hash_operation_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_hash_operation_t(uint8_t **pos, + size_t *remaining, + psa_hash_operation_t value); + +/** Deserialise a `psa_hash_operation_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_hash_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_hash_operation_t(uint8_t **pos, + size_t *remaining, + psa_hash_operation_t *value); diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 2a6c3885b7..b89d058516 100644 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -32,7 +32,10 @@ # deserialisation functions written manually (like those for the "buffer" type # are). # -my @types = qw(unsigned-int int size_t buffer psa_status_t psa_algorithm_t); +my @types = qw(unsigned-int int size_t + buffer + psa_status_t psa_algorithm_t + psa_hash_operation_t); grep(s/-/ /g, @types); # IS-A: Some data types are typedef'd; we serialise them as the other type @@ -110,7 +113,7 @@ sub declare_serialise my $type_d = $type; $type_d =~ s/ /_/g; - return < $#code; + + # Find where the ( is + my $idx = index($code[$i], "("); + die("can't find (") if $idx < 0; + + my $indent = " " x ($idx + 1); + $code[$i + 1] =~ s/^\s+/$indent/; + $code[$i + 2] =~ s/^\s+/$indent/; + + return join("\n", @code) . "\n"; +} From f37a6f42fc1f94ca5e560187cb122fa83ca2cca0 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 12:34:27 +0100 Subject: [PATCH 026/125] Add the rest of the psa_hash_xxx() functions to the simulator Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 7 + psasim/src/psa_sim_crypto_client.c | 494 +++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 571 +++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 266 ++++++++++++++ 4 files changed, 1338 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 9306be95a1..00937338dd 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -12,7 +12,14 @@ enum { /* Start here to avoid overlap with PSA_IPC_CONNECT, PSA_IPC_DISCONNECT * and VERSION_REQUEST */ PSA_CRYPTO_INIT = 100, + PSA_HASH_ABORT, + PSA_HASH_CLONE, + PSA_HASH_COMPARE, PSA_HASH_COMPUTE, + PSA_HASH_FINISH, + PSA_HASH_SETUP, + PSA_HASH_UPDATE, + PSA_HASH_VERIFY, }; #endif /* _PSA_FUNCTIONS_CODES_H_ */ diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 85c8a3c036..4ac6c4a581 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -121,6 +121,208 @@ void mbedtls_psa_crypto_free(void) } +psa_status_t psa_hash_abort( + psa_hash_operation_t *operation + ) +{ + 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_hash_operation_t_needs(*operation); + + 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_hash_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_ABORT, + 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_psa_hash_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_hash_clone( + const psa_hash_operation_t *source_operation, + psa_hash_operation_t *target_operation + ) +{ + 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_hash_operation_t_needs(*source_operation) + + psasim_serialise_psa_hash_operation_t_needs(*target_operation); + + 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_hash_operation_t(&pos, &remaining, *source_operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_hash_operation_t(&pos, &remaining, *target_operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_CLONE, + 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_psa_hash_operation_t(&rpos, &rremain, target_operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_hash_compare( + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *hash, 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_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_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_COMPARE, + 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; + } + +fail: + free(params); + free(result); + + return status; +} + + psa_status_t psa_hash_compute( psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -205,3 +407,295 @@ psa_status_t psa_hash_compute( return status; } + + +psa_status_t psa_hash_finish( + psa_hash_operation_t *operation, + 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_hash_operation_t_needs(*operation) + + 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_hash_operation_t(&pos, &remaining, *operation); + 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_FINISH, + 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_psa_hash_operation_t(&rpos, &rremain, operation); + 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; +} + + +psa_status_t psa_hash_setup( + psa_hash_operation_t *operation, + psa_algorithm_t alg + ) +{ + 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_hash_operation_t_needs(*operation) + + psasim_serialise_psa_algorithm_t_needs(alg); + + 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_hash_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_SETUP, + 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_psa_hash_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_hash_update( + psa_hash_operation_t *operation, + const uint8_t *input, size_t input_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_hash_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_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_hash_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_UPDATE, + 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_psa_hash_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_hash_verify( + psa_hash_operation_t *operation, + const uint8_t *hash, 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_hash_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(hash, 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_hash_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_VERIFY, + 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_psa_hash_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index c15b2b0c82..7a8068237d 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -60,6 +60,227 @@ int psa_crypto_init_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_hash_abort_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_hash_operation_t operation; + + 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_hash_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_abort( + &operation + ); + + // 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_psa_hash_operation_t_needs(operation); + + 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_psa_hash_operation_t(&rpos, &rremain, operation); + 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_clone_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_hash_operation_t source_operation; + psa_hash_operation_t target_operation; + + 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_hash_operation_t(&pos, &remaining, &source_operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_hash_operation_t(&pos, &remaining, &target_operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_clone( + &source_operation, + &target_operation + ); + + // 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_psa_hash_operation_t_needs(target_operation); + + 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_psa_hash_operation_t(&rpos, &rremain, target_operation); + 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_compare_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_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_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_compare( + alg, + input, input_length, + hash, 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); + + 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, @@ -157,6 +378,328 @@ int psa_hash_compute_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_hash_finish_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_hash_operation_t operation; + 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_hash_operation_t(&pos, &remaining, &operation); + 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_finish( + &operation, + 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_psa_hash_operation_t_needs(operation) + + 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_psa_hash_operation_t(&rpos, &rremain, operation); + 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! +} + +// Returns 1 for success, 0 for failure +int psa_hash_setup_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_hash_operation_t operation; + psa_algorithm_t alg; + + 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_hash_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_setup( + &operation, + alg + ); + + // 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_psa_hash_operation_t_needs(operation); + + 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_psa_hash_operation_t(&rpos, &rremain, operation); + 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_update_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_hash_operation_t operation; + uint8_t *input = NULL; + size_t input_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_hash_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_update( + &operation, + input, input_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_psa_hash_operation_t_needs(operation); + + 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_psa_hash_operation_t(&rpos, &rremain, operation); + 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_verify_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_hash_operation_t operation; + uint8_t *hash = NULL; + 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_hash_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_verify( + &operation, + hash, 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_psa_hash_operation_t_needs(operation); + + 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_psa_hash_operation_t(&rpos, &rremain, operation); + 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; @@ -197,10 +740,38 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_crypto_init_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_HASH_ABORT: + ok = psa_hash_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_HASH_CLONE: + ok = psa_hash_clone_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_HASH_COMPARE: + ok = psa_hash_compare_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; + case PSA_HASH_FINISH: + ok = psa_hash_finish_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_HASH_SETUP: + ok = psa_hash_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_HASH_UPDATE: + ok = psa_hash_update_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_HASH_VERIFY: + ok = psa_hash_verify_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; } free(in_params); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 62c1a893b7..9eef1e52d2 100644 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -1128,3 +1128,269 @@ sub put_crypto_init_first uint8_t *hash, size_t hash_size, size_t *hash_length); + +/* XXX We put this next one in place to check we ignore static functions + * when we eventually read all this from a real header file + */ + +/** Return an initial value for a hash operation object. + */ +static psa_hash_operation_t psa_hash_operation_init(void); + +/* XXX Back to normal function declarations */ + +/** Set up a multipart hash operation. + * + * The sequence of operations to calculate a hash (message digest) + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_hash_operation_t, e.g. #PSA_HASH_OPERATION_INIT. + * -# Call psa_hash_setup() to specify the algorithm. + * -# Call psa_hash_update() zero, one or more times, passing a fragment + * of the message each time. The hash that is calculated is the hash + * of the concatenation of these messages in order. + * -# To calculate the hash, call psa_hash_finish(). + * To compare the hash with an expected value, call psa_hash_verify(). + * + * If an error occurs at any step after a call to psa_hash_setup(), the + * operation will need to be reset by a call to psa_hash_abort(). The + * application may call psa_hash_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_hash_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_hash_finish() or psa_hash_verify(). + * - A call to psa_hash_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_hash_operation_t and not yet in use. + * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_HASH(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not a supported hash algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p alg is not a hash algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_setup(psa_hash_operation_t *operation, + psa_algorithm_t alg); + +/** Add a message fragment to a multipart hash operation. + * + * The application must call psa_hash_setup() before calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). + * + * \param[in,out] operation Active hash operation. + * \param[in] input Buffer containing the message fragment to hash. + * \param input_length Size of the \p input buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_update(psa_hash_operation_t *operation, + const uint8_t *input, + size_t input_length); + +/** Finish the calculation of the hash of a message. + * + * The application must call psa_hash_setup() before calling this function. + * This function calculates the hash of the message formed by concatenating + * the inputs passed to preceding calls to psa_hash_update(). + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). + * + * \warning Applications should not call this function if they expect + * a specific value for the hash. Call psa_hash_verify() instead. + * Beware that comparing integrity or authenticity data such as + * hash values with a function such as \c memcmp is risky + * because the time taken by the comparison may leak information + * about the hashed data which could allow an attacker to guess + * a valid hash and thereby bypass security controls. + * + * \param[in,out] operation Active hash operation. + * \param[out] hash Buffer where the hash is to be written. + * \param hash_size Size of the \p hash buffer in bytes. + * \param[out] hash_length On success, the number of bytes + * that make up the hash value. This is always + * #PSA_HASH_LENGTH(\c alg) where \c alg is the + * hash algorithm that is calculated. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p hash buffer is too small. You can determine a + * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg) + * where \c alg is the hash algorithm that is calculated. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_finish(psa_hash_operation_t *operation, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +/** Finish the calculation of the hash of a message and compare it with + * an expected value. + * + * The application must call psa_hash_setup() before calling this function. + * This function calculates the hash of the message formed by concatenating + * the inputs passed to preceding calls to psa_hash_update(). It then + * compares the calculated hash with the expected hash passed as a + * parameter to this function. + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). + * + * \note Implementations shall make the best effort to ensure that the + * comparison between the actual hash and the expected hash is performed + * in constant time. + * + * \param[in,out] operation Active hash operation. + * \param[in] hash Buffer containing the expected hash value. + * \param hash_length Size of the \p hash buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected hash is identical to the actual hash of the message. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The hash of the message was calculated successfully, but it + * differs from the expected hash. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_verify(psa_hash_operation_t *operation, + const uint8_t *hash, + size_t hash_length); + +/** Abort a hash operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * psa_hash_setup() again. + * + * You may call this function any time after the operation object has + * been initialized by one of the methods described in #psa_hash_operation_t. + * + * In particular, calling psa_hash_abort() after the operation has been + * terminated by a call to psa_hash_abort(), psa_hash_finish() or + * psa_hash_verify() is safe and has no effect. + * + * \param[in,out] operation Initialized hash operation. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_abort(psa_hash_operation_t *operation); + +/** Clone a hash operation. + * + * This function copies the state of an ongoing hash operation to + * a new operation object. In other words, this function is equivalent + * to calling psa_hash_setup() on \p target_operation with the same + * algorithm that \p source_operation was set up for, then + * psa_hash_update() on \p target_operation with the same input that + * that was passed to \p source_operation. After this function returns, the + * two objects are independent, i.e. subsequent calls involving one of + * the objects do not affect the other object. + * + * \param[in] source_operation The active hash operation to clone. + * \param[in,out] target_operation The operation object to set up. + * It must be initialized but not active. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The \p source_operation state is not valid (it must be active), or + * the \p target_operation state is not valid (it must be inactive), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, + psa_hash_operation_t *target_operation); + +/** Calculate the hash (digest) of a message and compare it with a + * reference value. + * + * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_HASH(\p alg) is true). + * \param[in] input Buffer containing the message to hash. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] hash Buffer containing the expected hash value. + * \param hash_length Size of the \p hash buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected hash is identical to the actual hash of the input. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The hash of the message was calculated successfully, but it + * differs from the expected hash. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a hash algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p input_length or \p hash_length do not match the hash size for \p alg + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_compare(psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *hash, + size_t hash_length); From f5ad2242fff3bfec8229b4414cd3a6bf0ab80357 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 12:36:09 +0100 Subject: [PATCH 027/125] Extend PSA crypto simulator tests to run psa_hash.c under the simulator Signed-off-by: Tom Cosgrove --- psasim/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/psasim/Makefile b/psasim/Makefile index 45ec45820e..06d3059b4b 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -1,4 +1,4 @@ -MAIN ?= client.c +MAIN ?= src/client.c CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L @@ -20,7 +20,7 @@ GENERATED_H_FILES = include/psa_manifest/manifest.h \ include/psa_manifest/sid.h PSA_CLIENT_SRC = src/psa_ff_client.c \ - src/$(MAIN) \ + $(MAIN) \ src/psa_sim_crypto_client.c \ src/psa_sim_serialise.c From 70ea0c3dd3452aa0b3e9f24372de2282936dd1aa Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 16:52:38 +0100 Subject: [PATCH 028/125] Mark temporary PSA crypto sim Perl scripts as executable Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 0 psasim/src/psa_sim_serialise.pl | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 psasim/src/psa_sim_generate.pl mode change 100644 => 100755 psasim/src/psa_sim_serialise.pl diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl old mode 100644 new mode 100755 diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl old mode 100644 new mode 100755 From ad00107fceea2f3a2f247f7b06da35a38fa616e0 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Wed, 29 May 2024 22:48:45 +0100 Subject: [PATCH 029/125] PSA crypto sim's server wrappers need to free deseraliased buffers when they're no longer needed Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_crypto_server.c | 33 ++++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 9 +++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 7a8068237d..7e874d16e8 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -57,6 +57,7 @@ int psa_crypto_init_wrapper( fail: free(result); + return 0; // This shouldn't happen! } @@ -125,6 +126,7 @@ int psa_hash_abort_wrapper( fail: free(result); + return 0; // This shouldn't happen! } @@ -200,6 +202,7 @@ int psa_hash_clone_wrapper( fail: free(result); + return 0; // This shouldn't happen! } @@ -274,10 +277,17 @@ int psa_hash_compare_wrapper( *out_params = result; *out_params_len = result_size; + free(input); + free(hash); + return 1; // success fail: free(result); + + free(input); + free(hash); + return 0; // This shouldn't happen! } @@ -371,10 +381,17 @@ int psa_hash_compute_wrapper( *out_params = result; *out_params_len = result_size; + free(input); + free(hash); + return 1; // success fail: free(result); + + free(input); + free(hash); + return 0; // This shouldn't happen! } @@ -466,10 +483,15 @@ int psa_hash_finish_wrapper( *out_params = result; *out_params_len = result_size; + free(hash); + return 1; // success fail: free(result); + + free(hash); + return 0; // This shouldn't happen! } @@ -545,6 +567,7 @@ int psa_hash_setup_wrapper( fail: free(result); + return 0; // This shouldn't happen! } @@ -617,10 +640,15 @@ int psa_hash_update_wrapper( *out_params = result; *out_params_len = result_size; + free(input); + return 1; // success fail: free(result); + + free(input); + return 0; // This shouldn't happen! } @@ -693,10 +721,15 @@ int psa_hash_verify_wrapper( *out_params = result; *out_params_len = result_size; + free(hash); + return 1; // success fail: free(result); + + free(hash); + return 0; // This shouldn't happen! } diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 9eef1e52d2..7fea72c9d0 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -484,6 +484,8 @@ sub output_server_wrapper my $ret_name = $f->{return}->{name}; my $ret_default = $f->{return}->{default}; + my @buffers = (); # We need to free() these on exit + print $fh < Date: Thu, 30 May 2024 11:12:22 +0100 Subject: [PATCH 030/125] Add missing licences Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_crypto_server.c | 5 +++++ psasim/src/psa_sim_generate.pl | 8 ++++++++ psasim/src/psa_sim_serialise.pl | 3 +++ 3 files changed, 16 insertions(+) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 7e874d16e8..919eb84419 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -2,6 +2,11 @@ /* server implementations */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + #include #include diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 7fea72c9d0..19c6a0bf4a 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -5,6 +5,9 @@ # manually and the output files are what are to be reviewed. In due course # this will be replaced by a Python script. # +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +# use strict; use Data::Dumper; use JSON qw(encode_json); @@ -251,6 +254,11 @@ sub server_implementations_header /* server implementations */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + #include #include diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index b89d058516..5161db1f67 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -10,6 +10,9 @@ # perl psa_sim_serialise.pl h > psa_sim_serialise.h # perl psa_sim_serialise.pl c > psa_sim_serialise.c # +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +# use strict; my $usage = "$0: usage: $0 c|h\n"; From 0190ef004c257e7cfa5634ea165b87e63007b973 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 10 Jun 2024 13:43:41 +0100 Subject: [PATCH 031/125] Correctly build client-side code that's to be run under the PSA crypto sim Signed-off-by: Tom Cosgrove --- psasim/Makefile | 4 +++- psasim/src/psa_sim_client_config_adjust.h | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 psasim/src/psa_sim_client_config_adjust.h diff --git a/psasim/Makefile b/psasim/Makefile index 06d3059b4b..b9ec3ad742 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -24,6 +24,8 @@ PSA_CLIENT_SRC = src/psa_ff_client.c \ src/psa_sim_crypto_client.c \ src/psa_sim_serialise.c +PSA_CLIENT_DEFS = -Isrc -DMBEDTLS_USER_CONFIG_FILE='"psa_sim_client_config_adjust.h"' + PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ @@ -39,7 +41,7 @@ test/seedfile: dd if=/dev/urandom of=./test/seedfile bs=64 count=1 test/psa_client: $(PSA_CLIENT_SRC) $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ + $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_DEFS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ test/psa_partition: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) test/seedfile $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_SERVER_SRC) $(LIBPSASERVER) $(LDFLAGS) -o $@ diff --git a/psasim/src/psa_sim_client_config_adjust.h b/psasim/src/psa_sim_client_config_adjust.h new file mode 100644 index 0000000000..3640c2a2fe --- /dev/null +++ b/psasim/src/psa_sim_client_config_adjust.h @@ -0,0 +1,14 @@ +/** + * \file psa_sim_client_config_adjust.h + * + * \brief User config file for client-side code to be run under PSA simulator + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#define MBEDTLS_PSA_CRYPTO_CLIENT +#undef MBEDTLS_PSA_CRYPTO_C +#undef MBEDTLS_PSA_CRYPTO_STORAGE_C From 5972faaa36edd42a4d0d6ad9375af676203f85c1 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 10 Jun 2024 13:53:08 +0100 Subject: [PATCH 032/125] We want the PSA hash code if MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C Signed-off-by: Tom Cosgrove --- psasim/src/aut_psa_hash_compute.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/psasim/src/aut_psa_hash_compute.c b/psasim/src/aut_psa_hash_compute.c index 519c0721f7..70c3e5be4f 100644 --- a/psasim/src/aut_psa_hash_compute.c +++ b/psasim/src/aut_psa_hash_compute.c @@ -32,11 +32,12 @@ * If you switch to a different algorithm you will need to update * the hash data in the EXAMPLE_HASH_VALUE macro below. */ -#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256) +#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ + (!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256)) int main(void) { mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256" - "not defined.\r\n"); + "not defined, and not MBEDTLS_PSA_CRYPTO_CLIENT.\r\n"); return EXIT_SUCCESS; } #else From 01b8304ecefaa70445518f33bf30fc447be8bdc4 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 10 Jun 2024 14:08:04 +0100 Subject: [PATCH 033/125] Store operation_ts on PSA sim server side; only send handle to client Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_crypto_server.c | 66 +++++++++--------- psasim/src/psa_sim_serialise.c | 107 +++++++++++++++++++++++++++++ psasim/src/psa_sim_serialise.h | 10 +++ 3 files changed, 150 insertions(+), 33 deletions(-) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 919eb84419..e511c74fa2 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -72,7 +72,7 @@ int psa_hash_abort_wrapper( uint8_t **out_params, size_t *out_params_len) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_hash_operation_t operation; + psa_hash_operation_t *operation; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -84,7 +84,7 @@ int psa_hash_abort_wrapper( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } @@ -92,14 +92,14 @@ int psa_hash_abort_wrapper( // Now we call the actual target function status = psa_hash_abort( - &operation + operation ); // 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_psa_hash_operation_t_needs(operation); + psasim_server_serialise_psa_hash_operation_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -119,7 +119,7 @@ int psa_hash_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); if (!ok) { goto fail; } @@ -141,8 +141,8 @@ int psa_hash_clone_wrapper( uint8_t **out_params, size_t *out_params_len) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_hash_operation_t source_operation; - psa_hash_operation_t target_operation; + psa_hash_operation_t *source_operation; + psa_hash_operation_t *target_operation; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -154,12 +154,12 @@ int psa_hash_clone_wrapper( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&pos, &remaining, &source_operation); + ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &source_operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&pos, &remaining, &target_operation); + ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &target_operation); if (!ok) { goto fail; } @@ -167,15 +167,15 @@ int psa_hash_clone_wrapper( // Now we call the actual target function status = psa_hash_clone( - &source_operation, - &target_operation + source_operation, + target_operation ); // 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_psa_hash_operation_t_needs(target_operation); + psasim_server_serialise_psa_hash_operation_t_needs(target_operation); result = malloc(result_size); if (result == NULL) { @@ -195,7 +195,7 @@ int psa_hash_clone_wrapper( goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&rpos, &rremain, target_operation); + ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, target_operation); if (!ok) { goto fail; } @@ -406,7 +406,7 @@ int psa_hash_finish_wrapper( uint8_t **out_params, size_t *out_params_len) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_hash_operation_t operation; + psa_hash_operation_t *operation; uint8_t *hash = NULL; size_t hash_size; size_t hash_length; @@ -421,7 +421,7 @@ int psa_hash_finish_wrapper( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } @@ -439,7 +439,7 @@ int psa_hash_finish_wrapper( // Now we call the actual target function status = psa_hash_finish( - &operation, + operation, hash, hash_size, &hash_length ); @@ -448,7 +448,7 @@ int psa_hash_finish_wrapper( size_t result_size = psasim_serialise_begin_needs() + psasim_serialise_psa_status_t_needs(status) + - psasim_serialise_psa_hash_operation_t_needs(operation) + + psasim_server_serialise_psa_hash_operation_t_needs(operation) + psasim_serialise_buffer_needs(hash, hash_size) + psasim_serialise_size_t_needs(hash_length); @@ -470,7 +470,7 @@ int psa_hash_finish_wrapper( goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); if (!ok) { goto fail; } @@ -506,7 +506,7 @@ int psa_hash_setup_wrapper( uint8_t **out_params, size_t *out_params_len) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_hash_operation_t operation; + psa_hash_operation_t *operation; psa_algorithm_t alg; uint8_t *pos = in_params; @@ -519,7 +519,7 @@ int psa_hash_setup_wrapper( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } @@ -532,7 +532,7 @@ int psa_hash_setup_wrapper( // Now we call the actual target function status = psa_hash_setup( - &operation, + operation, alg ); @@ -540,7 +540,7 @@ int psa_hash_setup_wrapper( size_t result_size = psasim_serialise_begin_needs() + psasim_serialise_psa_status_t_needs(status) + - psasim_serialise_psa_hash_operation_t_needs(operation); + psasim_server_serialise_psa_hash_operation_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -560,7 +560,7 @@ int psa_hash_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); if (!ok) { goto fail; } @@ -582,7 +582,7 @@ int psa_hash_update_wrapper( uint8_t **out_params, size_t *out_params_len) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_hash_operation_t operation; + psa_hash_operation_t *operation; uint8_t *input = NULL; size_t input_length; @@ -596,7 +596,7 @@ int psa_hash_update_wrapper( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } @@ -609,7 +609,7 @@ int psa_hash_update_wrapper( // Now we call the actual target function status = psa_hash_update( - &operation, + operation, input, input_length ); @@ -617,7 +617,7 @@ int psa_hash_update_wrapper( size_t result_size = psasim_serialise_begin_needs() + psasim_serialise_psa_status_t_needs(status) + - psasim_serialise_psa_hash_operation_t_needs(operation); + psasim_server_serialise_psa_hash_operation_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -637,7 +637,7 @@ int psa_hash_update_wrapper( goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); if (!ok) { goto fail; } @@ -663,7 +663,7 @@ int psa_hash_verify_wrapper( uint8_t **out_params, size_t *out_params_len) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_hash_operation_t operation; + psa_hash_operation_t *operation; uint8_t *hash = NULL; size_t hash_length; @@ -677,7 +677,7 @@ int psa_hash_verify_wrapper( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } @@ -690,7 +690,7 @@ int psa_hash_verify_wrapper( // Now we call the actual target function status = psa_hash_verify( - &operation, + operation, hash, hash_length ); @@ -698,7 +698,7 @@ int psa_hash_verify_wrapper( size_t result_size = psasim_serialise_begin_needs() + psasim_serialise_psa_status_t_needs(status) + - psasim_serialise_psa_hash_operation_t_needs(operation); + psasim_server_serialise_psa_hash_operation_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -718,7 +718,7 @@ int psa_hash_verify_wrapper( goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); if (!ok) { goto fail; } diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 78ae9d65d7..20d89c54fa 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -13,6 +13,51 @@ #include #include +/* include/psa/crypto_platform.h:typedef uint32_t mbedtls_psa_client_handle_t; + * but we don't get it on server builds, so redefine it here with a unique type name + */ +typedef uint32_t psasim_client_handle_t; + +typedef struct psasim_operation_s { + psasim_client_handle_t handle; +} psasim_operation_t; + +#define MAX_LIVE_HANDLES_PER_CLASS 100 /* this many slots */ + +static psa_hash_operation_t hash_operations[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t hash_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t next_hash_operation_handle = 1; + +/* Get a free slot */ +static ssize_t allocate_hash_operation_slot(void) +{ + psasim_client_handle_t handle = next_hash_operation_handle++; + if (next_hash_operation_handle == 0) { /* wrapped around */ + fprintf(stderr, "MAX HASH HANDLES REACHED\n"); + exit(1); + } + + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (hash_operation_handles[i] == 0) { + hash_operation_handles[i] = handle; + return i; + } + } + + return -1; /* all in use */ +} + +static ssize_t find_hash_slot_by_handle(psasim_client_handle_t handle) +{ + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (hash_operation_handles[i] == handle) { + return i; + } + } + + return -1; /* all in use */ +} + /* Basic idea: * * All arguments to a function will be serialised into a single buffer to @@ -404,3 +449,65 @@ int psasim_deserialise_psa_hash_operation_t(uint8_t **pos, return 1; } + +/* On the server side, we have a certain number of slots. One array holds the + * psa_XXX_operation_t values by slot, the other holds the client-side handles + * for the slots. + */ +size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *operation) +{ + (void) operation; + + /* We will actually return a handle */ + return sizeof(psasim_operation_t); +} + +int psasim_server_serialise_psa_hash_operation_t(uint8_t **pos, + size_t *remaining, + psa_hash_operation_t *operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(client_operation)) { + return 0; + } + + ssize_t slot = operation - hash_operations; + + client_operation.handle = hash_operation_handles[slot]; + + memcpy(*pos, &client_operation, sizeof(client_operation)); + *pos += sizeof(client_operation); + + return 1; +} + +int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos, + size_t *remaining, + psa_hash_operation_t **operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(psasim_operation_t)) { + return 0; + } + + memcpy(&client_operation, *pos, sizeof(psasim_operation_t)); + *pos += sizeof(psasim_operation_t); + *remaining -= sizeof(psasim_operation_t); + + ssize_t slot; + if (client_operation.handle == 0) { /* We need a new handle */ + slot = allocate_hash_operation_slot(); + } else { + slot = find_hash_slot_by_handle(client_operation.handle); + } + + if (slot < 0) { + return 0; + } + + *operation = &hash_operations[slot]; + + return 1; +} diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index d5eaccf482..7a5881e74e 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -408,3 +408,13 @@ int psasim_serialise_psa_hash_operation_t(uint8_t **pos, int psasim_deserialise_psa_hash_operation_t(uint8_t **pos, size_t *remaining, psa_hash_operation_t *value); + +size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *operation); + +int psasim_server_serialise_psa_hash_operation_t(uint8_t **pos, + size_t *remaining, + psa_hash_operation_t *operation); + +int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos, + size_t *remaining, + psa_hash_operation_t **operation); From 566c7a69015d6657a85f830ac209a30c69697e1f Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 10 Jun 2024 14:24:28 +0100 Subject: [PATCH 034/125] Make psa_sim_generate.pl output the new type of server wrapper we want Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 19c6a0bf4a..efd50aa846 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -522,8 +522,9 @@ sub output_server_wrapper push(@buffers, $n1); # Add to the list to be free()d at end } else { $argname =~ s/^\*//; # Remove any leading * + my $pointer = ($argtype =~ /^psa_\w+_operation_t/) ? "*" : ""; print $fh <{is_output}, @$args); @@ -616,9 +618,10 @@ sub output_server_wrapper my $sep = ($i == $#outputs) ? ";" : " +"; $argtype =~ s/^const //; $argname =~ s/^\*//; # Remove any leading * + my $server_specific = ($argtype =~ /^psa_\w+_operation_t/) ? "server_" : ""; print $fh <{return}->{name}; my $args = $f->{args}; @@ -900,6 +905,9 @@ sub output_call print $fh " $n1, $n2"; } else { $argname =~ s/^\*/\&/; # Replace leading * with & + if ($is_server && $argtype =~ /^psa_\w+_operation_t/) { + $argname =~ s/^\&//; # Actually, for psa_XXX_operation_t, don't do this on the server side + } print $fh " $argname"; } my $sep = ($i == $#$args) ? "\n );" : ","; From a84398bd750390741820dedfe3d8024ee282776f Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 10 Jun 2024 15:34:19 +0100 Subject: [PATCH 035/125] Move the comment block in psa_sim_serialise.c back to where it belongs Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_serialise.c | 76 +++++++++++++++++----------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 20d89c54fa..e45cd00c4c 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -13,6 +13,44 @@ #include #include +/* Basic idea: + * + * All arguments to a function will be serialised into a single buffer to + * be sent to the server with the PSA crypto function to be called. + * + * All returned data (the function's return value and any values returned + * via `out` parameters) will similarly be serialised into a buffer to be + * sent back to the client from the server. + * + * For each data type foo (e.g. int, size_t, psa_algorithm_t, but also "buffer" + * where "buffer" is a (uint8_t *, size_t) pair, we have a pair of functions, + * psasim_serialise_foo() and psasim_deserialise_foo(). + * + * We also have psasim_serialise_foo_needs() functions, which return a + * size_t giving the number of bytes that serialising that instance of that + * type will need. This allows callers to size buffers for serialisation. + * + * Each serialised buffer starts with a version byte, bytes that indicate + * the size of basic C types, and four bytes that indicate the endianness + * (to avoid incompatibilities if we ever run this over a network - we are + * not aiming for universality, just for correctness and simplicity). + * + * Most types are serialised as a fixed-size (per type) octet string, with + * no type indication. This is acceptable as (a) this is for the test PSA crypto + * simulator only, not production, and (b) these functions are called by + * code that itself is written by script. + * + * We also want to keep serialised data reasonably compact as communication + * between client and server goes in messages of less than 200 bytes each. + * + * Many serialisation functions can be created by a script; an exemplar Perl + * script is included. It is not hooked into the build and so must be run + * manually, but is expected to be replaced by a Python script in due course. + * Types that can have their functions created by script include plain old C + * data types (e.g. int), types typedef'd to those, and even structures that + * don't contain pointers. + */ + /* include/psa/crypto_platform.h:typedef uint32_t mbedtls_psa_client_handle_t; * but we don't get it on server builds, so redefine it here with a unique type name */ @@ -58,44 +96,6 @@ static ssize_t find_hash_slot_by_handle(psasim_client_handle_t handle) return -1; /* all in use */ } -/* Basic idea: - * - * All arguments to a function will be serialised into a single buffer to - * be sent to the server with the PSA crypto function to be called. - * - * All returned data (the function's return value and any values returned - * via `out` parameters) will similarly be serialised into a buffer to be - * sent back to the client from the server. - * - * For each data type foo (e.g. int, size_t, psa_algorithm_t, but also "buffer" - * where "buffer" is a (uint8_t *, size_t) pair, we have a pair of functions, - * psasim_serialise_foo() and psasim_deserialise_foo(). - * - * We also have psasim_serialise_foo_needs() functions, which return a - * size_t giving the number of bytes that serialising that instance of that - * type will need. This allows callers to size buffers for serialisation. - * - * Each serialised buffer starts with a version byte, bytes that indicate - * the size of basic C types, and four bytes that indicate the endianness - * (to avoid incompatibilities if we ever run this over a network - we are - * not aiming for universality, just for correctness and simplicity). - * - * Most types are serialised as a fixed-size (per type) octet string, with - * no type indication. This is acceptable as (a) this is for the test PSA crypto - * simulator only, not production, and (b) these functions are called by - * code that itself is written by script. - * - * We also want to keep serialised data reasonably compact as communication - * between client and server goes in messages of less than 200 bytes each. - * - * Many serialisation functions can be created by a script; an exemplar Perl - * script is included. It is not hooked into the build and so must be run - * manually, but is expected to be replaced by a Python script in due course. - * Types that can have their functions created by script include plain old C - * data types (e.g. int), types typedef'd to those, and even structures that - * don't contain pointers. - */ - size_t psasim_serialise_begin_needs(void) { /* The serialisation buffer will From 7774c5fef383b51392905b0e1f82552c35cd92ff Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Mon, 10 Jun 2024 15:20:44 +0100 Subject: [PATCH 036/125] psa_sim_serialise.pl now creates the updated .h file Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_serialise.h | 38 +++++++++++++++++++++++++--- psasim/src/psa_sim_serialise.pl | 44 ++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 7a5881e74e..4ec7ec04fb 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -409,12 +409,44 @@ int psasim_deserialise_psa_hash_operation_t(uint8_t **pos, size_t *remaining, psa_hash_operation_t *value); -size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *operation); +/** Return how much buffer space is needed by \c psasim_server_serialise_psa_hash_operation_t() + * to serialise a `psa_hash_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_hash_operation_t() to serialise + * the given value. + */ +size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *value); +/** Serialise a `psa_hash_operation_t` into a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ int psasim_server_serialise_psa_hash_operation_t(uint8_t **pos, size_t *remaining, - psa_hash_operation_t *operation); + psa_hash_operation_t *value); +/** Deserialise a `psa_hash_operation_t` from a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_hash_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos, size_t *remaining, - psa_hash_operation_t **operation); + psa_hash_operation_t **value); diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 5161db1f67..21bfec52ba 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -55,9 +55,15 @@ if ($type eq "buffer") { print declare_buffer_functions(); } else { - print declare_needs($type); - print declare_serialise($type); - print declare_deserialise($type); + print declare_needs($type, ""); + print declare_serialise($type, ""); + print declare_deserialise($type, ""); + + if ($type =~ /^psa_\w+_operation_t$/) { + print declare_needs($type, "server_"); + print declare_serialise($type, "server_"); + print declare_deserialise($type, "server_"); + } } } @@ -85,15 +91,17 @@ sub declare_needs { - my ($type) = @_; + my ($type, $server) = @_; my $an = ($type =~ /^[ui]/) ? "an" : "a"; my $type_d = $type; $type_d =~ s/ /_/g; + my $ptr = (length($server)) ? "*" : ""; + return < Date: Mon, 10 Jun 2024 15:50:53 +0100 Subject: [PATCH 037/125] psa_sim_serialise.pl now creates the updated .c file Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_serialise.c | 5 +- psasim/src/psa_sim_serialise.pl | 187 ++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 4 deletions(-) diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index e45cd00c4c..348e42c2b4 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -85,6 +85,7 @@ static ssize_t allocate_hash_operation_slot(void) return -1; /* all in use */ } +/* Find the slot given the handle */ static ssize_t find_hash_slot_by_handle(psasim_client_handle_t handle) { for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { @@ -450,10 +451,6 @@ int psasim_deserialise_psa_hash_operation_t(uint8_t **pos, return 1; } -/* On the server side, we have a certain number of slots. One array holds the - * psa_XXX_operation_t values by slot, the other holds the client-side handles - * for the slots. - */ size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *operation) { (void) operation; diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 21bfec52ba..eb2893ea5f 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -69,7 +69,17 @@ } elsif ($which eq "c") { + my $have_operation_types = (grep(/psa_\w+_operation_t/, @types)) ? 1 : 0; + print c_header(); + print c_define_types_for_operation_types() if $have_operation_types; + + for my $type (@types) { + next unless $type =~ /^psa_(\w+)_operation_t$/; + print define_operation_type_data_and_functions($1); + } + + print c_define_begins(); for my $type (@types) { if ($type eq "buffer") { @@ -82,6 +92,12 @@ print define_needs($type); print define_serialise($type); print define_deserialise($type); + + if ($type =~ /^psa_\w+_operation_t$/) { + print define_server_needs($type); + print define_server_serialise($type); + print define_server_deserialise($type); + } } } @@ -363,6 +379,25 @@ sub define_needs EOF } +sub define_server_needs +{ + my ($type) = @_; + + my $type_d = $type; + $type_d =~ s/ /_/g; + + return < Date: Tue, 11 Jun 2024 09:53:53 +0100 Subject: [PATCH 038/125] Revert "Correctly build client-side code that's to be run under the PSA crypto sim" This reverts commit 0190ef004c257e7cfa5634ea165b87e63007b973. Signed-off-by: Tom Cosgrove --- psasim/Makefile | 4 +--- psasim/src/psa_sim_client_config_adjust.h | 14 -------------- 2 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 psasim/src/psa_sim_client_config_adjust.h diff --git a/psasim/Makefile b/psasim/Makefile index b9ec3ad742..06d3059b4b 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -24,8 +24,6 @@ PSA_CLIENT_SRC = src/psa_ff_client.c \ src/psa_sim_crypto_client.c \ src/psa_sim_serialise.c -PSA_CLIENT_DEFS = -Isrc -DMBEDTLS_USER_CONFIG_FILE='"psa_sim_client_config_adjust.h"' - PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ @@ -41,7 +39,7 @@ test/seedfile: dd if=/dev/urandom of=./test/seedfile bs=64 count=1 test/psa_client: $(PSA_CLIENT_SRC) $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_DEFS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ + $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ test/psa_partition: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) test/seedfile $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_SERVER_SRC) $(LIBPSASERVER) $(LDFLAGS) -o $@ diff --git a/psasim/src/psa_sim_client_config_adjust.h b/psasim/src/psa_sim_client_config_adjust.h deleted file mode 100644 index 3640c2a2fe..0000000000 --- a/psasim/src/psa_sim_client_config_adjust.h +++ /dev/null @@ -1,14 +0,0 @@ -/** - * \file psa_sim_client_config_adjust.h - * - * \brief User config file for client-side code to be run under PSA simulator - */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#define MBEDTLS_PSA_CRYPTO_CLIENT -#undef MBEDTLS_PSA_CRYPTO_C -#undef MBEDTLS_PSA_CRYPTO_STORAGE_C From 9dc22c56b0d6c867a7686f49a66bdfb2ae4390aa Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 11 Jun 2024 13:38:15 +0100 Subject: [PATCH 039/125] Use our own copy of programs/psa/psa_hash.c in the PSA simulator tests Signed-off-by: Tom Cosgrove --- psasim/src/aut_psa_hash.c | 160 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 psasim/src/aut_psa_hash.c diff --git a/psasim/src/aut_psa_hash.c b/psasim/src/aut_psa_hash.c new file mode 100644 index 0000000000..6c2c07e062 --- /dev/null +++ b/psasim/src/aut_psa_hash.c @@ -0,0 +1,160 @@ +/* + * Example computing a SHA-256 hash using the PSA Crypto API + * + * The example computes the SHA-256 hash of a test string using the + * one-shot API call psa_hash_compute() and the using multi-part + * operation, which requires psa_hash_setup(), psa_hash_update() and + * psa_hash_finish(). The multi-part operation is popular on embedded + * devices where a rolling hash needs to be computed. + * + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa/crypto.h" +#include +#include +#include + +#include "mbedtls/build_info.h" +#include "mbedtls/platform.h" + +/* Information about hashing with the PSA API can be + * found here: + * https://arm-software.github.io/psa-api/crypto/1.1/api/ops/hashes.html + * + * The algorithm used by this demo is SHA 256. + * Please see include/psa/crypto_values.h to see the other + * algorithms that are supported by Mbed TLS. + * If you switch to a different algorithm you will need to update + * the hash data in the EXAMPLE_HASH_VALUE macro below. */ + +#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ + (!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256)) +int main(void) +{ + mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256" + "not defined, and not MBEDTLS_PSA_CRYPTO_CLIENT.\r\n"); + return EXIT_SUCCESS; +} +#else + +#define HASH_ALG PSA_ALG_SHA_256 + +const uint8_t sample_message[] = "Hello World!"; +/* sample_message is terminated with a null byte which is not part of + * the message itself so we make sure to subtract it in order to get + * the message length. */ +const size_t sample_message_length = sizeof(sample_message) - 1; + +#define EXPECTED_HASH_VALUE { \ + 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \ + 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, \ + 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \ +} + +const uint8_t expected_hash[] = EXPECTED_HASH_VALUE; +const size_t expected_hash_len = sizeof(expected_hash); + +int main(void) +{ + psa_status_t status; + uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)]; + size_t hash_length; + psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT; + psa_hash_operation_t cloned_hash_operation = PSA_HASH_OPERATION_INIT; + + mbedtls_printf("PSA Crypto API: SHA-256 example\n\n"); + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + /* Compute hash using multi-part operation */ + status = psa_hash_setup(&hash_operation, HASH_ALG); + if (status == PSA_ERROR_NOT_SUPPORTED) { + mbedtls_printf("unknown hash algorithm supplied\n"); + return EXIT_FAILURE; + } else if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_setup failed\n"); + return EXIT_FAILURE; + } + + status = psa_hash_update(&hash_operation, sample_message, sample_message_length); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_update failed\n"); + goto cleanup; + } + + status = psa_hash_clone(&hash_operation, &cloned_hash_operation); + if (status != PSA_SUCCESS) { + mbedtls_printf("PSA hash clone failed\n"); + goto cleanup; + } + + status = psa_hash_finish(&hash_operation, hash, sizeof(hash), &hash_length); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_finish failed\n"); + goto cleanup; + } + + /* Check the result of the operation against the sample */ + if (hash_length != expected_hash_len || + (memcmp(hash, expected_hash, expected_hash_len) != 0)) { + mbedtls_printf("Multi-part hash operation gave the wrong result!\n\n"); + goto cleanup; + } + + status = + psa_hash_verify(&cloned_hash_operation, expected_hash, + expected_hash_len); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_verify failed\n"); + goto cleanup; + } else { + mbedtls_printf("Multi-part hash operation successful!\n"); + } + + /* Clear local variables prior to one-shot hash demo */ + memset(hash, 0, sizeof(hash)); + hash_length = 0; + + /* Compute hash using one-shot function call */ + status = psa_hash_compute(HASH_ALG, + sample_message, sample_message_length, + hash, sizeof(hash), + &hash_length); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_compute failed\n"); + goto cleanup; + } + + if (hash_length != expected_hash_len || + (memcmp(hash, expected_hash, expected_hash_len) != 0)) { + mbedtls_printf("One-shot hash operation gave the wrong result!\n\n"); + goto cleanup; + } + + mbedtls_printf("One-shot hash operation successful!\n\n"); + + /* Print out result */ + mbedtls_printf("The SHA-256( '%s' ) is: ", sample_message); + + for (size_t j = 0; j < expected_hash_len; j++) { + mbedtls_printf("%02x", hash[j]); + } + + mbedtls_printf("\n"); + + mbedtls_psa_crypto_free(); + return EXIT_SUCCESS; + +cleanup: + psa_hash_abort(&hash_operation); + psa_hash_abort(&cloned_hash_operation); + return EXIT_FAILURE; +} +#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */ From eb7ef78f7427a93ad2aef85b0bbb0800a37f3321 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 10 Jun 2024 20:11:43 +0200 Subject: [PATCH 040/125] psa_sim_crypto_[client/server]: check if CRYPTO_C is enabled CRYPTO_C must or must-not be enabled on client and server sides as follows: - if it's enabled while building the client side it's a failure; - it it's NOT enabled while building the server it's a failure. Signed-off-by: Valerio Setti --- psasim/src/psa_sim_crypto_client.c | 4 ++++ psasim/src/psa_sim_crypto_server.c | 4 ++++ psasim/src/psa_sim_generate.pl | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 4ac6c4a581..5811ac5e3f 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -26,6 +26,10 @@ static psa_handle_t handle = -1; +#if defined(MBEDTLS_PSA_CRYPTO_C) +#error "Error: MBEDTLS_PSA_CRYPTO_C must be disabled on client build" +#endif + int psa_crypto_call(int function, uint8_t *in_params, size_t in_params_len, uint8_t **out_params, size_t *out_params_len) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index e511c74fa2..581254259e 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -17,6 +17,10 @@ #include "service.h" +#if !defined(MBEDTLS_PSA_CRYPTO_C) +#error "Error: MBEDTLS_PSA_CRYPTO_C must be enabled on server build" +#endif + // Returns 1 for success, 0 for failure int psa_crypto_init_wrapper( uint8_t *in_params, size_t in_params_len, diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index efd50aa846..cd0e3eba37 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -268,6 +268,10 @@ sub server_implementations_header #include "psa_sim_serialise.h" #include "service.h" + +#if !defined(MBEDTLS_PSA_CRYPTO_C) +#error "Error: MBEDTLS_PSA_CRYPTO_C must be enabled on server build" +#endif EOF } @@ -301,6 +305,10 @@ sub client_calls_header PRINT("Client: " fmt, ##__VA_ARGS__) static psa_handle_t handle = -1; + +#if defined(MBEDTLS_PSA_CRYPTO_C) +#error "Error: MBEDTLS_PSA_CRYPTO_C must be disabled on client build" +#endif EOF $code .= debug_functions() if $debug; From 5096a3ebcb0bb1debabe6784a1d5a56ae577f728 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 10 Jun 2024 20:13:13 +0200 Subject: [PATCH 041/125] psasim: build server library and binary before client's ones This allows to keep the same CONFIG_H while building the Mbed TLS library and the application (no matter if it's client or server). Signed-off-by: Valerio Setti --- psasim/Makefile | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/psasim/Makefile b/psasim/Makefile index 06d3059b4b..38dbef6cd6 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -12,9 +12,6 @@ LIBPSASERVER := -Llibpsaserver/ -lmbedcrypto MBEDTLS_ROOT_PATH = ../../.. COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/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 @@ -33,7 +30,7 @@ PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ .PHONY: all clean libpsaclient libpsaserver -all: $(TEST_BIN) +all: test/seedfile: dd if=/dev/urandom of=./test/seedfile bs=64 count=1 @@ -59,7 +56,7 @@ libpsaclient libpsaserver: $(MAKE) -C $(MBEDTLS_ROOT_PATH) clean clean: - rm -f $(TEST_BIN) + rm -f test/psa_client test/psa_partition rm -f $(PARTITION_SERVER_BOOTSTRAP) rm -rf libpsaclient libpsaserver rm -rf include/psa_manifest From 0ad794021b9e4f49517336a3c9aaec1334e3031c Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 11 Jun 2024 17:19:31 +0100 Subject: [PATCH 042/125] Have PSA sim client wrappers say which call fails, if one does Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_crypto_client.c | 16 ++++++++-------- psasim/src/psa_sim_generate.pl | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 5811ac5e3f..505a976d0b 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -158,7 +158,7 @@ psa_status_t psa_hash_abort( ok = psa_crypto_call(PSA_HASH_ABORT, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\n"); + printf("PSA_HASH_ABORT server call failed\n"); goto fail; } @@ -227,7 +227,7 @@ psa_status_t psa_hash_clone( ok = psa_crypto_call(PSA_HASH_CLONE, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\n"); + printf("PSA_HASH_CLONE server call failed\n"); goto fail; } @@ -302,7 +302,7 @@ psa_status_t psa_hash_compare( ok = psa_crypto_call(PSA_HASH_COMPARE, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\n"); + printf("PSA_HASH_COMPARE server call failed\n"); goto fail; } @@ -378,7 +378,7 @@ psa_status_t psa_hash_compute( ok = psa_crypto_call(PSA_HASH_COMPUTE, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\n"); + printf("PSA_HASH_COMPUTE server call failed\n"); goto fail; } @@ -458,7 +458,7 @@ psa_status_t psa_hash_finish( ok = psa_crypto_call(PSA_HASH_FINISH, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\n"); + printf("PSA_HASH_FINISH server call failed\n"); goto fail; } @@ -537,7 +537,7 @@ psa_status_t psa_hash_setup( ok = psa_crypto_call(PSA_HASH_SETUP, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\n"); + printf("PSA_HASH_SETUP server call failed\n"); goto fail; } @@ -606,7 +606,7 @@ psa_status_t psa_hash_update( ok = psa_crypto_call(PSA_HASH_UPDATE, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\n"); + printf("PSA_HASH_UPDATE server call failed\n"); goto fail; } @@ -675,7 +675,7 @@ psa_status_t psa_hash_verify( ok = psa_crypto_call(PSA_HASH_VERIFY, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\n"); + printf("PSA_HASH_VERIFY server call failed\n"); goto fail; } diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index cd0e3eba37..9765de796c 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -803,7 +803,7 @@ sub output_client ok = psa_crypto_call($enum, params, (size_t) (pos - params), &result, &result_length); if (!ok) { - printf("XXX server call failed\\n"); + printf("$enum server call failed\\n"); goto fail; } EOF From 8377744879a9a0cdd5425e0c939b53485cb5aaac Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 11 Jun 2024 17:21:15 +0100 Subject: [PATCH 043/125] Make it possible to pass arguments to PSA sim psa_client Signed-off-by: Tom Cosgrove --- psasim/test/run_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh index 31429c8bb5..45a317a24e 100755 --- a/psasim/test/run_test.sh +++ b/psasim/test/run_test.sh @@ -33,5 +33,5 @@ clean_run ./psa_partition -k & SERV_PID=$! wait_for_server_startup -./psa_client +./psa_client "$@" wait $SERV_PID From 6b961834fbf2d29431bc622f4c76c4a45533c85a Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 11 Jun 2024 17:26:17 +0100 Subject: [PATCH 044/125] Add support for and run (a copy of) the PSA aead_demo program under PSA sim Signed-off-by: Tom Cosgrove --- psasim/src/aut_psa_aead_demo.c | 283 ++++++ psasim/src/psa_functions_codes.h | 15 + psasim/src/psa_sim_crypto_client.c | 1210 +++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 1478 ++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 936 ++++++++++++++++++ psasim/src/psa_sim_serialise.c | 198 ++++ psasim/src/psa_sim_serialise.h | 168 ++++ psasim/src/psa_sim_serialise.pl | 6 +- 8 files changed, 4293 insertions(+), 1 deletion(-) create mode 100644 psasim/src/aut_psa_aead_demo.c diff --git a/psasim/src/aut_psa_aead_demo.c b/psasim/src/aut_psa_aead_demo.c new file mode 100644 index 0000000000..4a46c4039c --- /dev/null +++ b/psasim/src/aut_psa_aead_demo.c @@ -0,0 +1,283 @@ +/** + * PSA API multi-part AEAD demonstration. + * + * This program AEAD-encrypts a message, using the algorithm and key size + * specified on the command line, using the multi-part API. + * + * It comes with a companion program cipher/cipher_aead_demo.c, which does the + * same operations with the legacy Cipher API. The goal is that comparing the + * two programs will help people migrating to the PSA Crypto API. + * + * When used with multi-part AEAD operations, the `mbedtls_cipher_context` + * serves a triple purpose (1) hold the key, (2) store the algorithm when no + * operation is active, and (3) save progress information for the current + * operation. With PSA those roles are held by disinct objects: (1) a + * psa_key_id_t to hold the key, a (2) psa_algorithm_t to represent the + * algorithm, and (3) a psa_operation_t for multi-part progress. + * + * On the other hand, with PSA, the algorithms encodes the desired tag length; + * with Cipher the desired tag length needs to be tracked separately. + * + * This program and its companion cipher/cipher_aead_demo.c illustrate this by + * doing the same sequence of multi-part AEAD computation with both APIs; + * looking at the two side by side should make the differences and + * similarities clear. + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* First include Mbed TLS headers to get the Mbed TLS configuration and + * platform definitions that we'll use in this program. Also include + * standard C headers for functions we'll use here. */ +#include "mbedtls/build_info.h" + +#include "psa/crypto.h" + +#include +#include +#include + +/* If the build options we need are not enabled, compile a placeholder. */ +#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ + (!defined(MBEDTLS_PSA_CRYPTO_C) || \ + !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ + !defined(MBEDTLS_CHACHAPOLY_C) || \ + defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)) +int main(void) +{ + printf("MBEDTLS_PSA_CRYPTO_CLIENT or " + "MBEDTLS_PSA_CRYPTO_C and/or " + "MBEDTLS_AES_C and/or MBEDTLS_GCM_C and/or " + "MBEDTLS_CHACHAPOLY_C not defined, and/or " + "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n"); + return 0; +} +#else + +/* The real program starts here. */ + +const char usage[] = + "Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; + +/* Dummy data for encryption: IV/nonce, additional data, 2-part message */ +const unsigned char iv1[12] = { 0x00 }; +const unsigned char add_data1[] = { 0x01, 0x02 }; +const unsigned char msg1_part1[] = { 0x03, 0x04 }; +const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 }; + +/* Dummy data (2nd message) */ +const unsigned char iv2[12] = { 0x10 }; +const unsigned char add_data2[] = { 0x11, 0x12 }; +const unsigned char msg2_part1[] = { 0x13, 0x14 }; +const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 }; + +/* Maximum total size of the messages */ +#define MSG1_SIZE (sizeof(msg1_part1) + sizeof(msg1_part2)) +#define MSG2_SIZE (sizeof(msg2_part1) + sizeof(msg2_part2)) +#define MSG_MAX_SIZE (MSG1_SIZE > MSG2_SIZE ? MSG1_SIZE : MSG2_SIZE) + +/* Dummy key material - never do this in production! + * 32-byte is enough to all the key size supported by this program. */ +const unsigned char key_bytes[32] = { 0x2a }; + +/* Print the contents of a buffer in hex */ +void print_buf(const char *title, uint8_t *buf, size_t len) +{ + printf("%s:", title); + for (size_t i = 0; i < len; i++) { + printf(" %02x", buf[i]); + } + printf("\n"); +} + +/* Run a PSA function and bail out if it fails. + * The symbolic name of the error code can be recovered using: + * programs/psa/psa_constant_name status */ +#define PSA_CHECK(expr) \ + do \ + { \ + status = (expr); \ + if (status != PSA_SUCCESS) \ + { \ + printf("Error %d at line %d: %s\n", \ + (int) status, \ + __LINE__, \ + #expr); \ + goto exit; \ + } \ + } \ + while (0) + +/* + * Prepare encryption material: + * - interpret command-line argument + * - set up key + * - outputs: key and algorithm, which together hold all the information + */ +static psa_status_t aead_prepare(const char *info, + psa_key_id_t *key, + psa_algorithm_t *alg) +{ + psa_status_t status; + + /* Convert arg to alg + key_bits + key_type */ + size_t key_bits; + psa_key_type_t key_type; + if (strcmp(info, "aes128-gcm") == 0) { + *alg = PSA_ALG_GCM; + key_bits = 128; + key_type = PSA_KEY_TYPE_AES; + } else if (strcmp(info, "aes256-gcm") == 0) { + *alg = PSA_ALG_GCM; + key_bits = 256; + key_type = PSA_KEY_TYPE_AES; + } else if (strcmp(info, "aes128-gcm_8") == 0) { + *alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8); + key_bits = 128; + key_type = PSA_KEY_TYPE_AES; + } else if (strcmp(info, "chachapoly") == 0) { + *alg = PSA_ALG_CHACHA20_POLY1305; + key_bits = 256; + key_type = PSA_KEY_TYPE_CHACHA20; + } else { + puts(usage); + return PSA_ERROR_INVALID_ARGUMENT; + } + + /* Prepare key attributes */ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, *alg); + psa_set_key_type(&attributes, key_type); + psa_set_key_bits(&attributes, key_bits); // optional + + /* Import key */ + PSA_CHECK(psa_import_key(&attributes, key_bytes, key_bits / 8, key)); + +exit: + return status; +} + +/* + * Print out some information. + * + * All of this information was present in the command line argument, but his + * function demonstrates how each piece can be recovered from (key, alg). + */ +static void aead_info(psa_key_id_t key, psa_algorithm_t alg) +{ + psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT; + (void) psa_get_key_attributes(key, &attr); + psa_key_type_t key_type = psa_get_key_type(&attr); + size_t key_bits = psa_get_key_bits(&attr); + psa_algorithm_t base_alg = PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg); + size_t tag_len = PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg); + + const char *type_str = key_type == PSA_KEY_TYPE_AES ? "AES" + : key_type == PSA_KEY_TYPE_CHACHA20 ? "Chacha" + : "???"; + const char *base_str = base_alg == PSA_ALG_GCM ? "GCM" + : base_alg == PSA_ALG_CHACHA20_POLY1305 ? "ChachaPoly" + : "???"; + + printf("%s, %u, %s, %u\n", + type_str, (unsigned) key_bits, base_str, (unsigned) tag_len); +} + +/* + * Encrypt a 2-part message. + */ +static int aead_encrypt(psa_key_id_t key, psa_algorithm_t alg, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *part1, size_t part1_len, + const unsigned char *part2, size_t part2_len) +{ + psa_status_t status; + size_t olen, olen_tag; + unsigned char out[PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(MSG_MAX_SIZE)]; + unsigned char *p = out, *end = out + sizeof(out); + unsigned char tag[PSA_AEAD_TAG_MAX_SIZE]; + + psa_aead_operation_t op = PSA_AEAD_OPERATION_INIT; + PSA_CHECK(psa_aead_encrypt_setup(&op, key, alg)); + + PSA_CHECK(psa_aead_set_nonce(&op, iv, iv_len)); + PSA_CHECK(psa_aead_update_ad(&op, ad, ad_len)); + PSA_CHECK(psa_aead_update(&op, part1, part1_len, p, end - p, &olen)); + p += olen; + PSA_CHECK(psa_aead_update(&op, part2, part2_len, p, end - p, &olen)); + p += olen; + PSA_CHECK(psa_aead_finish(&op, p, end - p, &olen, + tag, sizeof(tag), &olen_tag)); + p += olen; + memcpy(p, tag, olen_tag); + p += olen_tag; + + olen = p - out; + print_buf("out", out, olen); + +exit: + psa_aead_abort(&op); // required on errors, harmless on success + return status; +} + +/* + * AEAD demo: set up key/alg, print out info, encrypt messages. + */ +static psa_status_t aead_demo(const char *info) +{ + psa_status_t status; + + psa_key_id_t key; + psa_algorithm_t alg; + + PSA_CHECK(aead_prepare(info, &key, &alg)); + + aead_info(key, alg); + + PSA_CHECK(aead_encrypt(key, alg, + iv1, sizeof(iv1), add_data1, sizeof(add_data1), + msg1_part1, sizeof(msg1_part1), + msg1_part2, sizeof(msg1_part2))); + PSA_CHECK(aead_encrypt(key, alg, + iv2, sizeof(iv2), add_data2, sizeof(add_data2), + msg2_part1, sizeof(msg2_part1), + msg2_part2, sizeof(msg2_part2))); + +exit: + psa_destroy_key(key); + + return status; +} + +/* + * Main function + */ +int main(int argc, char **argv) +{ + psa_status_t status = PSA_SUCCESS; + + /* Check usage */ + if (argc != 2) { + puts(usage); + return EXIT_FAILURE; + } + + /* Initialize the PSA crypto library. */ + PSA_CHECK(psa_crypto_init()); + + /* Run the demo */ + PSA_CHECK(aead_demo(argv[1])); + + /* Deinitialize the PSA crypto library. */ + mbedtls_psa_crypto_free(); + +exit: + return status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE; +} + +#endif diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 00937338dd..c68b416096 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -12,6 +12,20 @@ enum { /* Start here to avoid overlap with PSA_IPC_CONNECT, PSA_IPC_DISCONNECT * and VERSION_REQUEST */ PSA_CRYPTO_INIT = 100, + PSA_AEAD_ABORT, + PSA_AEAD_DECRYPT, + PSA_AEAD_DECRYPT_SETUP, + PSA_AEAD_ENCRYPT, + PSA_AEAD_ENCRYPT_SETUP, + PSA_AEAD_FINISH, + PSA_AEAD_GENERATE_NONCE, + PSA_AEAD_SET_LENGTHS, + PSA_AEAD_SET_NONCE, + PSA_AEAD_UPDATE, + PSA_AEAD_UPDATE_AD, + PSA_AEAD_VERIFY, + PSA_DESTROY_KEY, + PSA_GET_KEY_ATTRIBUTES, PSA_HASH_ABORT, PSA_HASH_CLONE, PSA_HASH_COMPARE, @@ -20,6 +34,7 @@ enum { PSA_HASH_SETUP, PSA_HASH_UPDATE, PSA_HASH_VERIFY, + PSA_IMPORT_KEY, }; #endif /* _PSA_FUNCTIONS_CODES_H_ */ diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 505a976d0b..2ffb615de7 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -125,6 +125,1141 @@ void mbedtls_psa_crypto_free(void) } +psa_status_t psa_aead_abort( + psa_aead_operation_t *operation + ) +{ + 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_aead_operation_t_needs(*operation); + + 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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_ABORT, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_ABORT 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_decrypt( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, + size_t *plaintext_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_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(nonce, nonce_length) + + psasim_serialise_buffer_needs(additional_data, additional_data_length) + + psasim_serialise_buffer_needs(ciphertext, ciphertext_length) + + psasim_serialise_buffer_needs(plaintext, plaintext_size) + + psasim_serialise_size_t_needs(*plaintext_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_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, nonce, nonce_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, additional_data, additional_data_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, ciphertext, ciphertext_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, plaintext, plaintext_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *plaintext_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_DECRYPT, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_DECRYPT 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, plaintext, plaintext_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, plaintext_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_decrypt_setup( + psa_aead_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg + ) +{ + 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_aead_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); + + 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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_DECRYPT_SETUP, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_DECRYPT_SETUP 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_encrypt( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, + size_t *ciphertext_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_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(nonce, nonce_length) + + psasim_serialise_buffer_needs(additional_data, additional_data_length) + + psasim_serialise_buffer_needs(plaintext, plaintext_length) + + psasim_serialise_buffer_needs(ciphertext, ciphertext_size) + + psasim_serialise_size_t_needs(*ciphertext_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_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, nonce, nonce_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, additional_data, additional_data_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, plaintext, plaintext_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, ciphertext, ciphertext_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *ciphertext_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_ENCRYPT, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_ENCRYPT 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, ciphertext, ciphertext_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, ciphertext_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_encrypt_setup( + psa_aead_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg + ) +{ + 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_aead_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); + + 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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_ENCRYPT_SETUP, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_ENCRYPT_SETUP 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_finish( + psa_aead_operation_t *operation, + uint8_t *ciphertext, size_t ciphertext_size, + size_t *ciphertext_length, + uint8_t *tag, size_t tag_size, + size_t *tag_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_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(ciphertext, ciphertext_size) + + psasim_serialise_size_t_needs(*ciphertext_length) + + psasim_serialise_buffer_needs(tag, tag_size) + + psasim_serialise_size_t_needs(*tag_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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, ciphertext, ciphertext_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *ciphertext_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, tag, tag_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *tag_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_FINISH, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_FINISH 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, ciphertext, ciphertext_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, ciphertext_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, tag, tag_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, tag_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_generate_nonce( + psa_aead_operation_t *operation, + uint8_t *nonce, size_t nonce_size, + size_t *nonce_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_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(nonce, nonce_size) + + psasim_serialise_size_t_needs(*nonce_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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, nonce, nonce_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *nonce_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_GENERATE_NONCE, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_GENERATE_NONCE 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, nonce, nonce_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, nonce_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_set_lengths( + psa_aead_operation_t *operation, + size_t ad_length, + size_t plaintext_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_aead_operation_t_needs(*operation) + + psasim_serialise_size_t_needs(ad_length) + + psasim_serialise_size_t_needs(plaintext_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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, ad_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, plaintext_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_SET_LENGTHS, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_SET_LENGTHS 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_set_nonce( + psa_aead_operation_t *operation, + const uint8_t *nonce, size_t nonce_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_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(nonce, nonce_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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, nonce, nonce_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_SET_NONCE, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_SET_NONCE 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_update( + psa_aead_operation_t *operation, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, + size_t *output_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_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_UPDATE, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_UPDATE 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_update_ad( + psa_aead_operation_t *operation, + const uint8_t *input, size_t input_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_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_UPDATE_AD, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_UPDATE_AD 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_aead_verify( + psa_aead_operation_t *operation, + uint8_t *plaintext, size_t plaintext_size, + size_t *plaintext_length, + const uint8_t *tag, size_t tag_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_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(plaintext, plaintext_size) + + psasim_serialise_size_t_needs(*plaintext_length) + + psasim_serialise_buffer_needs(tag, tag_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_aead_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, plaintext, plaintext_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *plaintext_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, tag, tag_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_AEAD_VERIFY, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_AEAD_VERIFY 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_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, plaintext, plaintext_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, plaintext_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_destroy_key( + mbedtls_svc_key_id_t key + ) +{ + 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_mbedtls_svc_key_id_t_needs(key); + + 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_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_DESTROY_KEY, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_DESTROY_KEY 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; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_get_key_attributes( + mbedtls_svc_key_id_t key, + psa_key_attributes_t *attributes + ) +{ + 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_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_key_attributes_t_needs(*attributes); + + 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_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_GET_KEY_ATTRIBUTES, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_GET_KEY_ATTRIBUTES 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_psa_key_attributes_t(&rpos, &rremain, attributes); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + psa_status_t psa_hash_abort( psa_hash_operation_t *operation ) @@ -703,3 +1838,78 @@ psa_status_t psa_hash_verify( return status; } + + +psa_status_t psa_import_key( + const psa_key_attributes_t *attributes, + const uint8_t *data, size_t data_length, + mbedtls_svc_key_id_t *key + ) +{ + 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_key_attributes_t_needs(*attributes) + + psasim_serialise_buffer_needs(data, data_length) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + + 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_key_attributes_t(&pos, &remaining, *attributes); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, data, data_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_IMPORT_KEY, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_IMPORT_KEY 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_mbedtls_svc_key_id_t(&rpos, &rremain, key); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 581254259e..da3adb0d31 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -70,6 +70,1336 @@ int psa_crypto_init_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_aead_abort_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_aead_operation_t *operation; + + 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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_abort( + operation + ); + + // 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_server_serialise_psa_aead_operation_t_needs(operation); + + 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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + 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_aead_decrypt_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *nonce = NULL; + size_t nonce_length; + uint8_t *additional_data = NULL; + size_t additional_data_length; + uint8_t *ciphertext = NULL; + size_t ciphertext_length; + uint8_t *plaintext = NULL; + size_t plaintext_size; + size_t plaintext_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &nonce, &nonce_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &additional_data, &additional_data_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &ciphertext, &ciphertext_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &plaintext, &plaintext_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &plaintext_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_decrypt( + key, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + ciphertext, ciphertext_length, + plaintext, plaintext_size, + &plaintext_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(plaintext, plaintext_size) + + psasim_serialise_size_t_needs(plaintext_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, plaintext, plaintext_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, plaintext_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(nonce); + free(additional_data); + free(ciphertext); + free(plaintext); + + return 1; // success + +fail: + free(result); + + free(nonce); + free(additional_data); + free(ciphertext); + free(plaintext); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_aead_decrypt_setup_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_aead_operation_t *operation; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + + 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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_decrypt_setup( + operation, + key, + alg + ); + + // 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_server_serialise_psa_aead_operation_t_needs(operation); + + 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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + 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_aead_encrypt_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *nonce = NULL; + size_t nonce_length; + uint8_t *additional_data = NULL; + size_t additional_data_length; + uint8_t *plaintext = NULL; + size_t plaintext_length; + uint8_t *ciphertext = NULL; + size_t ciphertext_size; + size_t ciphertext_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &nonce, &nonce_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &additional_data, &additional_data_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &plaintext, &plaintext_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &ciphertext, &ciphertext_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &ciphertext_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_encrypt( + key, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + plaintext, plaintext_length, + ciphertext, ciphertext_size, + &ciphertext_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(ciphertext, ciphertext_size) + + psasim_serialise_size_t_needs(ciphertext_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, ciphertext, ciphertext_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, ciphertext_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(nonce); + free(additional_data); + free(plaintext); + free(ciphertext); + + return 1; // success + +fail: + free(result); + + free(nonce); + free(additional_data); + free(plaintext); + free(ciphertext); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_aead_encrypt_setup_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_aead_operation_t *operation; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + + 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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_encrypt_setup( + operation, + key, + alg + ); + + // 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_server_serialise_psa_aead_operation_t_needs(operation); + + 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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + 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_aead_finish_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_aead_operation_t *operation; + uint8_t *ciphertext = NULL; + size_t ciphertext_size; + size_t ciphertext_length; + uint8_t *tag = NULL; + size_t tag_size; + size_t tag_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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &ciphertext, &ciphertext_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &ciphertext_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &tag, &tag_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &tag_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_finish( + operation, + ciphertext, ciphertext_size, + &ciphertext_length, + tag, tag_size, + &tag_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_server_serialise_psa_aead_operation_t_needs(operation) + + psasim_serialise_buffer_needs(ciphertext, ciphertext_size) + + psasim_serialise_size_t_needs(ciphertext_length) + + psasim_serialise_buffer_needs(tag, tag_size) + + psasim_serialise_size_t_needs(tag_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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, ciphertext, ciphertext_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, ciphertext_length); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, tag, tag_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, tag_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(ciphertext); + free(tag); + + return 1; // success + +fail: + free(result); + + free(ciphertext); + free(tag); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_aead_generate_nonce_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_aead_operation_t *operation; + uint8_t *nonce = NULL; + size_t nonce_size; + size_t nonce_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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &nonce, &nonce_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &nonce_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_generate_nonce( + operation, + nonce, nonce_size, + &nonce_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_server_serialise_psa_aead_operation_t_needs(operation) + + psasim_serialise_buffer_needs(nonce, nonce_size) + + psasim_serialise_size_t_needs(nonce_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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, nonce, nonce_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, nonce_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(nonce); + + return 1; // success + +fail: + free(result); + + free(nonce); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_aead_set_lengths_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_aead_operation_t *operation; + size_t ad_length; + size_t plaintext_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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &ad_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &plaintext_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_set_lengths( + operation, + ad_length, + plaintext_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_server_serialise_psa_aead_operation_t_needs(operation); + + 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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + 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_aead_set_nonce_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_aead_operation_t *operation; + uint8_t *nonce = NULL; + size_t nonce_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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &nonce, &nonce_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_set_nonce( + operation, + nonce, nonce_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_server_serialise_psa_aead_operation_t_needs(operation); + + 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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(nonce); + + return 1; // success + +fail: + free(result); + + free(nonce); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_aead_update_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_aead_operation_t *operation; + uint8_t *input = NULL; + size_t input_length; + uint8_t *output = NULL; + size_t output_size; + size_t output_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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_update( + operation, + input, input_length, + output, output_size, + &output_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_server_serialise_psa_aead_operation_t_needs(operation) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(output_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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(output); + + return 1; // success + +fail: + free(result); + + free(input); + free(output); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_aead_update_ad_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_aead_operation_t *operation; + uint8_t *input = NULL; + size_t input_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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_update_ad( + operation, + input, input_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_server_serialise_psa_aead_operation_t_needs(operation); + + 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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + + return 1; // success + +fail: + free(result); + + free(input); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_aead_verify_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_aead_operation_t *operation; + uint8_t *plaintext = NULL; + size_t plaintext_size; + size_t plaintext_length; + uint8_t *tag = NULL; + size_t tag_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_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &plaintext, &plaintext_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &plaintext_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &tag, &tag_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_aead_verify( + operation, + plaintext, plaintext_size, + &plaintext_length, + tag, tag_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_server_serialise_psa_aead_operation_t_needs(operation) + + psasim_serialise_buffer_needs(plaintext, plaintext_size) + + psasim_serialise_size_t_needs(plaintext_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_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, plaintext, plaintext_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, plaintext_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(plaintext); + free(tag); + + return 1; // success + +fail: + free(result); + + free(plaintext); + free(tag); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_destroy_key_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; + mbedtls_svc_key_id_t key; + + 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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_destroy_key( + key + ); + + // 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_get_key_attributes_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; + mbedtls_svc_key_id_t key; + psa_key_attributes_t attributes; + + 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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_get_key_attributes( + key, + &attributes + ); + + // 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_psa_key_attributes_t_needs(attributes); + + 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_psa_key_attributes_t(&rpos, &rremain, attributes); + 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_abort_wrapper( uint8_t *in_params, size_t in_params_len, @@ -742,6 +2072,94 @@ int psa_hash_verify_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_import_key_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_key_attributes_t attributes; + uint8_t *data = NULL; + size_t data_length; + mbedtls_svc_key_id_t key; + + 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_key_attributes_t(&pos, &remaining, &attributes); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &data, &data_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_import_key( + &attributes, + data, data_length, + &key + ); + + // 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_mbedtls_svc_key_id_t_needs(key); + + 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_mbedtls_svc_key_id_t(&rpos, &rremain, key); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(data); + + return 1; // success + +fail: + free(result); + + free(data); + + return 0; // This shouldn't happen! +} + psa_status_t psa_crypto_call(psa_msg_t msg) { int ok = 0; @@ -782,6 +2200,62 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_crypto_init_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_AEAD_ABORT: + ok = psa_aead_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_DECRYPT: + ok = psa_aead_decrypt_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_DECRYPT_SETUP: + ok = psa_aead_decrypt_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_ENCRYPT: + ok = psa_aead_encrypt_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_ENCRYPT_SETUP: + ok = psa_aead_encrypt_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_FINISH: + ok = psa_aead_finish_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_GENERATE_NONCE: + ok = psa_aead_generate_nonce_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_SET_LENGTHS: + ok = psa_aead_set_lengths_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_SET_NONCE: + ok = psa_aead_set_nonce_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_UPDATE: + ok = psa_aead_update_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_UPDATE_AD: + ok = psa_aead_update_ad_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_AEAD_VERIFY: + ok = psa_aead_verify_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_DESTROY_KEY: + ok = psa_destroy_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_GET_KEY_ATTRIBUTES: + ok = psa_get_key_attributes_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_HASH_ABORT: ok = psa_hash_abort_wrapper(in_params, in_params_len, &out_params, &out_params_len); @@ -814,6 +2288,10 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_hash_verify_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_IMPORT_KEY: + ok = psa_import_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; } free(in_params); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 9765de796c..ee3894f0ee 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -1425,3 +1425,939 @@ sub put_crypto_init_first size_t input_length, const uint8_t *hash, size_t hash_length); + +/** Process an authenticated encryption operation. + * + * \param key Identifier of the key to use for the + * operation. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. + * \param alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param[in] nonce Nonce or IV to use. + * \param nonce_length Size of the \p nonce buffer in bytes. + * \param[in] additional_data Additional data that will be authenticated + * but not encrypted. + * \param additional_data_length Size of \p additional_data in bytes. + * \param[in] plaintext Data that will be authenticated and + * encrypted. + * \param plaintext_length Size of \p plaintext in bytes. + * \param[out] ciphertext Output buffer for the authenticated and + * encrypted data. The additional data is not + * part of this output. For algorithms where the + * encrypted data and the authentication tag + * are defined as separate outputs, the + * authentication tag is appended to the + * encrypted data. + * \param ciphertext_size Size of the \p ciphertext buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, + * \p alg, \p plaintext_length) where + * \c key_type is the type of \p key. + * - #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p + * plaintext_length) evaluates to the maximum + * ciphertext size of any supported AEAD + * encryption. + * \param[out] ciphertext_length On success, the size of the output + * in the \p ciphertext buffer. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not an AEAD algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p ciphertext_size is too small. + * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, \p alg, + * \p plaintext_length) or + * #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length) can be used to + * determine the required buffer size. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *nonce, + size_t nonce_length, + const uint8_t *additional_data, + size_t additional_data_length, + const uint8_t *plaintext, + size_t plaintext_length, + uint8_t *ciphertext, + size_t ciphertext_size, + size_t *ciphertext_length); + +/** Process an authenticated decryption operation. + * + * \param key Identifier of the key to use for the + * operation. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. + * \param alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param[in] nonce Nonce or IV to use. + * \param nonce_length Size of the \p nonce buffer in bytes. + * \param[in] additional_data Additional data that has been authenticated + * but not encrypted. + * \param additional_data_length Size of \p additional_data in bytes. + * \param[in] ciphertext Data that has been authenticated and + * encrypted. For algorithms where the + * encrypted data and the authentication tag + * are defined as separate inputs, the buffer + * must contain the encrypted data followed + * by the authentication tag. + * \param ciphertext_length Size of \p ciphertext in bytes. + * \param[out] plaintext Output buffer for the decrypted data. + * \param plaintext_size Size of the \p plaintext buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, + * \p alg, \p ciphertext_length) where + * \c key_type is the type of \p key. + * - #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p + * ciphertext_length) evaluates to the maximum + * plaintext size of any supported AEAD + * decryption. + * \param[out] plaintext_length On success, the size of the output + * in the \p plaintext buffer. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The ciphertext is not authentic. + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not an AEAD algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p plaintext_size is too small. + * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, \p alg, + * \p ciphertext_length) or + * #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length) can be used + * to determine the required buffer size. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *nonce, + size_t nonce_length, + const uint8_t *additional_data, + size_t additional_data_length, + const uint8_t *ciphertext, + size_t ciphertext_length, + uint8_t *plaintext, + size_t plaintext_size, + size_t *plaintext_length); + +/** The type of the state data structure for multipart AEAD operations. + * + * Before calling any function on an AEAD operation object, the application + * must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_aead_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_aead_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_AEAD_OPERATION_INIT, + * for example: + * \code + * psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_aead_operation_init() + * to the structure, for example: + * \code + * psa_aead_operation_t operation; + * operation = psa_aead_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ +typedef struct psa_aead_operation_s psa_aead_operation_t; + +/** \def PSA_AEAD_OPERATION_INIT + * + * This macro returns a suitable initializer for an AEAD operation object of + * type #psa_aead_operation_t. + */ + +/** Return an initial value for an AEAD operation object. + */ +static psa_aead_operation_t psa_aead_operation_init(void); + +/** Set the key for a multipart authenticated encryption operation. + * + * The sequence of operations to encrypt a message with authentication + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_aead_operation_t, e.g. + * #PSA_AEAD_OPERATION_INIT. + * -# Call psa_aead_encrypt_setup() to specify the algorithm and key. + * -# If needed, call psa_aead_set_lengths() to specify the length of the + * inputs to the subsequent calls to psa_aead_update_ad() and + * psa_aead_update(). See the documentation of psa_aead_set_lengths() + * for details. + * -# Call either psa_aead_generate_nonce() or psa_aead_set_nonce() to + * generate or set the nonce. You should use + * psa_aead_generate_nonce() unless the protocol you are implementing + * requires a specific nonce value. + * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment + * of the non-encrypted additional authenticated data each time. + * -# Call psa_aead_update() zero, one or more times, passing a fragment + * of the message to encrypt each time. + * -# Call psa_aead_finish(). + * + * If an error occurs at any step after a call to psa_aead_encrypt_setup(), + * the operation will need to be reset by a call to psa_aead_abort(). The + * application may call psa_aead_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_aead_encrypt_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_aead_finish(). + * - A call to psa_aead_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_aead_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. + * \param alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive), or + * the library has not been previously initialized by psa_crypto_init(). + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not an AEAD algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Set the key for a multipart authenticated decryption operation. + * + * The sequence of operations to decrypt a message with authentication + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_aead_operation_t, e.g. + * #PSA_AEAD_OPERATION_INIT. + * -# Call psa_aead_decrypt_setup() to specify the algorithm and key. + * -# If needed, call psa_aead_set_lengths() to specify the length of the + * inputs to the subsequent calls to psa_aead_update_ad() and + * psa_aead_update(). See the documentation of psa_aead_set_lengths() + * for details. + * -# Call psa_aead_set_nonce() with the nonce for the decryption. + * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment + * of the non-encrypted additional authenticated data each time. + * -# Call psa_aead_update() zero, one or more times, passing a fragment + * of the ciphertext to decrypt each time. + * -# Call psa_aead_verify(). + * + * If an error occurs at any step after a call to psa_aead_decrypt_setup(), + * the operation will need to be reset by a call to psa_aead_abort(). The + * application may call psa_aead_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_aead_decrypt_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_aead_verify(). + * - A call to psa_aead_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_aead_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. + * \param alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not an AEAD algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive), or the + * library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Generate a random nonce for an authenticated encryption operation. + * + * This function generates a random nonce for the authenticated encryption + * operation with an appropriate size for the chosen algorithm, key type + * and key size. + * + * The application must call psa_aead_encrypt_setup() before + * calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \param[in,out] operation Active AEAD operation. + * \param[out] nonce Buffer where the generated nonce is to be + * written. + * \param nonce_size Size of the \p nonce buffer in bytes. + * \param[out] nonce_length On success, the number of bytes of the + * generated nonce. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p nonce buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active aead encrypt + * operation, with no nonce set), or the library has not been + * previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, + uint8_t *nonce, + size_t nonce_size, + size_t *nonce_length); + +/** Set the nonce for an authenticated encryption or decryption operation. + * + * This function sets the nonce for the authenticated + * encryption or decryption operation. + * + * The application must call psa_aead_encrypt_setup() or + * psa_aead_decrypt_setup() before calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \note When encrypting, applications should use psa_aead_generate_nonce() + * instead of this function, unless implementing a protocol that requires + * a non-random IV. + * + * \param[in,out] operation Active AEAD operation. + * \param[in] nonce Buffer containing the nonce to use. + * \param nonce_length Size of the nonce in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The size of \p nonce is not acceptable for the chosen algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, with no nonce + * set), or the library has not been previously initialized + * by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, + const uint8_t *nonce, + size_t nonce_length); + +/** Declare the lengths of the message and additional data for AEAD. + * + * The application must call this function before calling + * psa_aead_update_ad() or psa_aead_update() if the algorithm for + * the operation requires it. If the algorithm does not require it, + * calling this function is optional, but if this function is called + * then the implementation must enforce the lengths. + * + * You may call this function before or after setting the nonce with + * psa_aead_set_nonce() or psa_aead_generate_nonce(). + * + * - For #PSA_ALG_CCM, calling this function is required. + * - For the other AEAD algorithms defined in this specification, calling + * this function is not required. + * - For vendor-defined algorithm, refer to the vendor documentation. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \param[in,out] operation Active AEAD operation. + * \param ad_length Size of the non-encrypted additional + * authenticated data in bytes. + * \param plaintext_length Size of the plaintext to encrypt in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * At least one of the lengths is not acceptable for the chosen + * algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, and + * psa_aead_update_ad() and psa_aead_update() must not have been + * called yet), or the library has not been previously initialized + * by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, + size_t ad_length, + size_t plaintext_length); + +/** Pass additional data to an active AEAD operation. + * + * Additional data is authenticated, but not encrypted. + * + * You may call this function multiple times to pass successive fragments + * of the additional data. You may not call this function after passing + * data to encrypt or decrypt with psa_aead_update(). + * + * Before calling this function, you must: + * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). + * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, + * there is no guarantee that the input is valid. Therefore, until + * you have called psa_aead_verify() and it has returned #PSA_SUCCESS, + * treat the input as untrusted and prepare to undo any action that + * depends on the input if psa_aead_verify() returns an error status. + * + * \param[in,out] operation Active AEAD operation. + * \param[in] input Buffer containing the fragment of + * additional data. + * \param input_length Size of the \p input buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total input length overflows the additional data length that + * was previously specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, have a nonce + * set, have lengths set if required by the algorithm, and + * psa_aead_update() must not have been called yet), or the library + * has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, + const uint8_t *input, + size_t input_length); + +/** Encrypt or decrypt a message fragment in an active AEAD operation. + * + * Before calling this function, you must: + * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). + * The choice of setup function determines whether this function + * encrypts or decrypts its input. + * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). + * 3. Call psa_aead_update_ad() to pass all the additional data. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, + * there is no guarantee that the input is valid. Therefore, until + * you have called psa_aead_verify() and it has returned #PSA_SUCCESS: + * - Do not use the output in any way other than storing it in a + * confidential location. If you take any action that depends + * on the tentative decrypted data, this action will need to be + * undone if the input turns out not to be valid. Furthermore, + * if an adversary can observe that this action took place + * (for example through timing), they may be able to use this + * fact as an oracle to decrypt any message encrypted with the + * same key. + * - In particular, do not copy the output anywhere but to a + * memory or storage space that you have exclusive access to. + * + * This function does not require the input to be aligned to any + * particular block boundary. If the implementation can only process + * a whole block at a time, it must consume all the input provided, but + * it may delay the end of the corresponding output until a subsequent + * call to psa_aead_update(), psa_aead_finish() or psa_aead_verify() + * provides sufficient input. The amount of data that can be delayed + * in this way is bounded by #PSA_AEAD_UPDATE_OUTPUT_SIZE. + * + * \param[in,out] operation Active AEAD operation. + * \param[in] input Buffer containing the message fragment to + * encrypt or decrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the output is to be written. + * \param output_size Size of the \p output buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, + * \c alg, \p input_length) where + * \c key_type is the type of key and \c alg is + * the algorithm that were used to set up the + * operation. + * - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p + * input_length) evaluates to the maximum + * output size of any supported AEAD + * algorithm. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or + * #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to + * determine the required buffer size. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total length of input to psa_aead_update_ad() so far is + * less than the additional data length that was previously + * specified with psa_aead_set_lengths(), or + * the total input length overflows the plaintext length that + * was previously specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, have a nonce + * set, and have lengths set if required by the algorithm), or the + * library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_update(psa_aead_operation_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Finish encrypting a message in an AEAD operation. + * + * The operation must have been set up with psa_aead_encrypt_setup(). + * + * This function finishes the authentication of the additional data + * formed by concatenating the inputs passed to preceding calls to + * psa_aead_update_ad() with the plaintext formed by concatenating the + * inputs passed to preceding calls to psa_aead_update(). + * + * This function has two output buffers: + * - \p ciphertext contains trailing ciphertext that was buffered from + * preceding calls to psa_aead_update(). + * - \p tag contains the authentication tag. + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \param[in,out] operation Active AEAD operation. + * \param[out] ciphertext Buffer where the last part of the ciphertext + * is to be written. + * \param ciphertext_size Size of the \p ciphertext buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, + * \c alg) where \c key_type is the type of key + * and \c alg is the algorithm that were used to + * set up the operation. + * - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to + * the maximum output size of any supported AEAD + * algorithm. + * \param[out] ciphertext_length On success, the number of bytes of + * returned ciphertext. + * \param[out] tag Buffer where the authentication tag is + * to be written. + * \param tag_size Size of the \p tag buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c + * key_type, \c key_bits, \c alg) where + * \c key_type and \c key_bits are the type and + * bit-size of the key, and \c alg is the + * algorithm that were used in the call to + * psa_aead_encrypt_setup(). + * - #PSA_AEAD_TAG_MAX_SIZE evaluates to the + * maximum tag size of any supported AEAD + * algorithm. + * \param[out] tag_length On success, the number of bytes + * that make up the returned tag. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p ciphertext or \p tag buffer is too small. + * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, \c alg) or + * #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE can be used to determine the + * required \p ciphertext buffer size. #PSA_AEAD_TAG_LENGTH(\c key_type, + * \c key_bits, \c alg) or #PSA_AEAD_TAG_MAX_SIZE can be used to + * determine the required \p tag buffer size. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total length of input to psa_aead_update_ad() so far is + * less than the additional data length that was previously + * specified with psa_aead_set_lengths(), or + * the total length of input to psa_aead_update() so far is + * less than the plaintext length that was previously + * specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active encryption + * operation with a nonce set), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_finish(psa_aead_operation_t *operation, + uint8_t *ciphertext, + size_t ciphertext_size, + size_t *ciphertext_length, + uint8_t *tag, + size_t tag_size, + size_t *tag_length); + +/** Finish authenticating and decrypting a message in an AEAD operation. + * + * The operation must have been set up with psa_aead_decrypt_setup(). + * + * This function finishes the authenticated decryption of the message + * components: + * + * - The additional data consisting of the concatenation of the inputs + * passed to preceding calls to psa_aead_update_ad(). + * - The ciphertext consisting of the concatenation of the inputs passed to + * preceding calls to psa_aead_update(). + * - The tag passed to this function call. + * + * If the authentication tag is correct, this function outputs any remaining + * plaintext and reports success. If the authentication tag is not correct, + * this function returns #PSA_ERROR_INVALID_SIGNATURE. + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \note Implementations shall make the best effort to ensure that the + * comparison between the actual tag and the expected tag is performed + * in constant time. + * + * \param[in,out] operation Active AEAD operation. + * \param[out] plaintext Buffer where the last part of the plaintext + * is to be written. This is the remaining data + * from previous calls to psa_aead_update() + * that could not be processed until the end + * of the input. + * \param plaintext_size Size of the \p plaintext buffer in bytes. + * This must be appropriate for the selected algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, + * \c alg) where \c key_type is the type of key + * and \c alg is the algorithm that were used to + * set up the operation. + * - #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE evaluates to + * the maximum output size of any supported AEAD + * algorithm. + * \param[out] plaintext_length On success, the number of bytes of + * returned plaintext. + * \param[in] tag Buffer containing the authentication tag. + * \param tag_length Size of the \p tag buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculations were successful, but the authentication tag is + * not correct. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p plaintext buffer is too small. + * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, \c alg) or + * #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE can be used to determine the + * required buffer size. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total length of input to psa_aead_update_ad() so far is + * less than the additional data length that was previously + * specified with psa_aead_set_lengths(), or + * the total length of input to psa_aead_update() so far is + * less than the plaintext length that was previously + * specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active decryption + * operation with a nonce set), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_verify(psa_aead_operation_t *operation, + uint8_t *plaintext, + size_t plaintext_size, + size_t *plaintext_length, + const uint8_t *tag, + size_t tag_length); + +/** Abort an AEAD operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * psa_aead_encrypt_setup() or psa_aead_decrypt_setup() again. + * + * You may call this function any time after the operation object has + * been initialized as described in #psa_aead_operation_t. + * + * In particular, calling psa_aead_abort() after the operation has been + * terminated by a call to psa_aead_abort(), psa_aead_finish() or + * psa_aead_verify() is safe and has no effect. + * + * \param[in,out] operation Initialized AEAD operation. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_abort(psa_aead_operation_t *operation); + +/** + * \brief Import a key in binary format. + * + * This function supports any output from psa_export_key(). Refer to the + * documentation of psa_export_public_key() for the format of public keys + * and to the documentation of psa_export_key() for the format for + * other key types. + * + * The key data determines the key size. The attributes may optionally + * specify a key size; in this case it must match the size determined + * from the key data. A key size of 0 in \p attributes indicates that + * the key size is solely determined by the key data. + * + * Implementations must reject an attempt to import a key of size 0. + * + * This specification supports a single format for each key type. + * Implementations may support other formats as long as the standard + * format is supported. Implementations that support other formats + * should ensure that the formats are clearly unambiguous so as to + * minimize the risk that an invalid input is accidentally interpreted + * according to a different format. + * + * \param[in] attributes The attributes for the new key. + * The key size is always determined from the + * \p data buffer. + * If the key size in \p attributes is nonzero, + * it must be equal to the size from \p data. + * \param[out] key On success, an identifier to the newly created key. + * For persistent keys, this is the key identifier + * defined in \p attributes. + * \c 0 on failure. + * \param[in] data Buffer containing the key data. The content of this + * buffer is interpreted according to the type declared + * in \p attributes. + * All implementations must support at least the format + * described in the documentation + * of psa_export_key() or psa_export_public_key() for + * the chosen type. Implementations may allow other + * formats, but should be conservative: implementations + * should err on the side of rejecting content if it + * may be erroneous (e.g. wrong type or truncated data). + * \param data_length Size of the \p data buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The key type or key size is not supported, either by the + * implementation in general or in this particular persistent location. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key attributes, as a whole, are invalid, or + * the key data is not correctly formatted, or + * the size in \p attributes is nonzero and does not match the size + * of the key data. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_import_key(const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + mbedtls_svc_key_id_t *key); + +/** Retrieve the attributes of a key. + * + * This function first resets the attribute structure as with + * psa_reset_key_attributes(). It then copies the attributes of + * the given key into the given attribute structure. + * + * \note This function may allocate memory or other resources. + * Once you have called this function on an attribute structure, + * you must call psa_reset_key_attributes() to free these resources. + * + * \param[in] key Identifier of the key to query. + * \param[in,out] attributes On success, the attributes of the key. + * On failure, equivalent to a + * freshly-initialized structure. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, + psa_key_attributes_t *attributes); + +/** + * \brief Destroy a key. + * + * This function destroys a key from both volatile + * memory and, if applicable, non-volatile storage. Implementations shall + * make a best effort to ensure that the key material cannot be recovered. + * + * This function also erases any metadata such as policies and frees + * resources associated with the key. + * + * If a key is currently in use in a multipart operation, then destroying the + * key will cause the multipart operation to fail. + * + * \warning We can only guarantee that the the key material will + * eventually be wiped from memory. With threading enabled + * and during concurrent execution, copies of the key material may + * still exist until all threads have finished using the key. + * + * \param key Identifier of the key to erase. If this is \c 0, do nothing and + * return #PSA_SUCCESS. + * + * \retval #PSA_SUCCESS + * \p key was a valid identifier and the key material that it + * referred to has been erased. Alternatively, \p key is \c 0. + * \retval #PSA_ERROR_NOT_PERMITTED + * The key cannot be erased because it is + * read-only, either due to a policy or due to physical restrictions. + * \retval #PSA_ERROR_INVALID_HANDLE + * \p key is not a valid identifier nor \c 0. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * There was a failure in communication with the cryptoprocessor. + * The key material may still be present in the cryptoprocessor. + * \retval #PSA_ERROR_DATA_INVALID + * This error is typically a result of either storage corruption on a + * cleartext storage backend, or an attempt to read data that was + * written by an incompatible version of the library. + * \retval #PSA_ERROR_STORAGE_FAILURE + * The storage is corrupted. Implementations shall make a best effort + * to erase key material even in this stage, however applications + * should be aware that it may be impossible to guarantee that the + * key material is not recoverable in such cases. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * An unexpected condition which is not a storage corruption or + * a communication failure occurred. The cryptoprocessor may have + * been compromised. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 348e42c2b4..9e8c38bb57 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -97,6 +97,41 @@ static ssize_t find_hash_slot_by_handle(psasim_client_handle_t handle) return -1; /* all in use */ } +static psa_aead_operation_t aead_operations[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t aead_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t next_aead_operation_handle = 1; + +/* Get a free slot */ +static ssize_t allocate_aead_operation_slot(void) +{ + psasim_client_handle_t handle = next_aead_operation_handle++; + if (next_aead_operation_handle == 0) { /* wrapped around */ + fprintf(stderr, "MAX HASH HANDLES REACHED\n"); + exit(1); + } + + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (aead_operation_handles[i] == 0) { + aead_operation_handles[i] = handle; + return i; + } + } + + return -1; /* all in use */ +} + +/* Find the slot given the handle */ +static ssize_t find_aead_slot_by_handle(psasim_client_handle_t handle) +{ + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (aead_operation_handles[i] == handle) { + return i; + } + } + + return -1; /* all in use */ +} + size_t psasim_serialise_begin_needs(void) { /* The serialisation buffer will @@ -508,3 +543,166 @@ int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos, return 1; } + +size_t psasim_serialise_psa_aead_operation_t_needs(psa_aead_operation_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_aead_operation_t(uint8_t **pos, + size_t *remaining, + psa_aead_operation_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_aead_operation_t(uint8_t **pos, + size_t *remaining, + psa_aead_operation_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_server_serialise_psa_aead_operation_t_needs(psa_aead_operation_t *operation) +{ + (void) operation; + + /* We will actually return a handle */ + return sizeof(psasim_operation_t); +} + +int psasim_server_serialise_psa_aead_operation_t(uint8_t **pos, + size_t *remaining, + psa_aead_operation_t *operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(client_operation)) { + return 0; + } + + ssize_t slot = operation - aead_operations; + + client_operation.handle = aead_operation_handles[slot]; + + memcpy(*pos, &client_operation, sizeof(client_operation)); + *pos += sizeof(client_operation); + + return 1; +} + +int psasim_server_deserialise_psa_aead_operation_t(uint8_t **pos, + size_t *remaining, + psa_aead_operation_t **operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(psasim_operation_t)) { + return 0; + } + + memcpy(&client_operation, *pos, sizeof(psasim_operation_t)); + *pos += sizeof(psasim_operation_t); + *remaining -= sizeof(psasim_operation_t); + + ssize_t slot; + if (client_operation.handle == 0) { /* We need a new handle */ + slot = allocate_aead_operation_slot(); + } else { + slot = find_aead_slot_by_handle(client_operation.handle); + } + + if (slot < 0) { + return 0; + } + + *operation = &aead_operations[slot]; + + return 1; +} + +size_t psasim_serialise_psa_key_attributes_t_needs(psa_key_attributes_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_key_attributes_t(uint8_t **pos, + size_t *remaining, + psa_key_attributes_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_key_attributes_t(uint8_t **pos, + size_t *remaining, + psa_key_attributes_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value) +{ + return sizeof(value); +} + +int psasim_serialise_mbedtls_svc_key_id_t(uint8_t **pos, + size_t *remaining, + mbedtls_svc_key_id_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, + size_t *remaining, + mbedtls_svc_key_id_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 4ec7ec04fb..9c69e65cc0 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -450,3 +450,171 @@ int psasim_server_serialise_psa_hash_operation_t(uint8_t **pos, int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos, size_t *remaining, psa_hash_operation_t **value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_aead_operation_t() + * to serialise a `psa_aead_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_aead_operation_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_aead_operation_t_needs(psa_aead_operation_t value); + +/** Serialise a `psa_aead_operation_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_aead_operation_t(uint8_t **pos, + size_t *remaining, + psa_aead_operation_t value); + +/** Deserialise a `psa_aead_operation_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_aead_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_aead_operation_t(uint8_t **pos, + size_t *remaining, + psa_aead_operation_t *value); + +/** Return how much buffer space is needed by \c psasim_server_serialise_psa_aead_operation_t() + * to serialise a `psa_aead_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_aead_operation_t() to serialise + * the given value. + */ +size_t psasim_server_serialise_psa_aead_operation_t_needs(psa_aead_operation_t *value); + +/** Serialise a `psa_aead_operation_t` into a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_serialise_psa_aead_operation_t(uint8_t **pos, + size_t *remaining, + psa_aead_operation_t *value); + +/** Deserialise a `psa_aead_operation_t` from a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_aead_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_deserialise_psa_aead_operation_t(uint8_t **pos, + size_t *remaining, + psa_aead_operation_t **value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_key_attributes_t() + * to serialise a `psa_key_attributes_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_key_attributes_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_key_attributes_t_needs(psa_key_attributes_t value); + +/** Serialise a `psa_key_attributes_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_key_attributes_t(uint8_t **pos, + size_t *remaining, + psa_key_attributes_t value); + +/** Deserialise a `psa_key_attributes_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_key_attributes_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_key_attributes_t(uint8_t **pos, + size_t *remaining, + psa_key_attributes_t *value); + +/** Return how much buffer space is needed by \c psasim_serialise_mbedtls_svc_key_id_t() + * to serialise a `mbedtls_svc_key_id_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_mbedtls_svc_key_id_t() to serialise + * the given value. + */ +size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value); + +/** Serialise a `mbedtls_svc_key_id_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_mbedtls_svc_key_id_t(uint8_t **pos, + size_t *remaining, + mbedtls_svc_key_id_t value); + +/** Deserialise a `mbedtls_svc_key_id_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `mbedtls_svc_key_id_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, + size_t *remaining, + mbedtls_svc_key_id_t *value); diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index eb2893ea5f..e09bb818a5 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -38,7 +38,11 @@ my @types = qw(unsigned-int int size_t buffer psa_status_t psa_algorithm_t - psa_hash_operation_t); + psa_hash_operation_t + psa_aead_operation_t + psa_key_attributes_t + mbedtls_svc_key_id_t); + grep(s/-/ /g, @types); # IS-A: Some data types are typedef'd; we serialise them as the other type From 016a246324f6b64e2f962615dd7b20f93b26e0e3 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 10 Jun 2024 09:41:49 +0200 Subject: [PATCH 045/125] Adjust build systems Adjust build systems such as we can build Mbed TLS in the default and full configuration. Signed-off-by: Ronald Cron --- psasim/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/Makefile b/psasim/Makefile index 06d3059b4b..093f3b92c7 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -10,7 +10,7 @@ LIBPSACLIENT := -Llibpsaclient/ -lmbedcrypto -lmbedx509 -lmbedtls LIBPSASERVER := -Llibpsaserver/ -lmbedcrypto MBEDTLS_ROOT_PATH = ../../.. -COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include +COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include TEST_BIN = test/psa_client \ test/psa_partition From 1ee5e04f2911d8b2c152cb8ca5b17eb085df3680 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 17 Jun 2024 17:26:10 +0200 Subject: [PATCH 046/125] psa_sim: make server ping time much faster Reduce server's ping time for messages from 50ms to 1us because otherwise tests suites will take forever to execute. Signed-off-by: Valerio Setti --- psasim/src/psa_ff_server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index 219722ad61..7f97b9bf0f 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -26,7 +26,7 @@ #define MAX_CLIENTS 128 #define MAX_MESSAGES 32 -#define SLEEP_MS 50 +#define SLEEP_US 1 struct connection { uint32_t client; @@ -105,7 +105,7 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout) ssize_t len; int idx; #if !defined(PSASIM_USE_USLEEP) - const struct timespec ts_delay = { .tv_sec = 0, .tv_nsec = SLEEP_MS * 1000000 }; + const struct timespec ts_delay = { .tv_sec = 0, .tv_nsec = SLEEP_US * 1000 }; #endif if (timeout == PSA_POLL) { @@ -262,7 +262,7 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout) } else { /* There is no 'select' function in SysV to block on multiple queues, so busy-wait :( */ #if defined(PSASIM_USE_USLEEP) - usleep(SLEEP_MS * 1000); + usleep(SLEEP_US); #else /* PSASIM_USE_USLEEP */ nanosleep(&ts_delay, NULL); #endif /* PSASIM_USE_USLEEP */ From 598e10ec902ad352187deb0b8293af017679d6df Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 17 Jun 2024 17:34:03 +0200 Subject: [PATCH 047/125] psasim-server: add function to reset operations slots When the client disconnects the server can clean operations slots so that upcoming clients will not hit the maximum slot limit (at least it's very unlikely to happen for normal clients). Signed-off-by: Valerio Setti --- psasim/src/psa_sim_crypto_server.c | 5 +++++ psasim/src/psa_sim_serialise.c | 6 ++++++ psasim/src/psa_sim_serialise.h | 2 ++ psasim/src/server.c | 2 ++ 4 files changed, 15 insertions(+) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index da3adb0d31..30d4b26dc8 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -2314,3 +2314,8 @@ psa_status_t psa_crypto_call(psa_msg_t msg) return ok ? PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR; } + +void psa_crypto_close(void) +{ + psa_sim_serialize_reset(); +} diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 9e8c38bb57..e326637a61 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -706,3 +706,9 @@ int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, return 1; } + +void psa_sim_serialize_reset(void) +{ + memset(hash_operation_handles, 0, sizeof(hash_operation_handles)); + memset(hash_operations, 0, sizeof(hash_operations)); +} diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 9c69e65cc0..7217595855 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -54,6 +54,8 @@ * don't contain pointers. */ +void psa_sim_serialize_reset(void); + /** Return how much buffer space is needed by \c psasim_serialise_begin(). * * \return The number of bytes needed in the buffer for diff --git a/psasim/src/server.c b/psasim/src/server.c index 77ce2694e3..10ab5a287f 100644 --- a/psasim/src/server.c +++ b/psasim/src/server.c @@ -54,6 +54,7 @@ int psa_server_main(int argc, char *argv[]) int client_disconnected = 0; char mbedtls_version[18]; extern psa_status_t psa_crypto_call(psa_msg_t msg); + extern psa_status_t psa_crypto_close(void); mbedtls_version_get_string_full(mbedtls_version); SERVER_PRINT("%s", mbedtls_version); @@ -81,6 +82,7 @@ int psa_server_main(int argc, char *argv[]) SERVER_PRINT("Got a disconnection message"); ret = PSA_SUCCESS; client_disconnected = 1; + psa_crypto_close(); break; default: SERVER_PRINT("Got an IPC call of type %d", msg.type); From d64ba421ab4855df6d0586349a14eaa02b54b1dc Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 18 Jun 2024 12:31:57 +0100 Subject: [PATCH 048/125] Have psa_sim_generate.pl add psa_crypto_close() to psa_sim_crypto_server.c Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index ee3894f0ee..baa060e344 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -242,6 +242,16 @@ sub write_server_implementations return ok ? PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR; } +EOF + + # Finally, add psa_crypto_close() + + print $fh < Date: Tue, 18 Jun 2024 12:32:57 +0100 Subject: [PATCH 049/125] Have psa_sim_serialise.pl generate psa_sim_serialize_reset() Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_serialise.c | 2 ++ psasim/src/psa_sim_serialise.h | 4 ++++ psasim/src/psa_sim_serialise.pl | 34 +++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index e326637a61..f51133cebc 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -711,4 +711,6 @@ void psa_sim_serialize_reset(void) { memset(hash_operation_handles, 0, sizeof(hash_operation_handles)); memset(hash_operations, 0, sizeof(hash_operations)); + memset(aead_operation_handles, 0, sizeof(aead_operation_handles)); + memset(aead_operations, 0, sizeof(aead_operations)); } diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 7217595855..537730c1f8 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -54,6 +54,10 @@ * don't contain pointers. */ +/** Reset all operation slots. + * + * Should be called when all clients have disconnected. + */ void psa_sim_serialize_reset(void); /** Return how much buffer space is needed by \c psasim_serialise_begin(). diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index e09bb818a5..bbd946f24d 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -105,6 +105,7 @@ } } + print define_server_serialize_reset(@types); } else { die("internal error - shouldn't happen"); } @@ -329,6 +330,12 @@ sub h_header * don't contain pointers. */ +/** Reset all operation slots. + * + * Should be called when all clients have disconnected. + */ +void psa_sim_serialize_reset(void); + /** Return how much buffer space is needed by \c psasim_serialise_begin(). * * \return The number of bytes needed in the buffer for @@ -907,6 +914,33 @@ sub c_define_begins EOF } +# Return the code for psa_sim_serialize_reset() +sub define_server_serialize_reset +{ + my @types = @_; + + my $code = < Date: Mon, 17 Jun 2024 10:50:36 +0200 Subject: [PATCH 050/125] psa_sim: improve log prints - always print ERROR and FATAL messages because they should never occur, but when they do it's important to see them immediately; - keep INFO prints under DEBUG guard; - set client's PRINT as INFO message because otherwise it will mess test_suites's output; - change some error messages from INFO to ERROR because that's what they are. Signed-off-by: Valerio Setti --- psasim/include/util.h | 12 +++++------- psasim/src/client.c | 2 ++ psasim/src/psa_ff_client.c | 7 +++---- psasim/src/psa_sim_crypto_client.c | 2 +- psasim/src/psa_sim_serialise.c | 16 +++++++++++++--- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/psasim/include/util.h b/psasim/include/util.h index 558149fe2b..5eb8238c5c 100644 --- a/psasim/include/util.h +++ b/psasim/include/util.h @@ -13,20 +13,18 @@ #if defined(DEBUG) #define INFO(fmt, ...) \ fprintf(stdout, "Info (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) +#else /* !DEBUG */ +#define INFO(...) +#endif /* DEBUG*/ #define ERROR(fmt, ...) \ - fprintf(stdout, "Error (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) + fprintf(stderr, "Error (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define FATAL(fmt, ...) \ { \ - fprintf(stdout, "Fatal (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ + fprintf(stderr, "Fatal (%s - %d): " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ abort(); \ } -#else /* DEBUG */ -#define INFO(...) -#define ERROR(...) -#define FATAL(...) -#endif /* DEBUG*/ #define PROJECT_ID 'M' #define PATHNAMESIZE 256 diff --git a/psasim/src/client.c b/psasim/src/client.c index a8c9e08f3e..4c63abf5a3 100644 --- a/psasim/src/client.c +++ b/psasim/src/client.c @@ -7,12 +7,14 @@ /* Includes from mbedtls */ #include "psa/crypto.h" +#include "util.h" int main() { /* psa_crypto_init() connects to the server */ psa_status_t status = psa_crypto_init(); if (status != PSA_SUCCESS) { + ERROR("psa_crypto_init returned %d", status); return 1; } diff --git a/psasim/src/psa_ff_client.c b/psasim/src/psa_ff_client.c index 21a43b39dd..0d6bbf3c92 100644 --- a/psasim/src/psa_ff_client.c +++ b/psasim/src/psa_ff_client.c @@ -199,7 +199,6 @@ static psa_status_t process_response(int rx_qid, vectors_t *vecs, int type, default: FATAL(" ERROR: unknown internal message type: %ld", response.message_type); - return ret; } } } @@ -301,10 +300,10 @@ psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version) handles[idx].valid = 1; return idx; } else { - INFO("Server didn't like you"); + ERROR("Server didn't like you"); } } else { - INFO("Couldn't contact RoT service. Does it exist?"); + ERROR("Couldn't contact RoT service. Does it exist?"); if (__psa_ff_client_security_state == 0) { ERROR("Invalid SID"); @@ -339,7 +338,7 @@ uint32_t psa_version(uint32_t sid) } } } - INFO("psa_version failed: does the service exist?"); + ERROR("psa_version failed: does the service exist?"); return PSA_VERSION_NONE; } diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 2ffb615de7..758e9b2ec6 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -22,7 +22,7 @@ #include "psa/crypto.h" #define CLIENT_PRINT(fmt, ...) \ - PRINT("Client: " fmt, ##__VA_ARGS__) + INFO("Client: " fmt, ##__VA_ARGS__) static psa_handle_t handle = -1; diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 9e8c38bb57..703e4308f1 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -10,6 +10,7 @@ */ #include "psa_sim_serialise.h" +#include "util.h" #include #include @@ -71,8 +72,7 @@ static ssize_t allocate_hash_operation_slot(void) { psasim_client_handle_t handle = next_hash_operation_handle++; if (next_hash_operation_handle == 0) { /* wrapped around */ - fprintf(stderr, "MAX HASH HANDLES REACHED\n"); - exit(1); + FATAL("Hash operation handle wrapped"); } for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { @@ -82,6 +82,8 @@ static ssize_t allocate_hash_operation_slot(void) } } + ERROR("All slots are currently used. Unable to allocate a new one."); + return -1; /* all in use */ } @@ -94,7 +96,9 @@ static ssize_t find_hash_slot_by_handle(psasim_client_handle_t handle) } } - return -1; /* all in use */ + ERROR("Unable to find slot by handle %u", handle); + + return -1; /* not found */ } static psa_aead_operation_t aead_operations[MAX_LIVE_HANDLES_PER_CLASS]; @@ -706,3 +710,9 @@ int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, return 1; } + +void psa_sim_serialize_reset(void) +{ + memset(hash_operation_handles, 0, sizeof(hash_operation_handles)); + memset(hash_operations, 0, sizeof(hash_operations)); +} From 55b71e646b1f8a9ca2d480a26df2cfe92bcc6bff Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 18 Jun 2024 09:50:25 +0100 Subject: [PATCH 051/125] Update psa_sim_generate.pl to create the psa_sim_crypto_client.c we want Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index ee3894f0ee..15f57949df 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -302,7 +302,7 @@ sub client_calls_header #include "psa/crypto.h" #define CLIENT_PRINT(fmt, ...) \ - PRINT("Client: " fmt, ##__VA_ARGS__) + INFO("Client: " fmt, ##__VA_ARGS__) static psa_handle_t handle = -1; From 53dfdf3db27b5f2c055dfd91feb4aad6d4f71c16 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 18 Jun 2024 13:22:21 +0100 Subject: [PATCH 052/125] Update psa_sim_serialise.pl to create the psa_sim_serialise.c we want Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_serialise.c | 15 ++++++--------- psasim/src/psa_sim_serialise.pl | 12 +++++++++--- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 703e4308f1..aaf47db0a3 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -110,8 +110,7 @@ static ssize_t allocate_aead_operation_slot(void) { psasim_client_handle_t handle = next_aead_operation_handle++; if (next_aead_operation_handle == 0) { /* wrapped around */ - fprintf(stderr, "MAX HASH HANDLES REACHED\n"); - exit(1); + FATAL("Aead operation handle wrapped"); } for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { @@ -121,6 +120,8 @@ static ssize_t allocate_aead_operation_slot(void) } } + ERROR("All slots are currently used. Unable to allocate a new one."); + return -1; /* all in use */ } @@ -133,7 +134,9 @@ static ssize_t find_aead_slot_by_handle(psasim_client_handle_t handle) } } - return -1; /* all in use */ + ERROR("Unable to find slot by handle %u", handle); + + return -1; /* not found */ } size_t psasim_serialise_begin_needs(void) @@ -710,9 +713,3 @@ int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, return 1; } - -void psa_sim_serialize_reset(void) -{ - memset(hash_operation_handles, 0, sizeof(hash_operation_handles)); - memset(hash_operations, 0, sizeof(hash_operations)); -} diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index e09bb818a5..c795fd4dc9 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -724,6 +724,7 @@ sub c_header */ #include "psa_sim_serialise.h" +#include "util.h" #include #include @@ -788,6 +789,8 @@ sub define_operation_type_data_and_functions { my ($type) = @_; # e.g. 'hash' rather than 'psa_hash_operation_t' + my $utype = ucfirst($type); + return < Date: Fri, 21 Jun 2024 10:38:49 +0100 Subject: [PATCH 053/125] psasim: add support for psa_generate_random() Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 1 + psasim/src/psa_sim_crypto_client.c | 63 ++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 78 ++++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 27 +++++++++++ 4 files changed, 169 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index c68b416096..dd926d7137 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -25,6 +25,7 @@ enum { PSA_AEAD_UPDATE_AD, PSA_AEAD_VERIFY, PSA_DESTROY_KEY, + PSA_GENERATE_RANDOM, PSA_GET_KEY_ATTRIBUTES, PSA_HASH_ABORT, PSA_HASH_CLONE, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 758e9b2ec6..377b2369cf 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -1191,6 +1191,69 @@ psa_status_t psa_destroy_key( } +psa_status_t psa_generate_random( + uint8_t *output, size_t output_size + ) +{ + 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_buffer_needs(output, output_size); + + 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_buffer(&pos, &remaining, output, output_size); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_GENERATE_RANDOM, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_GENERATE_RANDOM 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, output, output_size); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key, psa_key_attributes_t *attributes diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 30d4b26dc8..0a84010f73 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -1324,6 +1324,80 @@ int psa_destroy_key_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_generate_random_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 *output = NULL; + size_t output_size; + + 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_buffer(&pos, &remaining, &output, &output_size); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_generate_random( + output, output_size + ); + + // 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(output, output_size); + + 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, output, output_size); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(output); + + return 1; // success + +fail: + free(result); + + free(output); + + return 0; // This shouldn't happen! +} + // Returns 1 for success, 0 for failure int psa_get_key_attributes_wrapper( uint8_t *in_params, size_t in_params_len, @@ -2252,6 +2326,10 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_destroy_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_GENERATE_RANDOM: + ok = psa_generate_random_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_GET_KEY_ATTRIBUTES: ok = psa_get_key_attributes_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 43de1db5e0..b2a59b20f1 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -2371,3 +2371,30 @@ sub put_crypto_init_first * results in this error code. */ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); + +/** + * \brief Generate random bytes. + * + * \warning This function **can** fail! Callers MUST check the return status + * and MUST NOT use the content of the output buffer if the return + * status is not #PSA_SUCCESS. + * + * \note To generate a key, use psa_generate_key() instead. + * + * \param[out] output Output buffer for the generated data. + * \param output_size Number of bytes to generate and output. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_generate_random(uint8_t *output, + size_t output_size); From a5d11af5b84a9fadadba48dfc6bbc7999cacfd12 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 10:41:56 +0100 Subject: [PATCH 054/125] psasim: add support for psa_mac_xxx() functions Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 8 + psasim/src/psa_sim_crypto_client.c | 604 ++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 732 +++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 404 ++++++++++++++++ psasim/src/psa_sim_serialise.c | 133 ++++++ psasim/src/psa_sim_serialise.h | 84 ++++ psasim/src/psa_sim_serialise.pl | 1 + 7 files changed, 1966 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index dd926d7137..44ebf678f4 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -36,6 +36,14 @@ enum { PSA_HASH_UPDATE, PSA_HASH_VERIFY, PSA_IMPORT_KEY, + PSA_MAC_ABORT, + PSA_MAC_COMPUTE, + PSA_MAC_SIGN_FINISH, + PSA_MAC_SIGN_SETUP, + PSA_MAC_UPDATE, + PSA_MAC_VERIFY, + PSA_MAC_VERIFY_FINISH, + PSA_MAC_VERIFY_SETUP, }; #endif /* _PSA_FUNCTIONS_CODES_H_ */ diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 377b2369cf..844c93951d 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -1976,3 +1976,607 @@ psa_status_t psa_import_key( return status; } + + +psa_status_t psa_mac_abort( + psa_mac_operation_t *operation + ) +{ + 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_mac_operation_t_needs(*operation); + + 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_mac_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_MAC_ABORT, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_MAC_ABORT 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_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_mac_compute( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + uint8_t *mac, size_t mac_size, + size_t *mac_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_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(mac, mac_size) + + psasim_serialise_size_t_needs(*mac_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_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, mac, mac_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *mac_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_MAC_COMPUTE, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_MAC_COMPUTE 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, mac, mac_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, mac_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_mac_sign_finish( + psa_mac_operation_t *operation, + uint8_t *mac, size_t mac_size, + size_t *mac_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_mac_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(mac, mac_size) + + psasim_serialise_size_t_needs(*mac_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_mac_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, mac, mac_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *mac_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_MAC_SIGN_FINISH, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_MAC_SIGN_FINISH 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_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, mac, mac_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, mac_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_mac_sign_setup( + psa_mac_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg + ) +{ + 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_mac_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); + + 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_mac_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_MAC_SIGN_SETUP, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_MAC_SIGN_SETUP 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_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_mac_update( + psa_mac_operation_t *operation, + const uint8_t *input, size_t input_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_mac_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_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_mac_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_MAC_UPDATE, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_MAC_UPDATE 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_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_mac_verify( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *mac, size_t mac_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_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(mac, mac_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_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, mac, mac_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_MAC_VERIFY, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_MAC_VERIFY 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; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_mac_verify_finish( + psa_mac_operation_t *operation, + const uint8_t *mac, size_t mac_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_mac_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(mac, mac_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_mac_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, mac, mac_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_MAC_VERIFY_FINISH, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_MAC_VERIFY_FINISH 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_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_mac_verify_setup( + psa_mac_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg + ) +{ + 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_mac_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); + + 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_mac_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_MAC_VERIFY_SETUP, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_MAC_VERIFY_SETUP 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_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 0a84010f73..856186f6a3 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -2234,6 +2234,706 @@ int psa_import_key_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_mac_abort_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_mac_operation_t *operation; + + 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_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_mac_abort( + operation + ); + + // 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_server_serialise_psa_mac_operation_t_needs(operation); + + 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_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + 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_mac_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *mac = NULL; + size_t mac_size; + size_t mac_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &mac, &mac_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &mac_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_mac_compute( + key, + alg, + input, input_length, + mac, mac_size, + &mac_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(mac, mac_size) + + psasim_serialise_size_t_needs(mac_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, mac, mac_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, mac_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(mac); + + return 1; // success + +fail: + free(result); + + free(input); + free(mac); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_mac_sign_finish_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_mac_operation_t *operation; + uint8_t *mac = NULL; + size_t mac_size; + size_t mac_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_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &mac, &mac_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &mac_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_mac_sign_finish( + operation, + mac, mac_size, + &mac_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_server_serialise_psa_mac_operation_t_needs(operation) + + psasim_serialise_buffer_needs(mac, mac_size) + + psasim_serialise_size_t_needs(mac_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_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, mac, mac_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, mac_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(mac); + + return 1; // success + +fail: + free(result); + + free(mac); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_mac_sign_setup_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_mac_operation_t *operation; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + + 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_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_mac_sign_setup( + operation, + key, + alg + ); + + // 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_server_serialise_psa_mac_operation_t_needs(operation); + + 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_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + 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_mac_update_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_mac_operation_t *operation; + uint8_t *input = NULL; + size_t input_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_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_mac_update( + operation, + input, input_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_server_serialise_psa_mac_operation_t_needs(operation); + + 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_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + + return 1; // success + +fail: + free(result); + + free(input); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_mac_verify_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *mac = NULL; + size_t mac_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &mac, &mac_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_mac_verify( + key, + alg, + input, input_length, + mac, mac_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); + + 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; + + free(input); + free(mac); + + return 1; // success + +fail: + free(result); + + free(input); + free(mac); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_mac_verify_finish_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_mac_operation_t *operation; + uint8_t *mac = NULL; + size_t mac_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_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &mac, &mac_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_mac_verify_finish( + operation, + mac, mac_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_server_serialise_psa_mac_operation_t_needs(operation); + + 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_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(mac); + + return 1; // success + +fail: + free(result); + + free(mac); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_mac_verify_setup_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_mac_operation_t *operation; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + + 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_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_mac_verify_setup( + operation, + key, + alg + ); + + // 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_server_serialise_psa_mac_operation_t_needs(operation); + + 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_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + 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; @@ -2370,6 +3070,38 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_import_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_MAC_ABORT: + ok = psa_mac_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_MAC_COMPUTE: + ok = psa_mac_compute_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_MAC_SIGN_FINISH: + ok = psa_mac_sign_finish_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_MAC_SIGN_SETUP: + ok = psa_mac_sign_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_MAC_UPDATE: + ok = psa_mac_update_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_MAC_VERIFY: + ok = psa_mac_verify_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_MAC_VERIFY_FINISH: + ok = psa_mac_verify_finish_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_MAC_VERIFY_SETUP: + ok = psa_mac_verify_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; } free(in_params); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index b2a59b20f1..ea5088e7a5 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -2398,3 +2398,407 @@ sub put_crypto_init_first */ psa_status_t psa_generate_random(uint8_t *output, size_t output_size); + +/** Calculate the MAC (message authentication code) of a message. + * + * \note To verify the MAC of a message against an + * expected value, use psa_mac_verify() instead. + * Beware that comparing integrity or authenticity data such as + * MAC values with a function such as \c memcmp is risky + * because the time taken by the comparison may leak information + * about the MAC value which could allow an attacker to guess + * a valid MAC and thereby bypass security controls. + * + * \param key Identifier of the key to use for the operation. It + * must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. + * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * \param[in] input Buffer containing the input message. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] mac Buffer where the MAC value is to be written. + * \param mac_size Size of the \p mac buffer in bytes. + * \param[out] mac_length On success, the number of bytes + * that make up the MAC value. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a MAC algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p mac_size is too small + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE + * The key could not be retrieved from storage. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length); + +/** Calculate the MAC of a message and compare it with a reference value. + * + * \param key Identifier of the key to use for the operation. It + * must allow the usage PSA_KEY_USAGE_VERIFY_MESSAGE. + * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * \param[in] input Buffer containing the input message. + * \param input_length Size of the \p input buffer in bytes. + * \param[in] mac Buffer containing the expected MAC value. + * \param mac_length Size of the \p mac buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected MAC is identical to the actual MAC of the input. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The MAC of the message was calculated successfully, but it + * differs from the expected value. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a MAC algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE + * The key could not be retrieved from storage. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *mac, + size_t mac_length); + +/** The type of the state data structure for multipart MAC operations. + * + * Before calling any function on a MAC operation object, the application must + * initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_mac_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_mac_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_MAC_OPERATION_INIT, + * for example: + * \code + * psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_mac_operation_init() + * to the structure, for example: + * \code + * psa_mac_operation_t operation; + * operation = psa_mac_operation_init(); + * \endcode + * + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ +typedef struct psa_mac_operation_s psa_mac_operation_t; + +/** \def PSA_MAC_OPERATION_INIT + * + * This macro returns a suitable initializer for a MAC operation object of type + * #psa_mac_operation_t. + */ + +/** Return an initial value for a MAC operation object. + */ +static psa_mac_operation_t psa_mac_operation_init(void); + +/** Set up a multipart MAC calculation operation. + * + * This function sets up the calculation of the MAC + * (message authentication code) of a byte string. + * To verify the MAC of a message against an + * expected value, use psa_mac_verify_setup() instead. + * + * The sequence of operations to calculate a MAC is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. + * -# Call psa_mac_sign_setup() to specify the algorithm and key. + * -# Call psa_mac_update() zero, one or more times, passing a fragment + * of the message each time. The MAC that is calculated is the MAC + * of the concatenation of these messages in order. + * -# At the end of the message, call psa_mac_sign_finish() to finish + * calculating the MAC value and retrieve it. + * + * If an error occurs at any step after a call to psa_mac_sign_setup(), the + * operation will need to be reset by a call to psa_mac_abort(). The + * application may call psa_mac_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_mac_sign_setup(), the application must + * eventually terminate the operation through one of the following methods: + * - A successful call to psa_mac_sign_finish(). + * - A call to psa_mac_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_mac_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. It + * must remain valid until the operation terminates. + * It must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. + * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a MAC algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE + * The key could not be retrieved from storage. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Set up a multipart MAC verification operation. + * + * This function sets up the verification of the MAC + * (message authentication code) of a byte string against an expected value. + * + * The sequence of operations to verify a MAC is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. + * -# Call psa_mac_verify_setup() to specify the algorithm and key. + * -# Call psa_mac_update() zero, one or more times, passing a fragment + * of the message each time. The MAC that is calculated is the MAC + * of the concatenation of these messages in order. + * -# At the end of the message, call psa_mac_verify_finish() to finish + * calculating the actual MAC of the message and verify it against + * the expected value. + * + * If an error occurs at any step after a call to psa_mac_verify_setup(), the + * operation will need to be reset by a call to psa_mac_abort(). The + * application may call psa_mac_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_mac_verify_setup(), the application must + * eventually terminate the operation through one of the following methods: + * - A successful call to psa_mac_verify_finish(). + * - A call to psa_mac_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_mac_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. It + * must remain valid until the operation terminates. + * It must allow the usage + * PSA_KEY_USAGE_VERIFY_MESSAGE. + * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c key is not compatible with \c alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \c alg is not supported or is not a MAC algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE + * The key could not be retrieved from storage. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Add a message fragment to a multipart MAC operation. + * + * The application must call psa_mac_sign_setup() or psa_mac_verify_setup() + * before calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). + * + * \param[in,out] operation Active MAC operation. + * \param[in] input Buffer containing the message fragment to add to + * the MAC calculation. + * \param input_length Size of the \p input buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_update(psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length); + +/** Finish the calculation of the MAC of a message. + * + * The application must call psa_mac_sign_setup() before calling this function. + * This function calculates the MAC of the message formed by concatenating + * the inputs passed to preceding calls to psa_mac_update(). + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). + * + * \warning Applications should not call this function if they expect + * a specific value for the MAC. Call psa_mac_verify_finish() instead. + * Beware that comparing integrity or authenticity data such as + * MAC values with a function such as \c memcmp is risky + * because the time taken by the comparison may leak information + * about the MAC value which could allow an attacker to guess + * a valid MAC and thereby bypass security controls. + * + * \param[in,out] operation Active MAC operation. + * \param[out] mac Buffer where the MAC value is to be written. + * \param mac_size Size of the \p mac buffer in bytes. + * \param[out] mac_length On success, the number of bytes + * that make up the MAC value. This is always + * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg) + * where \c key_type and \c key_bits are the type and + * bit-size respectively of the key and \c alg is the + * MAC algorithm that is calculated. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p mac buffer is too small. You can determine a + * sufficient buffer size by calling PSA_MAC_LENGTH(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active mac sign + * operation), or the library has not been previously initialized + * by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length); + +/** Finish the calculation of the MAC of a message and compare it with + * an expected value. + * + * The application must call psa_mac_verify_setup() before calling this function. + * This function calculates the MAC of the message formed by concatenating + * the inputs passed to preceding calls to psa_mac_update(). It then + * compares the calculated MAC with the expected MAC passed as a + * parameter to this function. + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). + * + * \note Implementations shall make the best effort to ensure that the + * comparison between the actual MAC and the expected MAC is performed + * in constant time. + * + * \param[in,out] operation Active MAC operation. + * \param[in] mac Buffer containing the expected MAC value. + * \param mac_length Size of the \p mac buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected MAC is identical to the actual MAC of the message. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The MAC of the message was calculated successfully, but it + * differs from the expected MAC. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active mac verify + * operation), or the library has not been previously initialized + * by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length); + +/** Abort a MAC operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * psa_mac_sign_setup() or psa_mac_verify_setup() again. + * + * You may call this function any time after the operation object has + * been initialized by one of the methods described in #psa_mac_operation_t. + * + * In particular, calling psa_mac_abort() after the operation has been + * terminated by a call to psa_mac_abort(), psa_mac_sign_finish() or + * psa_mac_verify_finish() is safe and has no effect. + * + * \param[in,out] operation Initialized MAC operation. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_abort(psa_mac_operation_t *operation); diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 651e0468e2..0cd2e09f95 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -139,6 +139,44 @@ static ssize_t find_aead_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } +static psa_mac_operation_t mac_operations[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t mac_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t next_mac_operation_handle = 1; + +/* Get a free slot */ +static ssize_t allocate_mac_operation_slot(void) +{ + psasim_client_handle_t handle = next_mac_operation_handle++; + if (next_mac_operation_handle == 0) { /* wrapped around */ + FATAL("Mac operation handle wrapped"); + } + + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (mac_operation_handles[i] == 0) { + mac_operation_handles[i] = handle; + return i; + } + } + + ERROR("All slots are currently used. Unable to allocate a new one."); + + return -1; /* all in use */ +} + +/* Find the slot given the handle */ +static ssize_t find_mac_slot_by_handle(psasim_client_handle_t handle) +{ + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (mac_operation_handles[i] == handle) { + return i; + } + } + + ERROR("Unable to find slot by handle %u", handle); + + return -1; /* not found */ +} + size_t psasim_serialise_begin_needs(void) { /* The serialisation buffer will @@ -679,6 +717,99 @@ int psasim_deserialise_psa_key_attributes_t(uint8_t **pos, return 1; } +size_t psasim_serialise_psa_mac_operation_t_needs(psa_mac_operation_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_mac_operation_t(uint8_t **pos, + size_t *remaining, + psa_mac_operation_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_mac_operation_t(uint8_t **pos, + size_t *remaining, + psa_mac_operation_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_server_serialise_psa_mac_operation_t_needs(psa_mac_operation_t *operation) +{ + (void) operation; + + /* We will actually return a handle */ + return sizeof(psasim_operation_t); +} + +int psasim_server_serialise_psa_mac_operation_t(uint8_t **pos, + size_t *remaining, + psa_mac_operation_t *operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(client_operation)) { + return 0; + } + + ssize_t slot = operation - mac_operations; + + client_operation.handle = mac_operation_handles[slot]; + + memcpy(*pos, &client_operation, sizeof(client_operation)); + *pos += sizeof(client_operation); + + return 1; +} + +int psasim_server_deserialise_psa_mac_operation_t(uint8_t **pos, + size_t *remaining, + psa_mac_operation_t **operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(psasim_operation_t)) { + return 0; + } + + memcpy(&client_operation, *pos, sizeof(psasim_operation_t)); + *pos += sizeof(psasim_operation_t); + *remaining -= sizeof(psasim_operation_t); + + ssize_t slot; + if (client_operation.handle == 0) { /* We need a new handle */ + slot = allocate_mac_operation_slot(); + } else { + slot = find_mac_slot_by_handle(client_operation.handle); + } + + if (slot < 0) { + return 0; + } + + *operation = &mac_operations[slot]; + + return 1; +} + size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value) { return sizeof(value); @@ -720,4 +851,6 @@ void psa_sim_serialize_reset(void) memset(hash_operations, 0, sizeof(hash_operations)); memset(aead_operation_handles, 0, sizeof(aead_operation_handles)); memset(aead_operations, 0, sizeof(aead_operations)); + memset(mac_operation_handles, 0, sizeof(mac_operation_handles)); + memset(mac_operations, 0, sizeof(mac_operations)); } diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 537730c1f8..11de3d711a 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -583,6 +583,90 @@ int psasim_deserialise_psa_key_attributes_t(uint8_t **pos, size_t *remaining, psa_key_attributes_t *value); +/** Return how much buffer space is needed by \c psasim_serialise_psa_mac_operation_t() + * to serialise a `psa_mac_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_mac_operation_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_mac_operation_t_needs(psa_mac_operation_t value); + +/** Serialise a `psa_mac_operation_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_mac_operation_t(uint8_t **pos, + size_t *remaining, + psa_mac_operation_t value); + +/** Deserialise a `psa_mac_operation_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_mac_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_mac_operation_t(uint8_t **pos, + size_t *remaining, + psa_mac_operation_t *value); + +/** Return how much buffer space is needed by \c psasim_server_serialise_psa_mac_operation_t() + * to serialise a `psa_mac_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_mac_operation_t() to serialise + * the given value. + */ +size_t psasim_server_serialise_psa_mac_operation_t_needs(psa_mac_operation_t *value); + +/** Serialise a `psa_mac_operation_t` into a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_serialise_psa_mac_operation_t(uint8_t **pos, + size_t *remaining, + psa_mac_operation_t *value); + +/** Deserialise a `psa_mac_operation_t` from a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_mac_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_deserialise_psa_mac_operation_t(uint8_t **pos, + size_t *remaining, + psa_mac_operation_t **value); + /** Return how much buffer space is needed by \c psasim_serialise_mbedtls_svc_key_id_t() * to serialise a `mbedtls_svc_key_id_t`. * diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index e89fafe0be..75f540b920 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -41,6 +41,7 @@ psa_hash_operation_t psa_aead_operation_t psa_key_attributes_t + psa_mac_operation_t mbedtls_svc_key_id_t); grep(s/-/ /g, @types); From 099679ce1b99abe044156c892371368fd4754546 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 10:43:39 +0100 Subject: [PATCH 055/125] psasim: add support for psa_cipher_xxx() functions Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 9 + psasim/src/psa_sim_crypto_client.c | 727 ++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 884 +++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 460 +++++++++++++++ psasim/src/psa_sim_serialise.c | 133 +++++ psasim/src/psa_sim_serialise.h | 84 +++ psasim/src/psa_sim_serialise.pl | 1 + 7 files changed, 2298 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 44ebf678f4..12c05e3cdd 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -24,6 +24,15 @@ enum { PSA_AEAD_UPDATE, PSA_AEAD_UPDATE_AD, PSA_AEAD_VERIFY, + PSA_CIPHER_ABORT, + PSA_CIPHER_DECRYPT, + PSA_CIPHER_DECRYPT_SETUP, + PSA_CIPHER_ENCRYPT, + PSA_CIPHER_ENCRYPT_SETUP, + PSA_CIPHER_FINISH, + PSA_CIPHER_GENERATE_IV, + PSA_CIPHER_SET_IV, + PSA_CIPHER_UPDATE, PSA_DESTROY_KEY, PSA_GENERATE_RANDOM, PSA_GET_KEY_ATTRIBUTES, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 844c93951d..613aa1f357 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -1133,6 +1133,733 @@ psa_status_t psa_aead_verify( } +psa_status_t psa_cipher_abort( + psa_cipher_operation_t *operation + ) +{ + 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_cipher_operation_t_needs(*operation); + + 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_cipher_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_ABORT, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_ABORT 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_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_cipher_decrypt( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, + size_t *output_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_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_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_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, output, output_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_DECRYPT, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_DECRYPT 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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_cipher_decrypt_setup( + psa_cipher_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg + ) +{ + 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_cipher_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); + + 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_cipher_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_DECRYPT_SETUP, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_DECRYPT_SETUP 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_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_cipher_encrypt( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, + size_t *output_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_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_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_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, output, output_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_ENCRYPT, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_ENCRYPT 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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_cipher_encrypt_setup( + psa_cipher_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg + ) +{ + 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_cipher_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); + + 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_cipher_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_ENCRYPT_SETUP, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_ENCRYPT_SETUP 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_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_cipher_finish( + psa_cipher_operation_t *operation, + uint8_t *output, size_t output_size, + size_t *output_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_cipher_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_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_cipher_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_FINISH, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_FINISH 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_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_cipher_generate_iv( + psa_cipher_operation_t *operation, + uint8_t *iv, size_t iv_size, + size_t *iv_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_cipher_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(iv, iv_size) + + psasim_serialise_size_t_needs(*iv_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_cipher_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, iv, iv_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *iv_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_GENERATE_IV, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_GENERATE_IV 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_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, iv, iv_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, iv_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_cipher_set_iv( + psa_cipher_operation_t *operation, + const uint8_t *iv, size_t iv_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_cipher_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(iv, iv_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_cipher_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, iv, iv_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_SET_IV, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_SET_IV 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_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + +psa_status_t psa_cipher_update( + psa_cipher_operation_t *operation, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, + size_t *output_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_cipher_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_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_cipher_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CIPHER_UPDATE, + params, (size_t) (pos - params), &result, &result_length); + if (!ok) { + printf("PSA_CIPHER_UPDATE 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_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + +fail: + free(params); + free(result); + + return status; +} + + psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key ) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 856186f6a3..897d50451d 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -1261,6 +1261,854 @@ int psa_aead_verify_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_cipher_abort_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_cipher_operation_t *operation; + + 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_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_abort( + operation + ); + + // 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_server_serialise_psa_cipher_operation_t_needs(operation); + + 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_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + 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_cipher_decrypt_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *output = NULL; + size_t output_size; + size_t output_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &output, &output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_decrypt( + key, + alg, + input, input_length, + output, output_size, + &output_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(output, output_size) + + psasim_serialise_size_t_needs(output_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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(output); + + return 1; // success + +fail: + free(result); + + free(input); + free(output); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_cipher_decrypt_setup_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_cipher_operation_t *operation; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + + 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_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_decrypt_setup( + operation, + key, + alg + ); + + // 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_server_serialise_psa_cipher_operation_t_needs(operation); + + 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_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + 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_cipher_encrypt_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *output = NULL; + size_t output_size; + size_t output_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &output, &output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_encrypt( + key, + alg, + input, input_length, + output, output_size, + &output_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(output, output_size) + + psasim_serialise_size_t_needs(output_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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(output); + + return 1; // success + +fail: + free(result); + + free(input); + free(output); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_cipher_encrypt_setup_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_cipher_operation_t *operation; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + + 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_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_encrypt_setup( + operation, + key, + alg + ); + + // 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_server_serialise_psa_cipher_operation_t_needs(operation); + + 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_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + 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_cipher_finish_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_cipher_operation_t *operation; + uint8_t *output = NULL; + size_t output_size; + size_t output_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_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_finish( + operation, + output, output_size, + &output_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_server_serialise_psa_cipher_operation_t_needs(operation) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(output_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_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(output); + + return 1; // success + +fail: + free(result); + + free(output); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_cipher_generate_iv_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_cipher_operation_t *operation; + uint8_t *iv = NULL; + size_t iv_size; + size_t iv_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_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &iv, &iv_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &iv_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_generate_iv( + operation, + iv, iv_size, + &iv_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_server_serialise_psa_cipher_operation_t_needs(operation) + + psasim_serialise_buffer_needs(iv, iv_size) + + psasim_serialise_size_t_needs(iv_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_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, iv, iv_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, iv_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(iv); + + return 1; // success + +fail: + free(result); + + free(iv); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_cipher_set_iv_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_cipher_operation_t *operation; + uint8_t *iv = NULL; + size_t iv_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_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &iv, &iv_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_set_iv( + operation, + iv, iv_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_server_serialise_psa_cipher_operation_t_needs(operation); + + 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_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(iv); + + return 1; // success + +fail: + free(result); + + free(iv); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_cipher_update_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_cipher_operation_t *operation; + uint8_t *input = NULL; + size_t input_length; + uint8_t *output = NULL; + size_t output_size; + size_t output_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_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_cipher_update( + operation, + input, input_length, + output, output_size, + &output_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_server_serialise_psa_cipher_operation_t_needs(operation) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(output_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_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(output); + + return 1; // success + +fail: + free(result); + + free(input); + free(output); + + return 0; // This shouldn't happen! +} + // Returns 1 for success, 0 for failure int psa_destroy_key_wrapper( uint8_t *in_params, size_t in_params_len, @@ -3022,6 +3870,42 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_aead_verify_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_CIPHER_ABORT: + ok = psa_cipher_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_CIPHER_DECRYPT: + ok = psa_cipher_decrypt_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_CIPHER_DECRYPT_SETUP: + ok = psa_cipher_decrypt_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_CIPHER_ENCRYPT: + ok = psa_cipher_encrypt_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_CIPHER_ENCRYPT_SETUP: + ok = psa_cipher_encrypt_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_CIPHER_FINISH: + ok = psa_cipher_finish_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_CIPHER_GENERATE_IV: + ok = psa_cipher_generate_iv_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_CIPHER_SET_IV: + ok = psa_cipher_set_iv_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_CIPHER_UPDATE: + ok = psa_cipher_update_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_DESTROY_KEY: ok = psa_destroy_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index ea5088e7a5..6cfcf86249 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -2802,3 +2802,463 @@ sub put_crypto_init_first * results in this error code. */ psa_status_t psa_mac_abort(psa_mac_operation_t *operation); + +/** Encrypt a message using a symmetric cipher. + * + * This function encrypts a message with a random IV (initialization + * vector). Use the multipart operation interface with a + * #psa_cipher_operation_t object to provide other forms of IV. + * + * \param key Identifier of the key to use for the operation. + * It must allow the usage #PSA_KEY_USAGE_ENCRYPT. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param[in] input Buffer containing the message to encrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the output is to be written. + * The output contains the IV followed by + * the ciphertext proper. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a cipher algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Decrypt a message using a symmetric cipher. + * + * This function decrypts a message encrypted with a symmetric cipher. + * + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param[in] input Buffer containing the message to decrypt. + * This consists of the IV followed by the + * ciphertext proper. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the plaintext is to be written. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a cipher algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** The type of the state data structure for multipart cipher operations. + * + * Before calling any function on a cipher operation object, the application + * must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_cipher_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_cipher_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_CIPHER_OPERATION_INIT, + * for example: + * \code + * psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_cipher_operation_init() + * to the structure, for example: + * \code + * psa_cipher_operation_t operation; + * operation = psa_cipher_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ +typedef struct psa_cipher_operation_s psa_cipher_operation_t; + +/** \def PSA_CIPHER_OPERATION_INIT + * + * This macro returns a suitable initializer for a cipher operation object of + * type #psa_cipher_operation_t. + */ + +/** Return an initial value for a cipher operation object. + */ +static psa_cipher_operation_t psa_cipher_operation_init(void); + +/** Set the key for a multipart symmetric encryption operation. + * + * The sequence of operations to encrypt a message with a symmetric cipher + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_cipher_operation_t, e.g. + * #PSA_CIPHER_OPERATION_INIT. + * -# Call psa_cipher_encrypt_setup() to specify the algorithm and key. + * -# Call either psa_cipher_generate_iv() or psa_cipher_set_iv() to + * generate or set the IV (initialization vector). You should use + * psa_cipher_generate_iv() unless the protocol you are implementing + * requires a specific IV value. + * -# Call psa_cipher_update() zero, one or more times, passing a fragment + * of the message each time. + * -# Call psa_cipher_finish(). + * + * If an error occurs at any step after a call to psa_cipher_encrypt_setup(), + * the operation will need to be reset by a call to psa_cipher_abort(). The + * application may call psa_cipher_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_cipher_encrypt_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_cipher_finish(). + * - A call to psa_cipher_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_cipher_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a cipher algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Set the key for a multipart symmetric decryption operation. + * + * The sequence of operations to decrypt a message with a symmetric cipher + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_cipher_operation_t, e.g. + * #PSA_CIPHER_OPERATION_INIT. + * -# Call psa_cipher_decrypt_setup() to specify the algorithm and key. + * -# Call psa_cipher_set_iv() with the IV (initialization vector) for the + * decryption. If the IV is prepended to the ciphertext, you can call + * psa_cipher_update() on a buffer containing the IV followed by the + * beginning of the message. + * -# Call psa_cipher_update() zero, one or more times, passing a fragment + * of the message each time. + * -# Call psa_cipher_finish(). + * + * If an error occurs at any step after a call to psa_cipher_decrypt_setup(), + * the operation will need to be reset by a call to psa_cipher_abort(). The + * application may call psa_cipher_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_cipher_decrypt_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_cipher_finish(). + * - A call to psa_cipher_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_cipher_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a cipher algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Generate an IV for a symmetric encryption operation. + * + * This function generates a random IV (initialization vector), nonce + * or initial counter value for the encryption operation as appropriate + * for the chosen algorithm, key type and key size. + * + * The application must call psa_cipher_encrypt_setup() before + * calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). + * + * \param[in,out] operation Active cipher operation. + * \param[out] iv Buffer where the generated IV is to be written. + * \param iv_size Size of the \p iv buffer in bytes. + * \param[out] iv_length On success, the number of bytes of the + * generated IV. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p iv buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, with no IV set), + * or the library has not been previously initialized + * by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, + uint8_t *iv, + size_t iv_size, + size_t *iv_length); + +/** Set the IV for a symmetric encryption or decryption operation. + * + * This function sets the IV (initialization vector), nonce + * or initial counter value for the encryption or decryption operation. + * + * The application must call psa_cipher_encrypt_setup() before + * calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). + * + * \note When encrypting, applications should use psa_cipher_generate_iv() + * instead of this function, unless implementing a protocol that requires + * a non-random IV. + * + * \param[in,out] operation Active cipher operation. + * \param[in] iv Buffer containing the IV to use. + * \param iv_length Size of the IV in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The size of \p iv is not acceptable for the chosen algorithm, + * or the chosen algorithm does not use an IV. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active cipher + * encrypt operation, with no IV set), or the library has not been + * previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, + const uint8_t *iv, + size_t iv_length); + +/** Encrypt or decrypt a message fragment in an active cipher operation. + * + * Before calling this function, you must: + * 1. Call either psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup(). + * The choice of setup function determines whether this function + * encrypts or decrypts its input. + * 2. If the algorithm requires an IV, call psa_cipher_generate_iv() + * (recommended when encrypting) or psa_cipher_set_iv(). + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). + * + * \param[in,out] operation Active cipher operation. + * \param[in] input Buffer containing the message fragment to + * encrypt or decrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the output is to be written. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, with an IV set + * if required for the algorithm), or the library has not been + * previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Finish encrypting or decrypting a message in a cipher operation. + * + * The application must call psa_cipher_encrypt_setup() or + * psa_cipher_decrypt_setup() before calling this function. The choice + * of setup function determines whether this function encrypts or + * decrypts its input. + * + * This function finishes the encryption or decryption of the message + * formed by concatenating the inputs passed to preceding calls to + * psa_cipher_update(). + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). + * + * \param[in,out] operation Active cipher operation. + * \param[out] output Buffer where the output is to be written. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total input size passed to this operation is not valid for + * this particular algorithm. For example, the algorithm is a based + * on block cipher and requires a whole number of blocks, but the + * total input size is not a multiple of the block size. + * \retval #PSA_ERROR_INVALID_PADDING + * This is a decryption operation for an algorithm that includes + * padding, and the ciphertext does not contain valid padding. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, with an IV set + * if required for the algorithm), or the library has not been + * previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Abort a cipher operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup() again. + * + * You may call this function any time after the operation object has + * been initialized as described in #psa_cipher_operation_t. + * + * In particular, calling psa_cipher_abort() after the operation has been + * terminated by a call to psa_cipher_abort() or psa_cipher_finish() + * is safe and has no effect. + * + * \param[in,out] operation Initialized cipher operation. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 0cd2e09f95..975abd2bb9 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -177,6 +177,44 @@ static ssize_t find_mac_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } +static psa_cipher_operation_t cipher_operations[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t cipher_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t next_cipher_operation_handle = 1; + +/* Get a free slot */ +static ssize_t allocate_cipher_operation_slot(void) +{ + psasim_client_handle_t handle = next_cipher_operation_handle++; + if (next_cipher_operation_handle == 0) { /* wrapped around */ + FATAL("Cipher operation handle wrapped"); + } + + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (cipher_operation_handles[i] == 0) { + cipher_operation_handles[i] = handle; + return i; + } + } + + ERROR("All slots are currently used. Unable to allocate a new one."); + + return -1; /* all in use */ +} + +/* Find the slot given the handle */ +static ssize_t find_cipher_slot_by_handle(psasim_client_handle_t handle) +{ + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (cipher_operation_handles[i] == handle) { + return i; + } + } + + ERROR("Unable to find slot by handle %u", handle); + + return -1; /* not found */ +} + size_t psasim_serialise_begin_needs(void) { /* The serialisation buffer will @@ -810,6 +848,99 @@ int psasim_server_deserialise_psa_mac_operation_t(uint8_t **pos, return 1; } +size_t psasim_serialise_psa_cipher_operation_t_needs(psa_cipher_operation_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_cipher_operation_t(uint8_t **pos, + size_t *remaining, + psa_cipher_operation_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_cipher_operation_t(uint8_t **pos, + size_t *remaining, + psa_cipher_operation_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_server_serialise_psa_cipher_operation_t_needs(psa_cipher_operation_t *operation) +{ + (void) operation; + + /* We will actually return a handle */ + return sizeof(psasim_operation_t); +} + +int psasim_server_serialise_psa_cipher_operation_t(uint8_t **pos, + size_t *remaining, + psa_cipher_operation_t *operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(client_operation)) { + return 0; + } + + ssize_t slot = operation - cipher_operations; + + client_operation.handle = cipher_operation_handles[slot]; + + memcpy(*pos, &client_operation, sizeof(client_operation)); + *pos += sizeof(client_operation); + + return 1; +} + +int psasim_server_deserialise_psa_cipher_operation_t(uint8_t **pos, + size_t *remaining, + psa_cipher_operation_t **operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(psasim_operation_t)) { + return 0; + } + + memcpy(&client_operation, *pos, sizeof(psasim_operation_t)); + *pos += sizeof(psasim_operation_t); + *remaining -= sizeof(psasim_operation_t); + + ssize_t slot; + if (client_operation.handle == 0) { /* We need a new handle */ + slot = allocate_cipher_operation_slot(); + } else { + slot = find_cipher_slot_by_handle(client_operation.handle); + } + + if (slot < 0) { + return 0; + } + + *operation = &cipher_operations[slot]; + + return 1; +} + size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value) { return sizeof(value); @@ -853,4 +984,6 @@ void psa_sim_serialize_reset(void) memset(aead_operations, 0, sizeof(aead_operations)); memset(mac_operation_handles, 0, sizeof(mac_operation_handles)); memset(mac_operations, 0, sizeof(mac_operations)); + memset(cipher_operation_handles, 0, sizeof(cipher_operation_handles)); + memset(cipher_operations, 0, sizeof(cipher_operations)); } diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 11de3d711a..55b2acb3da 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -667,6 +667,90 @@ int psasim_server_deserialise_psa_mac_operation_t(uint8_t **pos, size_t *remaining, psa_mac_operation_t **value); +/** Return how much buffer space is needed by \c psasim_serialise_psa_cipher_operation_t() + * to serialise a `psa_cipher_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_cipher_operation_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_cipher_operation_t_needs(psa_cipher_operation_t value); + +/** Serialise a `psa_cipher_operation_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_cipher_operation_t(uint8_t **pos, + size_t *remaining, + psa_cipher_operation_t value); + +/** Deserialise a `psa_cipher_operation_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_cipher_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_cipher_operation_t(uint8_t **pos, + size_t *remaining, + psa_cipher_operation_t *value); + +/** Return how much buffer space is needed by \c psasim_server_serialise_psa_cipher_operation_t() + * to serialise a `psa_cipher_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_cipher_operation_t() to serialise + * the given value. + */ +size_t psasim_server_serialise_psa_cipher_operation_t_needs(psa_cipher_operation_t *value); + +/** Serialise a `psa_cipher_operation_t` into a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_serialise_psa_cipher_operation_t(uint8_t **pos, + size_t *remaining, + psa_cipher_operation_t *value); + +/** Deserialise a `psa_cipher_operation_t` from a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_cipher_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_deserialise_psa_cipher_operation_t(uint8_t **pos, + size_t *remaining, + psa_cipher_operation_t **value); + /** Return how much buffer space is needed by \c psasim_serialise_mbedtls_svc_key_id_t() * to serialise a `mbedtls_svc_key_id_t`. * diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 75f540b920..a47b918662 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -42,6 +42,7 @@ psa_aead_operation_t psa_key_attributes_t psa_mac_operation_t + psa_cipher_operation_t mbedtls_svc_key_id_t); grep(s/-/ /g, @types); From c506151d890a407de343cc1a3c949641a75353eb Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 15:28:19 +0100 Subject: [PATCH 056/125] psasim: skip some functions; see _SKIP_FUNCTIONS in generate_psa_wrappers.py Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 6cfcf86249..fdc3435377 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -18,6 +18,16 @@ my %functions = get_functions(); my @functions = sort keys %functions; +# We don't want these functions (e.g. because they are not implemented, etc) +my @skip_functions = qw( + psa_key_derivation_verify_bytes + psa_key_derivation_verify_key +); + +# Remove @skip_functions from @functions +my %skip_functions = map { $_ => 1 } @skip_functions; +@functions = grep(!exists($skip_functions{$_}), @functions); + # get_functions(), called above, returns a data structure for each function # that we need to create client and server stubs for. In this example Perl script, # the function declarations we want are in the data section (after __END__ at From b0789830fb3705019a56f456377ce28efc1edfb7 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 15:33:18 +0100 Subject: [PATCH 057/125] psasim: use ser_params and ser_result variable names in client; 'params' is needed by some PSA functions Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_crypto_client.c | 738 ++++++++++++++--------------- psasim/src/psa_sim_generate.pl | 24 +- 2 files changed, 381 insertions(+), 381 deletions(-) diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 613aa1f357..1ae2dd7339 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -129,21 +129,21 @@ psa_status_t psa_aead_abort( psa_aead_operation_t *operation ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + psasim_serialise_psa_aead_operation_t_needs(*operation); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -156,13 +156,13 @@ psa_status_t psa_aead_abort( } ok = psa_crypto_call(PSA_AEAD_ABORT, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_ABORT server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -181,8 +181,8 @@ psa_status_t psa_aead_abort( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -198,8 +198,8 @@ psa_status_t psa_aead_decrypt( size_t *plaintext_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -212,13 +212,13 @@ psa_status_t psa_aead_decrypt( psasim_serialise_buffer_needs(plaintext, plaintext_size) + psasim_serialise_size_t_needs(*plaintext_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -255,13 +255,13 @@ psa_status_t psa_aead_decrypt( } ok = psa_crypto_call(PSA_AEAD_DECRYPT, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_DECRYPT server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -285,8 +285,8 @@ psa_status_t psa_aead_decrypt( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -298,8 +298,8 @@ psa_status_t psa_aead_decrypt_setup( psa_algorithm_t alg ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -308,13 +308,13 @@ psa_status_t psa_aead_decrypt_setup( psasim_serialise_mbedtls_svc_key_id_t_needs(key) + psasim_serialise_psa_algorithm_t_needs(alg); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -335,13 +335,13 @@ psa_status_t psa_aead_decrypt_setup( } ok = psa_crypto_call(PSA_AEAD_DECRYPT_SETUP, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_DECRYPT_SETUP server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -360,8 +360,8 @@ psa_status_t psa_aead_decrypt_setup( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -377,8 +377,8 @@ psa_status_t psa_aead_encrypt( size_t *ciphertext_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -391,13 +391,13 @@ psa_status_t psa_aead_encrypt( psasim_serialise_buffer_needs(ciphertext, ciphertext_size) + psasim_serialise_size_t_needs(*ciphertext_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -434,13 +434,13 @@ psa_status_t psa_aead_encrypt( } ok = psa_crypto_call(PSA_AEAD_ENCRYPT, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_ENCRYPT server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -464,8 +464,8 @@ psa_status_t psa_aead_encrypt( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -477,8 +477,8 @@ psa_status_t psa_aead_encrypt_setup( psa_algorithm_t alg ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -487,13 +487,13 @@ psa_status_t psa_aead_encrypt_setup( psasim_serialise_mbedtls_svc_key_id_t_needs(key) + psasim_serialise_psa_algorithm_t_needs(alg); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -514,13 +514,13 @@ psa_status_t psa_aead_encrypt_setup( } ok = psa_crypto_call(PSA_AEAD_ENCRYPT_SETUP, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_ENCRYPT_SETUP server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -539,8 +539,8 @@ psa_status_t psa_aead_encrypt_setup( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -554,8 +554,8 @@ psa_status_t psa_aead_finish( size_t *tag_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -566,13 +566,13 @@ psa_status_t psa_aead_finish( psasim_serialise_buffer_needs(tag, tag_size) + psasim_serialise_size_t_needs(*tag_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -601,13 +601,13 @@ psa_status_t psa_aead_finish( } ok = psa_crypto_call(PSA_AEAD_FINISH, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_FINISH server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -646,8 +646,8 @@ psa_status_t psa_aead_finish( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -659,8 +659,8 @@ psa_status_t psa_aead_generate_nonce( size_t *nonce_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -669,13 +669,13 @@ psa_status_t psa_aead_generate_nonce( psasim_serialise_buffer_needs(nonce, nonce_size) + psasim_serialise_size_t_needs(*nonce_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -696,13 +696,13 @@ psa_status_t psa_aead_generate_nonce( } ok = psa_crypto_call(PSA_AEAD_GENERATE_NONCE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_GENERATE_NONCE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -731,8 +731,8 @@ psa_status_t psa_aead_generate_nonce( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -744,8 +744,8 @@ psa_status_t psa_aead_set_lengths( size_t plaintext_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -754,13 +754,13 @@ psa_status_t psa_aead_set_lengths( psasim_serialise_size_t_needs(ad_length) + psasim_serialise_size_t_needs(plaintext_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -781,13 +781,13 @@ psa_status_t psa_aead_set_lengths( } ok = psa_crypto_call(PSA_AEAD_SET_LENGTHS, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_SET_LENGTHS server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -806,8 +806,8 @@ psa_status_t psa_aead_set_lengths( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -818,8 +818,8 @@ psa_status_t psa_aead_set_nonce( const uint8_t *nonce, size_t nonce_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -827,13 +827,13 @@ psa_status_t psa_aead_set_nonce( psasim_serialise_psa_aead_operation_t_needs(*operation) + psasim_serialise_buffer_needs(nonce, nonce_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -850,13 +850,13 @@ psa_status_t psa_aead_set_nonce( } ok = psa_crypto_call(PSA_AEAD_SET_NONCE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_SET_NONCE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -875,8 +875,8 @@ psa_status_t psa_aead_set_nonce( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -889,8 +889,8 @@ psa_status_t psa_aead_update( size_t *output_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -900,13 +900,13 @@ psa_status_t psa_aead_update( psasim_serialise_buffer_needs(output, output_size) + psasim_serialise_size_t_needs(*output_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -931,13 +931,13 @@ psa_status_t psa_aead_update( } ok = psa_crypto_call(PSA_AEAD_UPDATE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_UPDATE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -966,8 +966,8 @@ psa_status_t psa_aead_update( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -978,8 +978,8 @@ psa_status_t psa_aead_update_ad( const uint8_t *input, size_t input_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -987,13 +987,13 @@ psa_status_t psa_aead_update_ad( psasim_serialise_psa_aead_operation_t_needs(*operation) + psasim_serialise_buffer_needs(input, input_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1010,13 +1010,13 @@ psa_status_t psa_aead_update_ad( } ok = psa_crypto_call(PSA_AEAD_UPDATE_AD, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_UPDATE_AD server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1035,8 +1035,8 @@ psa_status_t psa_aead_update_ad( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1049,8 +1049,8 @@ psa_status_t psa_aead_verify( const uint8_t *tag, size_t tag_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1060,13 +1060,13 @@ psa_status_t psa_aead_verify( psasim_serialise_size_t_needs(*plaintext_length) + psasim_serialise_buffer_needs(tag, tag_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1091,13 +1091,13 @@ psa_status_t psa_aead_verify( } ok = psa_crypto_call(PSA_AEAD_VERIFY, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_AEAD_VERIFY server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1126,8 +1126,8 @@ psa_status_t psa_aead_verify( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1137,21 +1137,21 @@ psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + psasim_serialise_psa_cipher_operation_t_needs(*operation); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1164,13 +1164,13 @@ psa_status_t psa_cipher_abort( } ok = psa_crypto_call(PSA_CIPHER_ABORT, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_ABORT server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1189,8 +1189,8 @@ psa_status_t psa_cipher_abort( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1204,8 +1204,8 @@ psa_status_t psa_cipher_decrypt( size_t *output_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1216,13 +1216,13 @@ psa_status_t psa_cipher_decrypt( psasim_serialise_buffer_needs(output, output_size) + psasim_serialise_size_t_needs(*output_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1251,13 +1251,13 @@ psa_status_t psa_cipher_decrypt( } ok = psa_crypto_call(PSA_CIPHER_DECRYPT, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_DECRYPT server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1281,8 +1281,8 @@ psa_status_t psa_cipher_decrypt( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1294,8 +1294,8 @@ psa_status_t psa_cipher_decrypt_setup( psa_algorithm_t alg ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1304,13 +1304,13 @@ psa_status_t psa_cipher_decrypt_setup( psasim_serialise_mbedtls_svc_key_id_t_needs(key) + psasim_serialise_psa_algorithm_t_needs(alg); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1331,13 +1331,13 @@ psa_status_t psa_cipher_decrypt_setup( } ok = psa_crypto_call(PSA_CIPHER_DECRYPT_SETUP, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_DECRYPT_SETUP server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1356,8 +1356,8 @@ psa_status_t psa_cipher_decrypt_setup( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1371,8 +1371,8 @@ psa_status_t psa_cipher_encrypt( size_t *output_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1383,13 +1383,13 @@ psa_status_t psa_cipher_encrypt( psasim_serialise_buffer_needs(output, output_size) + psasim_serialise_size_t_needs(*output_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1418,13 +1418,13 @@ psa_status_t psa_cipher_encrypt( } ok = psa_crypto_call(PSA_CIPHER_ENCRYPT, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_ENCRYPT server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1448,8 +1448,8 @@ psa_status_t psa_cipher_encrypt( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1461,8 +1461,8 @@ psa_status_t psa_cipher_encrypt_setup( psa_algorithm_t alg ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1471,13 +1471,13 @@ psa_status_t psa_cipher_encrypt_setup( psasim_serialise_mbedtls_svc_key_id_t_needs(key) + psasim_serialise_psa_algorithm_t_needs(alg); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1498,13 +1498,13 @@ psa_status_t psa_cipher_encrypt_setup( } ok = psa_crypto_call(PSA_CIPHER_ENCRYPT_SETUP, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_ENCRYPT_SETUP server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1523,8 +1523,8 @@ psa_status_t psa_cipher_encrypt_setup( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1536,8 +1536,8 @@ psa_status_t psa_cipher_finish( size_t *output_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1546,13 +1546,13 @@ psa_status_t psa_cipher_finish( psasim_serialise_buffer_needs(output, output_size) + psasim_serialise_size_t_needs(*output_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1573,13 +1573,13 @@ psa_status_t psa_cipher_finish( } ok = psa_crypto_call(PSA_CIPHER_FINISH, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_FINISH server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1608,8 +1608,8 @@ psa_status_t psa_cipher_finish( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1621,8 +1621,8 @@ psa_status_t psa_cipher_generate_iv( size_t *iv_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1631,13 +1631,13 @@ psa_status_t psa_cipher_generate_iv( psasim_serialise_buffer_needs(iv, iv_size) + psasim_serialise_size_t_needs(*iv_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1658,13 +1658,13 @@ psa_status_t psa_cipher_generate_iv( } ok = psa_crypto_call(PSA_CIPHER_GENERATE_IV, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_GENERATE_IV server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1693,8 +1693,8 @@ psa_status_t psa_cipher_generate_iv( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1705,8 +1705,8 @@ psa_status_t psa_cipher_set_iv( const uint8_t *iv, size_t iv_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1714,13 +1714,13 @@ psa_status_t psa_cipher_set_iv( psasim_serialise_psa_cipher_operation_t_needs(*operation) + psasim_serialise_buffer_needs(iv, iv_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1737,13 +1737,13 @@ psa_status_t psa_cipher_set_iv( } ok = psa_crypto_call(PSA_CIPHER_SET_IV, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_SET_IV server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1762,8 +1762,8 @@ psa_status_t psa_cipher_set_iv( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1776,8 +1776,8 @@ psa_status_t psa_cipher_update( size_t *output_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1787,13 +1787,13 @@ psa_status_t psa_cipher_update( psasim_serialise_buffer_needs(output, output_size) + psasim_serialise_size_t_needs(*output_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1818,13 +1818,13 @@ psa_status_t psa_cipher_update( } ok = psa_crypto_call(PSA_CIPHER_UPDATE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_CIPHER_UPDATE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1853,8 +1853,8 @@ psa_status_t psa_cipher_update( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1864,21 +1864,21 @@ psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + psasim_serialise_mbedtls_svc_key_id_t_needs(key); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1891,13 +1891,13 @@ psa_status_t psa_destroy_key( } ok = psa_crypto_call(PSA_DESTROY_KEY, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_DESTROY_KEY server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1911,8 +1911,8 @@ psa_status_t psa_destroy_key( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1922,21 +1922,21 @@ psa_status_t psa_generate_random( uint8_t *output, size_t output_size ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + psasim_serialise_buffer_needs(output, output_size); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -1949,13 +1949,13 @@ psa_status_t psa_generate_random( } ok = psa_crypto_call(PSA_GENERATE_RANDOM, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_GENERATE_RANDOM server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -1974,8 +1974,8 @@ psa_status_t psa_generate_random( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -1986,8 +1986,8 @@ psa_status_t psa_get_key_attributes( psa_key_attributes_t *attributes ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -1995,13 +1995,13 @@ psa_status_t psa_get_key_attributes( psasim_serialise_mbedtls_svc_key_id_t_needs(key) + psasim_serialise_psa_key_attributes_t_needs(*attributes); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2018,13 +2018,13 @@ psa_status_t psa_get_key_attributes( } ok = psa_crypto_call(PSA_GET_KEY_ATTRIBUTES, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_GET_KEY_ATTRIBUTES server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2043,8 +2043,8 @@ psa_status_t psa_get_key_attributes( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2054,21 +2054,21 @@ psa_status_t psa_hash_abort( psa_hash_operation_t *operation ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + psasim_serialise_psa_hash_operation_t_needs(*operation); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2081,13 +2081,13 @@ psa_status_t psa_hash_abort( } ok = psa_crypto_call(PSA_HASH_ABORT, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_HASH_ABORT server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2106,8 +2106,8 @@ psa_status_t psa_hash_abort( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2118,8 +2118,8 @@ psa_status_t psa_hash_clone( psa_hash_operation_t *target_operation ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2127,13 +2127,13 @@ psa_status_t psa_hash_clone( psasim_serialise_psa_hash_operation_t_needs(*source_operation) + psasim_serialise_psa_hash_operation_t_needs(*target_operation); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2150,13 +2150,13 @@ psa_status_t psa_hash_clone( } ok = psa_crypto_call(PSA_HASH_CLONE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_HASH_CLONE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2175,8 +2175,8 @@ psa_status_t psa_hash_clone( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2188,8 +2188,8 @@ psa_status_t psa_hash_compare( const uint8_t *hash, size_t hash_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2198,13 +2198,13 @@ psa_status_t psa_hash_compare( psasim_serialise_buffer_needs(input, input_length) + psasim_serialise_buffer_needs(hash, hash_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2225,13 +2225,13 @@ psa_status_t psa_hash_compare( } ok = psa_crypto_call(PSA_HASH_COMPARE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_HASH_COMPARE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2245,8 +2245,8 @@ psa_status_t psa_hash_compare( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2259,8 +2259,8 @@ psa_status_t psa_hash_compute( size_t *hash_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2270,13 +2270,13 @@ psa_status_t psa_hash_compute( psasim_serialise_buffer_needs(hash, hash_size) + psasim_serialise_size_t_needs(*hash_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2301,13 +2301,13 @@ psa_status_t psa_hash_compute( } ok = psa_crypto_call(PSA_HASH_COMPUTE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_HASH_COMPUTE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2331,8 +2331,8 @@ psa_status_t psa_hash_compute( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2344,8 +2344,8 @@ psa_status_t psa_hash_finish( size_t *hash_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2354,13 +2354,13 @@ psa_status_t psa_hash_finish( psasim_serialise_buffer_needs(hash, hash_size) + psasim_serialise_size_t_needs(*hash_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2381,13 +2381,13 @@ psa_status_t psa_hash_finish( } ok = psa_crypto_call(PSA_HASH_FINISH, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_HASH_FINISH server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2416,8 +2416,8 @@ psa_status_t psa_hash_finish( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2428,8 +2428,8 @@ psa_status_t psa_hash_setup( psa_algorithm_t alg ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2437,13 +2437,13 @@ psa_status_t psa_hash_setup( psasim_serialise_psa_hash_operation_t_needs(*operation) + psasim_serialise_psa_algorithm_t_needs(alg); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2460,13 +2460,13 @@ psa_status_t psa_hash_setup( } ok = psa_crypto_call(PSA_HASH_SETUP, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_HASH_SETUP server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2485,8 +2485,8 @@ psa_status_t psa_hash_setup( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2497,8 +2497,8 @@ psa_status_t psa_hash_update( const uint8_t *input, size_t input_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2506,13 +2506,13 @@ psa_status_t psa_hash_update( psasim_serialise_psa_hash_operation_t_needs(*operation) + psasim_serialise_buffer_needs(input, input_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2529,13 +2529,13 @@ psa_status_t psa_hash_update( } ok = psa_crypto_call(PSA_HASH_UPDATE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_HASH_UPDATE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2554,8 +2554,8 @@ psa_status_t psa_hash_update( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2566,8 +2566,8 @@ psa_status_t psa_hash_verify( const uint8_t *hash, size_t hash_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2575,13 +2575,13 @@ psa_status_t psa_hash_verify( psasim_serialise_psa_hash_operation_t_needs(*operation) + psasim_serialise_buffer_needs(hash, hash_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2598,13 +2598,13 @@ psa_status_t psa_hash_verify( } ok = psa_crypto_call(PSA_HASH_VERIFY, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_HASH_VERIFY server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2623,8 +2623,8 @@ psa_status_t psa_hash_verify( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2636,8 +2636,8 @@ psa_status_t psa_import_key( mbedtls_svc_key_id_t *key ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2646,13 +2646,13 @@ psa_status_t psa_import_key( psasim_serialise_buffer_needs(data, data_length) + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2673,13 +2673,13 @@ psa_status_t psa_import_key( } ok = psa_crypto_call(PSA_IMPORT_KEY, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_IMPORT_KEY server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2698,8 +2698,8 @@ psa_status_t psa_import_key( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2709,21 +2709,21 @@ psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + psasim_serialise_psa_mac_operation_t_needs(*operation); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2736,13 +2736,13 @@ psa_status_t psa_mac_abort( } ok = psa_crypto_call(PSA_MAC_ABORT, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_MAC_ABORT server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2761,8 +2761,8 @@ psa_status_t psa_mac_abort( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2776,8 +2776,8 @@ psa_status_t psa_mac_compute( size_t *mac_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2788,13 +2788,13 @@ psa_status_t psa_mac_compute( psasim_serialise_buffer_needs(mac, mac_size) + psasim_serialise_size_t_needs(*mac_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2823,13 +2823,13 @@ psa_status_t psa_mac_compute( } ok = psa_crypto_call(PSA_MAC_COMPUTE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_MAC_COMPUTE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2853,8 +2853,8 @@ psa_status_t psa_mac_compute( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2866,8 +2866,8 @@ psa_status_t psa_mac_sign_finish( size_t *mac_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2876,13 +2876,13 @@ psa_status_t psa_mac_sign_finish( psasim_serialise_buffer_needs(mac, mac_size) + psasim_serialise_size_t_needs(*mac_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2903,13 +2903,13 @@ psa_status_t psa_mac_sign_finish( } ok = psa_crypto_call(PSA_MAC_SIGN_FINISH, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_MAC_SIGN_FINISH server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -2938,8 +2938,8 @@ psa_status_t psa_mac_sign_finish( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -2951,8 +2951,8 @@ psa_status_t psa_mac_sign_setup( psa_algorithm_t alg ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2961,13 +2961,13 @@ psa_status_t psa_mac_sign_setup( psasim_serialise_mbedtls_svc_key_id_t_needs(key) + psasim_serialise_psa_algorithm_t_needs(alg); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -2988,13 +2988,13 @@ psa_status_t psa_mac_sign_setup( } ok = psa_crypto_call(PSA_MAC_SIGN_SETUP, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_MAC_SIGN_SETUP server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -3013,8 +3013,8 @@ psa_status_t psa_mac_sign_setup( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -3025,8 +3025,8 @@ psa_status_t psa_mac_update( const uint8_t *input, size_t input_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -3034,13 +3034,13 @@ psa_status_t psa_mac_update( psasim_serialise_psa_mac_operation_t_needs(*operation) + psasim_serialise_buffer_needs(input, input_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -3057,13 +3057,13 @@ psa_status_t psa_mac_update( } ok = psa_crypto_call(PSA_MAC_UPDATE, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_MAC_UPDATE server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -3082,8 +3082,8 @@ psa_status_t psa_mac_update( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -3096,8 +3096,8 @@ psa_status_t psa_mac_verify( const uint8_t *mac, size_t mac_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -3107,13 +3107,13 @@ psa_status_t psa_mac_verify( psasim_serialise_buffer_needs(input, input_length) + psasim_serialise_buffer_needs(mac, mac_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -3138,13 +3138,13 @@ psa_status_t psa_mac_verify( } ok = psa_crypto_call(PSA_MAC_VERIFY, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_MAC_VERIFY server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -3158,8 +3158,8 @@ psa_status_t psa_mac_verify( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -3170,8 +3170,8 @@ psa_status_t psa_mac_verify_finish( const uint8_t *mac, size_t mac_length ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -3179,13 +3179,13 @@ psa_status_t psa_mac_verify_finish( psasim_serialise_psa_mac_operation_t_needs(*operation) + psasim_serialise_buffer_needs(mac, mac_length); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -3202,13 +3202,13 @@ psa_status_t psa_mac_verify_finish( } ok = psa_crypto_call(PSA_MAC_VERIFY_FINISH, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_MAC_VERIFY_FINISH server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -3227,8 +3227,8 @@ psa_status_t psa_mac_verify_finish( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } @@ -3240,8 +3240,8 @@ psa_status_t psa_mac_verify_setup( psa_algorithm_t alg ) { - uint8_t *params = NULL; - uint8_t *result = NULL; + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -3250,13 +3250,13 @@ psa_status_t psa_mac_verify_setup( psasim_serialise_mbedtls_svc_key_id_t_needs(key) + psasim_serialise_psa_algorithm_t_needs(alg); - params = malloc(needed); - if (params == NULL) { + ser_params = malloc(needed); + if (ser_params == NULL) { status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } - uint8_t *pos = params; + uint8_t *pos = ser_params; size_t remaining = needed; int ok; ok = psasim_serialise_begin(&pos, &remaining); @@ -3277,13 +3277,13 @@ psa_status_t psa_mac_verify_setup( } ok = psa_crypto_call(PSA_MAC_VERIFY_SETUP, - params, (size_t) (pos - params), &result, &result_length); + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { printf("PSA_MAC_VERIFY_SETUP server call failed\n"); goto fail; } - uint8_t *rpos = result; + uint8_t *rpos = ser_result; size_t rremain = result_length; ok = psasim_deserialise_begin(&rpos, &rremain); @@ -3302,8 +3302,8 @@ psa_status_t psa_mac_verify_setup( } fail: - free(params); - free(result); + free(ser_params); + free(ser_result); return status; } diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index fdc3435377..a85a62a12e 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -748,8 +748,8 @@ sub output_client print $fh < Date: Fri, 21 Jun 2024 15:35:44 +0100 Subject: [PATCH 058/125] psasim: psa_key_derivation_verify_bytes() doesn't follow the naming convention for a buffer, so override Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index a85a62a12e..76592151a4 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -1047,6 +1047,11 @@ sub get_functions #print("$arg: $name: might be a buffer?\n"); die("$arg: not a buffer 1!\n") if $i == $#args; my $next = $args[$i + 1]; + if ($func eq "psa_key_derivation_verify_bytes" && + $arg eq "const uint8_t *expected_output" && + $next eq "size_t output_length") { + $next = "size_t expected_output_length"; # doesn't follow naming convention, so override + } die("$arg: not a buffer 2!\n") if $next !~ /^size_t\s+(${name}_\w+)$/; $i++; # We're using the next param here my $nname = $1; From b17abbcc95ae9805e38991da61cf76c154bf0158 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 15:55:59 +0100 Subject: [PATCH 059/125] psasim: add the ability to serialise psa_key_production_parameters_t Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 44 +++++++++ psasim/src/psa_sim_serialise.pl | 160 ++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 76592151a4..97e92bc088 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -546,6 +546,13 @@ sub output_server_wrapper print $fh < UINT32_MAX / 2) { /* arbitrary limit */ + return 0; /* too big to serialise */ + } + + /* We use 32-bit lengths, which should be enough for any reasonable usage :) */ + /* (the UINT32_MAX / 2 above is an even more conservative check to avoid overflow here) */ + uint32_t len = (uint32_t) (sizeof(data_length) + sizeof(*params) + data_length); + if (*remaining < SER_TAG_SIZE + sizeof(uint32_t) + len) { + return 0; + } + + char tag[SER_TAG_SIZE] = "PKPP"; + + memcpy(*pos, tag, sizeof(tag)); + memcpy(*pos + sizeof(tag), &len, sizeof(len)); + *pos += sizeof(tag) + sizeof(len); + *remaining -= sizeof(tag) + sizeof(len); + + memcpy(*pos, &data_length, sizeof(data_length)); + memcpy(*pos + sizeof(data_length), params, sizeof(*params) + data_length); + *pos += sizeof(data_length) + sizeof(*params) + data_length; + *remaining -= sizeof(data_length) + sizeof(*params) + data_length; + + return 1; +} + +int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, + size_t *remaining, + psa_key_production_parameters_t **params, + size_t *data_length) +{ + if (*remaining < SER_TAG_SIZE + sizeof(uint32_t)) { + return 0; /* can't even be an empty serialisation */ + } + + char tag[SER_TAG_SIZE] = "PKPP"; /* expected */ + uint32_t len; + + memcpy(&len, *pos + sizeof(tag), sizeof(len)); + + if (memcmp(*pos, tag, sizeof(tag)) != 0) { + return 0; /* wrong tag */ + } + + *pos += sizeof(tag) + sizeof(len); + *remaining -= sizeof(tag) + sizeof(len); + + if (*remaining < sizeof(*data_length)) { + return 0; /* missing data_length */ + } + memcpy(data_length, *pos, sizeof(*data_length)); + + if ((size_t)len != (sizeof(data_length) + sizeof(**params) + *data_length)) { + return 0; /* wrong length */ + } + + if (*remaining < sizeof(*data_length) + sizeof(**params) + *data_length) { + return 0; /* not enough data provided */ + } + + *pos += sizeof(data_length); + *remaining -= sizeof(data_length); + + psa_key_production_parameters_t *out = malloc(sizeof(**params) + *data_length); + if (out == NULL) { + return 0; /* allocation failure */ + } + + memcpy(out, *pos, sizeof(*out) + *data_length); + *pos += sizeof(*out) + *data_length; + *remaining -= sizeof(*out) + *data_length; + + *params = out; + + return 1; +} +EOF +} + sub c_header { return <<'EOF'; From 0d3c4c780a5e94f775a63c28992b0a00c65c2cef Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 16:11:25 +0100 Subject: [PATCH 060/125] psasim: add support for psa_key_derivation_xxx() and psa_raw_key_agreement() to the simulator Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 12 + psasim/src/psa_sim_crypto_client.c | 908 +++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 1082 ++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 877 ++++++++++++++++++++++ psasim/src/psa_sim_serialise.c | 316 ++++++++ psasim/src/psa_sim_serialise.h | 260 +++++++ psasim/src/psa_sim_serialise.pl | 6 +- 7 files changed, 3460 insertions(+), 1 deletion(-) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 12c05e3cdd..c9b72e6f68 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -45,6 +45,17 @@ enum { PSA_HASH_UPDATE, PSA_HASH_VERIFY, PSA_IMPORT_KEY, + PSA_KEY_DERIVATION_ABORT, + PSA_KEY_DERIVATION_GET_CAPACITY, + PSA_KEY_DERIVATION_INPUT_BYTES, + PSA_KEY_DERIVATION_INPUT_INTEGER, + PSA_KEY_DERIVATION_INPUT_KEY, + PSA_KEY_DERIVATION_KEY_AGREEMENT, + PSA_KEY_DERIVATION_OUTPUT_BYTES, + PSA_KEY_DERIVATION_OUTPUT_KEY, + PSA_KEY_DERIVATION_OUTPUT_KEY_EXT, + PSA_KEY_DERIVATION_SET_CAPACITY, + PSA_KEY_DERIVATION_SETUP, PSA_MAC_ABORT, PSA_MAC_COMPUTE, PSA_MAC_SIGN_FINISH, @@ -53,6 +64,7 @@ enum { PSA_MAC_VERIFY, PSA_MAC_VERIFY_FINISH, PSA_MAC_VERIFY_SETUP, + PSA_RAW_KEY_AGREEMENT, }; #endif /* _PSA_FUNCTIONS_CODES_H_ */ diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 1ae2dd7339..84f2b5a6ab 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -2705,6 +2705,822 @@ psa_status_t psa_import_key( } +psa_status_t psa_key_derivation_abort( + psa_key_derivation_operation_t *operation + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_ABORT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_ABORT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_get_capacity( + const psa_key_derivation_operation_t *operation, + size_t *capacity + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_size_t_needs(*capacity); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *capacity); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_GET_CAPACITY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_GET_CAPACITY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_size_t(&rpos, &rremain, capacity); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_input_bytes( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + const uint8_t *data, size_t data_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_derivation_step_t_needs(step) + + psasim_serialise_buffer_needs(data, data_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, data, data_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_INPUT_BYTES, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_INPUT_BYTES server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_input_integer( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + uint64_t value + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_derivation_step_t_needs(step) + + psasim_serialise_uint64_t_needs(value); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step); + if (!ok) { + goto fail; + } + ok = psasim_serialise_uint64_t(&pos, &remaining, value); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_INPUT_INTEGER, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_INPUT_INTEGER server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_input_key( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + mbedtls_svc_key_id_t key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_derivation_step_t_needs(step) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_INPUT_KEY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_INPUT_KEY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_key_agreement( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + mbedtls_svc_key_id_t private_key, + const uint8_t *peer_key, size_t peer_key_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_derivation_step_t_needs(step) + + psasim_serialise_mbedtls_svc_key_id_t_needs(private_key) + + psasim_serialise_buffer_needs(peer_key, peer_key_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, private_key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, peer_key, peer_key_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_KEY_AGREEMENT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_KEY_AGREEMENT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_output_bytes( + psa_key_derivation_operation_t *operation, + uint8_t *output, size_t output_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(output, output_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, output, output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_OUTPUT_BYTES, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_OUTPUT_BYTES server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_output_key( + const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + mbedtls_svc_key_id_t *key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_OUTPUT_KEY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_OUTPUT_KEY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_output_key_ext( + const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + const psa_key_production_parameters_t *params, size_t params_data_length, + mbedtls_svc_key_id_t *key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_production_parameters_t(&pos, &remaining, params, params_data_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_OUTPUT_KEY_EXT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_OUTPUT_KEY_EXT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_set_capacity( + psa_key_derivation_operation_t *operation, + size_t capacity + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_size_t_needs(capacity); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, capacity); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_SET_CAPACITY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_SET_CAPACITY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_derivation_setup( + psa_key_derivation_operation_t *operation, + psa_algorithm_t alg + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_algorithm_t_needs(alg); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_KEY_DERIVATION_SETUP, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_DERIVATION_SETUP server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) @@ -3307,3 +4123,95 @@ psa_status_t psa_mac_verify_setup( return status; } + + +psa_status_t psa_raw_key_agreement( + psa_algorithm_t alg, + mbedtls_svc_key_id_t private_key, + const uint8_t *peer_key, size_t peer_key_length, + uint8_t *output, size_t output_size, + size_t *output_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_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_mbedtls_svc_key_id_t_needs(private_key) + + psasim_serialise_buffer_needs(peer_key, peer_key_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_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_mbedtls_svc_key_id_t(&pos, &remaining, private_key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, peer_key, peer_key_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_RAW_KEY_AGREEMENT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_RAW_KEY_AGREEMENT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 897d50451d..92ce96a904 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -3082,6 +3082,929 @@ int psa_import_key_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_key_derivation_abort_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_key_derivation_operation_t *operation; + + 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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_abort( + operation + ); + + // 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_server_serialise_psa_key_derivation_operation_t_needs(operation); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + 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_key_derivation_get_capacity_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_key_derivation_operation_t *operation; + size_t capacity; + + 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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &capacity); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_get_capacity( + operation, + &capacity + ); + + // 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_size_t_needs(capacity); + + 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_size_t(&rpos, &rremain, capacity); + 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_key_derivation_input_bytes_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_key_derivation_operation_t *operation; + psa_key_derivation_step_t step; + uint8_t *data = NULL; + size_t data_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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_derivation_step_t(&pos, &remaining, &step); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &data, &data_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_input_bytes( + operation, + step, + data, data_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_server_serialise_psa_key_derivation_operation_t_needs(operation); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(data); + + return 1; // success + +fail: + free(result); + + free(data); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_key_derivation_input_integer_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_key_derivation_operation_t *operation; + psa_key_derivation_step_t step; + uint64_t value; + + 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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_derivation_step_t(&pos, &remaining, &step); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_uint64_t(&pos, &remaining, &value); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_input_integer( + operation, + step, + value + ); + + // 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_server_serialise_psa_key_derivation_operation_t_needs(operation); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + 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_key_derivation_input_key_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_key_derivation_operation_t *operation; + psa_key_derivation_step_t step; + mbedtls_svc_key_id_t key; + + 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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_derivation_step_t(&pos, &remaining, &step); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_input_key( + operation, + step, + key + ); + + // 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_server_serialise_psa_key_derivation_operation_t_needs(operation); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + 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_key_derivation_key_agreement_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_key_derivation_operation_t *operation; + psa_key_derivation_step_t step; + mbedtls_svc_key_id_t private_key; + uint8_t *peer_key = NULL; + size_t peer_key_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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_derivation_step_t(&pos, &remaining, &step); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &private_key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &peer_key, &peer_key_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_key_agreement( + operation, + step, + private_key, + peer_key, peer_key_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_server_serialise_psa_key_derivation_operation_t_needs(operation); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(peer_key); + + return 1; // success + +fail: + free(result); + + free(peer_key); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_key_derivation_output_bytes_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_key_derivation_operation_t *operation; + uint8_t *output = NULL; + size_t output_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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_output_bytes( + operation, + output, output_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_server_serialise_psa_key_derivation_operation_t_needs(operation) + + psasim_serialise_buffer_needs(output, output_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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer(&rpos, &rremain, output, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(output); + + return 1; // success + +fail: + free(result); + + free(output); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_key_derivation_output_key_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_key_attributes_t attributes; + psa_key_derivation_operation_t *operation; + mbedtls_svc_key_id_t key; + + 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_key_attributes_t(&pos, &remaining, &attributes); + if (!ok) { + goto fail; + } + + ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_output_key( + &attributes, + operation, + &key + ); + + // 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_server_serialise_psa_key_derivation_operation_t_needs(operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + 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_key_derivation_output_key_ext_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_key_attributes_t attributes; + psa_key_derivation_operation_t *operation; + psa_key_production_parameters_t *params = NULL; + size_t params_data_length; + mbedtls_svc_key_id_t key; + + 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_key_attributes_t(&pos, &remaining, &attributes); + if (!ok) { + goto fail; + } + + ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_production_parameters_t(&pos, &remaining, ¶ms, ¶ms_data_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_output_key_ext( + &attributes, + operation, + params, params_data_length, + &key + ); + + // 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_server_serialise_psa_key_derivation_operation_t_needs(operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(params); + + return 1; // success + +fail: + free(result); + + free(params); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_key_derivation_set_capacity_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_key_derivation_operation_t *operation; + size_t capacity; + + 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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &capacity); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_set_capacity( + operation, + capacity + ); + + // 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_server_serialise_psa_key_derivation_operation_t_needs(operation); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + 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_key_derivation_setup_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_key_derivation_operation_t *operation; + psa_algorithm_t alg; + + 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_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_key_derivation_setup( + operation, + alg + ); + + // 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_server_serialise_psa_key_derivation_operation_t_needs(operation); + + 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_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + 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_mac_abort_wrapper( uint8_t *in_params, size_t in_params_len, @@ -3782,6 +4705,117 @@ int psa_mac_verify_setup_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_raw_key_agreement_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; + mbedtls_svc_key_id_t private_key; + uint8_t *peer_key = NULL; + size_t peer_key_length; + uint8_t *output = NULL; + size_t output_size; + size_t output_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_mbedtls_svc_key_id_t(&pos, &remaining, &private_key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &peer_key, &peer_key_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_raw_key_agreement( + alg, + private_key, + peer_key, peer_key_length, + output, output_size, + &output_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(output, output_size) + + psasim_serialise_size_t_needs(output_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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(peer_key); + free(output); + + return 1; // success + +fail: + free(result); + + free(peer_key); + free(output); + + return 0; // This shouldn't happen! +} + psa_status_t psa_crypto_call(psa_msg_t msg) { int ok = 0; @@ -3954,6 +4988,50 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_import_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_KEY_DERIVATION_ABORT: + ok = psa_key_derivation_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_GET_CAPACITY: + ok = psa_key_derivation_get_capacity_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_INPUT_BYTES: + ok = psa_key_derivation_input_bytes_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_INPUT_INTEGER: + ok = psa_key_derivation_input_integer_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_INPUT_KEY: + ok = psa_key_derivation_input_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_KEY_AGREEMENT: + ok = psa_key_derivation_key_agreement_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_OUTPUT_BYTES: + ok = psa_key_derivation_output_bytes_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_OUTPUT_KEY: + ok = psa_key_derivation_output_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_OUTPUT_KEY_EXT: + ok = psa_key_derivation_output_key_ext_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_SET_CAPACITY: + ok = psa_key_derivation_set_capacity_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_DERIVATION_SETUP: + ok = psa_key_derivation_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_MAC_ABORT: ok = psa_mac_abort_wrapper(in_params, in_params_len, &out_params, &out_params_len); @@ -3986,6 +5064,10 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_mac_verify_setup_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_RAW_KEY_AGREEMENT: + ok = psa_raw_key_agreement_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; } free(in_params); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 97e92bc088..5510be1fe5 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -3321,3 +3321,880 @@ sub put_crypto_init_first * results in this error code. */ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); + +/** \defgroup key_derivation Key derivation and pseudorandom generation + * @{ + */ + +/** The type of the state data structure for key derivation operations. + * + * Before calling any function on a key derivation operation object, the + * application must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_key_derivation_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_key_derivation_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_KEY_DERIVATION_OPERATION_INIT, + * for example: + * \code + * psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_key_derivation_operation_init() + * to the structure, for example: + * \code + * psa_key_derivation_operation_t operation; + * operation = psa_key_derivation_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. + */ +typedef struct psa_key_derivation_s psa_key_derivation_operation_t; + +/** \def PSA_KEY_DERIVATION_OPERATION_INIT + * + * This macro returns a suitable initializer for a key derivation operation + * object of type #psa_key_derivation_operation_t. + */ + +/** Return an initial value for a key derivation operation object. + */ +static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); + +/** Set up a key derivation operation. + * + * A key derivation algorithm takes some inputs and uses them to generate + * a byte stream in a deterministic way. + * This byte stream can be used to produce keys and other + * cryptographic material. + * + * To derive a key: + * -# Start with an initialized object of type #psa_key_derivation_operation_t. + * -# Call psa_key_derivation_setup() to select the algorithm. + * -# Provide the inputs for the key derivation by calling + * psa_key_derivation_input_bytes() or psa_key_derivation_input_key() + * as appropriate. Which inputs are needed, in what order, and whether + * they may be keys and if so of what type depends on the algorithm. + * -# Optionally set the operation's maximum capacity with + * psa_key_derivation_set_capacity(). You may do this before, in the middle + * of or after providing inputs. For some algorithms, this step is mandatory + * because the output depends on the maximum capacity. + * -# To derive a key, call psa_key_derivation_output_key() or + * psa_key_derivation_output_key_ext(). + * To derive a byte string for a different purpose, call + * psa_key_derivation_output_bytes(). + * Successive calls to these functions use successive output bytes + * calculated by the key derivation algorithm. + * -# Clean up the key derivation operation object with + * psa_key_derivation_abort(). + * + * If this function returns an error, the key derivation operation object is + * not changed. + * + * If an error occurs at any step after a call to psa_key_derivation_setup(), + * the operation will need to be reset by a call to psa_key_derivation_abort(). + * + * Implementations must reject an attempt to derive a key of size 0. + * + * \param[in,out] operation The key derivation operation object + * to set up. It must + * have been initialized but not set up yet. + * \param alg The key derivation algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c alg is not a key derivation algorithm. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \c alg is not supported or is not a key derivation algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_setup( + psa_key_derivation_operation_t *operation, + psa_algorithm_t alg); + +/** Retrieve the current capacity of a key derivation operation. + * + * The capacity of a key derivation is the maximum number of bytes that it can + * return. When you get *N* bytes of output from a key derivation operation, + * this reduces its capacity by *N*. + * + * \param[in] operation The operation to query. + * \param[out] capacity On success, the capacity of the operation. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active), or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_get_capacity( + const psa_key_derivation_operation_t *operation, + size_t *capacity); + +/** Set the maximum capacity of a key derivation operation. + * + * The capacity of a key derivation operation is the maximum number of bytes + * that the key derivation operation can return from this point onwards. + * + * \param[in,out] operation The key derivation operation object to modify. + * \param capacity The new capacity of the operation. + * It must be less or equal to the operation's + * current capacity. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p capacity is larger than the operation's current capacity. + * In this case, the operation object remains valid and its capacity + * remains unchanged. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active), or the + * library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_set_capacity( + psa_key_derivation_operation_t *operation, + size_t capacity); + +/** Use the maximum possible capacity for a key derivation operation. + * + * Use this value as the capacity argument when setting up a key derivation + * to indicate that the operation should have the maximum possible capacity. + * The value of the maximum possible capacity depends on the key derivation + * algorithm. + */ +#define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY ((size_t) (-1)) + +/** Provide an input for key derivation or key agreement. + * + * Which inputs are required and in what order depends on the algorithm. + * Refer to the documentation of each key derivation or key agreement + * algorithm for information. + * + * This function passes direct inputs, which is usually correct for + * non-secret inputs. To pass a secret input, which should be in a key + * object, call psa_key_derivation_input_key() instead of this function. + * Refer to the documentation of individual step types + * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) + * for more information. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to use. + * It must have been set up with + * psa_key_derivation_setup() and must not + * have produced any output yet. + * \param step Which step the input data is for. + * \param[in] data Input data to use. + * \param data_length Size of the \p data buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step is not compatible with the operation's algorithm, or + * \c step does not allow direct inputs. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this input \p step, or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_input_bytes( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + const uint8_t *data, + size_t data_length); + +/** Provide a numeric input for key derivation or key agreement. + * + * Which inputs are required and in what order depends on the algorithm. + * However, when an algorithm requires a particular order, numeric inputs + * usually come first as they tend to be configuration parameters. + * Refer to the documentation of each key derivation or key agreement + * algorithm for information. + * + * This function is used for inputs which are fixed-size non-negative + * integers. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to use. + * It must have been set up with + * psa_key_derivation_setup() and must not + * have produced any output yet. + * \param step Which step the input data is for. + * \param[in] value The value of the numeric input. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step is not compatible with the operation's algorithm, or + * \c step does not allow numeric inputs. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this input \p step, or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_input_integer( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + uint64_t value); + +/** Provide an input for key derivation in the form of a key. + * + * Which inputs are required and in what order depends on the algorithm. + * Refer to the documentation of each key derivation or key agreement + * algorithm for information. + * + * This function obtains input from a key object, which is usually correct for + * secret inputs or for non-secret personalization strings kept in the key + * store. To pass a non-secret parameter which is not in the key store, + * call psa_key_derivation_input_bytes() instead of this function. + * Refer to the documentation of individual step types + * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) + * for more information. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to use. + * It must have been set up with + * psa_key_derivation_setup() and must not + * have produced any output yet. + * \param step Which step the input data is for. + * \param key Identifier of the key. It must have an + * appropriate type for step and must allow the + * usage #PSA_KEY_USAGE_DERIVE or + * #PSA_KEY_USAGE_VERIFY_DERIVATION (see note) + * and the algorithm used by the operation. + * + * \note Once all inputs steps are completed, the operations will allow: + * - psa_key_derivation_output_bytes() if each input was either a direct input + * or a key with #PSA_KEY_USAGE_DERIVE set; + * - psa_key_derivation_output_key() or psa_key_derivation_output_key_ext() + * if the input for step + * #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD + * was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was + * either a direct input or a key with #PSA_KEY_USAGE_DERIVE set; + * - psa_key_derivation_verify_bytes() if each input was either a direct input + * or a key with #PSA_KEY_USAGE_VERIFY_DERIVATION set; + * - psa_key_derivation_verify_key() under the same conditions as + * psa_key_derivation_verify_bytes(). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED + * The key allows neither #PSA_KEY_USAGE_DERIVE nor + * #PSA_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this + * algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step is not compatible with the operation's algorithm, or + * \c step does not allow key inputs of the given type + * or does not allow key inputs at all. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this input \p step, or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_input_key( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + mbedtls_svc_key_id_t key); + +/** Perform a key agreement and use the shared secret as input to a key + * derivation. + * + * A key agreement algorithm takes two inputs: a private key \p private_key + * a public key \p peer_key. + * The result of this function is passed as input to a key derivation. + * The output of this key derivation can be extracted by reading from the + * resulting operation to produce keys and other cryptographic material. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to use. + * It must have been set up with + * psa_key_derivation_setup() with a + * key agreement and derivation algorithm + * \c alg (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_KEY_AGREEMENT(\c alg) is true + * and #PSA_ALG_IS_RAW_KEY_AGREEMENT(\c alg) + * is false). + * The operation must be ready for an + * input of the type given by \p step. + * \param step Which step the input data is for. + * \param private_key Identifier of the private key to use. It must + * allow the usage #PSA_KEY_USAGE_DERIVE. + * \param[in] peer_key Public key of the peer. The peer key must be in the + * same format that psa_import_key() accepts for the + * public key type corresponding to the type of + * private_key. That is, this function performs the + * equivalent of + * #psa_import_key(..., + * `peer_key`, `peer_key_length`) where + * with key attributes indicating the public key + * type corresponding to the type of `private_key`. + * For example, for EC keys, this means that peer_key + * is interpreted as a point on the curve that the + * private key is on. The standard formats for public + * keys are documented in the documentation of + * psa_export_public_key(). + * \param peer_key_length Size of \p peer_key in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c private_key is not compatible with \c alg, + * or \p peer_key is not valid for \c alg or not compatible with + * \c private_key, or \c step does not allow an input resulting + * from a key agreement. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \c alg is not supported or is not a key derivation algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this key agreement \p step, + * or the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_key_agreement( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + mbedtls_svc_key_id_t private_key, + const uint8_t *peer_key, + size_t peer_key_length); + +/** Read some data from a key derivation operation. + * + * This function calculates output bytes from a key derivation algorithm and + * return those bytes. + * If you view the key derivation's output as a stream of bytes, this + * function destructively reads the requested number of bytes from the + * stream. + * The operation's capacity decreases by the number of bytes read. + * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to read from. + * \param[out] output Buffer where the output will be written. + * \param output_length Number of bytes to output. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED + * One of the inputs was a key whose policy didn't allow + * #PSA_KEY_USAGE_DERIVE. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * The operation's capacity was less than + * \p output_length bytes. Note that in this case, + * no output is written to the output buffer. + * The operation's capacity is set to 0, thus + * subsequent calls to this function will not + * succeed, even with a smaller output buffer. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_output_bytes( + psa_key_derivation_operation_t *operation, + uint8_t *output, + size_t output_length); + +/** Derive a key from an ongoing key derivation operation. + * + * This function calculates output bytes from a key derivation algorithm + * and uses those bytes to generate a key deterministically. + * The key's location, usage policy, type and size are taken from + * \p attributes. + * + * If you view the key derivation's output as a stream of bytes, this + * function destructively reads as many bytes as required from the + * stream. + * The operation's capacity decreases by the number of bytes read. + * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * How much output is produced and consumed from the operation, and how + * the key is derived, depends on the key type and on the key size + * (denoted \c bits below): + * + * - For key types for which the key is an arbitrary sequence of bytes + * of a given size, this function is functionally equivalent to + * calling #psa_key_derivation_output_bytes + * and passing the resulting output to #psa_import_key. + * However, this function has a security benefit: + * if the implementation provides an isolation boundary then + * the key material is not exposed outside the isolation boundary. + * As a consequence, for these key types, this function always consumes + * exactly (\c bits / 8) bytes from the operation. + * The following key types defined in this specification follow this scheme: + * + * - #PSA_KEY_TYPE_AES; + * - #PSA_KEY_TYPE_ARIA; + * - #PSA_KEY_TYPE_CAMELLIA; + * - #PSA_KEY_TYPE_DERIVE; + * - #PSA_KEY_TYPE_HMAC; + * - #PSA_KEY_TYPE_PASSWORD_HASH. + * + * - For ECC keys on a Montgomery elliptic curve + * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a + * Montgomery curve), this function always draws a byte string whose + * length is determined by the curve, and sets the mandatory bits + * accordingly. That is: + * + * - Curve25519 (#PSA_ECC_FAMILY_MONTGOMERY, 255 bits): draw a 32-byte + * string and process it as specified in RFC 7748 §5. + * - Curve448 (#PSA_ECC_FAMILY_MONTGOMERY, 448 bits): draw a 56-byte + * string and process it as specified in RFC 7748 §5. + * + * - For key types for which the key is represented by a single sequence of + * \c bits bits with constraints as to which bit sequences are acceptable, + * this function draws a byte string of length (\c bits / 8) bytes rounded + * up to the nearest whole number of bytes. If the resulting byte string + * is acceptable, it becomes the key, otherwise the drawn bytes are discarded. + * This process is repeated until an acceptable byte string is drawn. + * The byte string drawn from the operation is interpreted as specified + * for the output produced by psa_export_key(). + * The following key types defined in this specification follow this scheme: + * + * - #PSA_KEY_TYPE_DES. + * Force-set the parity bits, but discard forbidden weak keys. + * For 2-key and 3-key triple-DES, the three keys are generated + * successively (for example, for 3-key triple-DES, + * if the first 8 bytes specify a weak key and the next 8 bytes do not, + * discard the first 8 bytes, use the next 8 bytes as the first key, + * and continue reading output from the operation to derive the other + * two keys). + * - Finite-field Diffie-Hellman keys (#PSA_KEY_TYPE_DH_KEY_PAIR(\c group) + * where \c group designates any Diffie-Hellman group) and + * ECC keys on a Weierstrass elliptic curve + * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a + * Weierstrass curve). + * For these key types, interpret the byte string as integer + * in big-endian order. Discard it if it is not in the range + * [0, *N* - 2] where *N* is the boundary of the private key domain + * (the prime *p* for Diffie-Hellman, the subprime *q* for DSA, + * or the order of the curve's base point for ECC). + * Add 1 to the resulting integer and use this as the private key *x*. + * This method allows compliance to NIST standards, specifically + * the methods titled "key-pair generation by testing candidates" + * in NIST SP 800-56A §5.6.1.1.4 for Diffie-Hellman, + * in FIPS 186-4 §B.1.2 for DSA, and + * in NIST SP 800-56A §5.6.1.2.2 or + * FIPS 186-4 §B.4.2 for elliptic curve keys. + * + * - For other key types, including #PSA_KEY_TYPE_RSA_KEY_PAIR, + * the way in which the operation output is consumed is + * implementation-defined. + * + * In all cases, the data that is read is discarded from the operation. + * The operation's capacity is decreased by the number of bytes read. + * + * For algorithms that take an input step #PSA_KEY_DERIVATION_INPUT_SECRET, + * the input to that step must be provided with psa_key_derivation_input_key(). + * Future versions of this specification may include additional restrictions + * on the derived key based on the attributes and strength of the secret key. + * + * \note This function is equivalent to calling + * psa_key_derivation_output_key_ext() + * with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT + * and `params_data_length == 0` (i.e. `params->data` is empty). + * + * \param[in] attributes The attributes for the new key. + * If the key type to be created is + * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in + * the policy must be the same as in the current + * operation. + * \param[in,out] operation The key derivation operation object to read from. + * \param[out] key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * There was not enough data to create the desired key. + * Note that in this case, no output is written to the output buffer. + * The operation's capacity is set to 0, thus subsequent calls to + * this function will not succeed, even with a smaller output buffer. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The key type or key size is not supported, either by the + * implementation in general or in this particular location. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The provided key attributes are not valid for the operation. + * \retval #PSA_ERROR_NOT_PERMITTED + * The #PSA_KEY_DERIVATION_INPUT_SECRET or + * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a + * key; or one of the inputs was a key whose policy didn't allow + * #PSA_KEY_USAGE_DERIVE. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_output_key( + const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + mbedtls_svc_key_id_t *key); + +/** Derive a key from an ongoing key derivation operation with custom + * production parameters. + * + * See the description of psa_key_derivation_out_key() for the operation of + * this function with the default production parameters. + * Mbed TLS currently does not currently support any non-default production + * parameters. + * + * \note This function is experimental and may change in future minor + * versions of Mbed TLS. + * + * \param[in] attributes The attributes for the new key. + * If the key type to be created is + * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in + * the policy must be the same as in the current + * operation. + * \param[in,out] operation The key derivation operation object to read from. + * \param[in] params Customization parameters for the key derivation. + * When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT + * with \p params_data_length = 0, + * this function is equivalent to + * psa_key_derivation_output_key(). + * Mbed TLS currently only supports the default + * production parameters, i.e. + * #PSA_KEY_PRODUCTION_PARAMETERS_INIT, + * for all key types. + * \param params_data_length + * Length of `params->data` in bytes. + * \param[out] key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * There was not enough data to create the desired key. + * Note that in this case, no output is written to the output buffer. + * The operation's capacity is set to 0, thus subsequent calls to + * this function will not succeed, even with a smaller output buffer. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The key type or key size is not supported, either by the + * implementation in general or in this particular location. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The provided key attributes are not valid for the operation. + * \retval #PSA_ERROR_NOT_PERMITTED + * The #PSA_KEY_DERIVATION_INPUT_SECRET or + * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a + * key; or one of the inputs was a key whose policy didn't allow + * #PSA_KEY_USAGE_DERIVE. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_output_key_ext( + const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + const psa_key_production_parameters_t *params, + size_t params_data_length, + mbedtls_svc_key_id_t *key); + +/** Compare output data from a key derivation operation to an expected value. + * + * This function calculates output bytes from a key derivation algorithm and + * compares those bytes to an expected value in constant time. + * If you view the key derivation's output as a stream of bytes, this + * function destructively reads the expected number of bytes from the + * stream before comparing them. + * The operation's capacity decreases by the number of bytes read. + * + * This is functionally equivalent to the following code: + * \code + * psa_key_derivation_output_bytes(operation, tmp, output_length); + * if (memcmp(output, tmp, output_length) != 0) + * return PSA_ERROR_INVALID_SIGNATURE; + * \endcode + * except (1) it works even if the key's policy does not allow outputting the + * bytes, and (2) the comparison will be done in constant time. + * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE, + * the operation enters an error state and must be aborted by calling + * psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to read from. + * \param[in] expected_output Buffer containing the expected derivation output. + * \param output_length Length of the expected output; this is also the + * number of bytes that will be read. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The output was read successfully, but it differs from the expected + * output. + * \retval #PSA_ERROR_NOT_PERMITTED + * One of the inputs was a key whose policy didn't allow + * #PSA_KEY_USAGE_VERIFY_DERIVATION. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * The operation's capacity was less than + * \p output_length bytes. Note that in this case, + * the operation's capacity is set to 0, thus + * subsequent calls to this function will not + * succeed, even with a smaller expected output. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_verify_bytes( + psa_key_derivation_operation_t *operation, + const uint8_t *expected_output, + size_t output_length); + +/** Compare output data from a key derivation operation to an expected value + * stored in a key object. + * + * This function calculates output bytes from a key derivation algorithm and + * compares those bytes to an expected value, provided as key of type + * #PSA_KEY_TYPE_PASSWORD_HASH. + * If you view the key derivation's output as a stream of bytes, this + * function destructively reads the number of bytes corresponding to the + * length of the expected value from the stream before comparing them. + * The operation's capacity decreases by the number of bytes read. + * + * This is functionally equivalent to exporting the key and calling + * psa_key_derivation_verify_bytes() on the result, except that it + * works even if the key cannot be exported. + * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE, + * the operation enters an error state and must be aborted by calling + * psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to read from. + * \param[in] expected A key of type #PSA_KEY_TYPE_PASSWORD_HASH + * containing the expected output. Its policy must + * include the #PSA_KEY_USAGE_VERIFY_DERIVATION flag + * and the permitted algorithm must match the + * operation. The value of this key was likely + * computed by a previous call to + * psa_key_derivation_output_key() or + * psa_key_derivation_output_key_ext(). + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The output was read successfully, but if differs from the expected + * output. + * \retval #PSA_ERROR_INVALID_HANDLE + * The key passed as the expected value does not exist. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key passed as the expected value has an invalid type. + * \retval #PSA_ERROR_NOT_PERMITTED + * The key passed as the expected value does not allow this usage or + * this algorithm; or one of the inputs was a key whose policy didn't + * allow #PSA_KEY_USAGE_VERIFY_DERIVATION. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * The operation's capacity was less than + * the length of the expected value. In this case, + * the operation's capacity is set to 0, thus + * subsequent calls to this function will not + * succeed, even with a smaller expected output. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_verify_key( + psa_key_derivation_operation_t *operation, + psa_key_id_t expected); + +/** Abort a key derivation operation. + * + * Aborting an operation frees all associated resources except for the \c + * operation structure itself. Once aborted, the operation object can be reused + * for another operation by calling psa_key_derivation_setup() again. + * + * This function may be called at any time after the operation + * object has been initialized as described in #psa_key_derivation_operation_t. + * + * In particular, it is valid to call psa_key_derivation_abort() twice, or to + * call psa_key_derivation_abort() on an operation that has not been set up. + * + * \param[in,out] operation The operation to abort. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_abort( + psa_key_derivation_operation_t *operation); + +/** Perform a key agreement and return the raw shared secret. + * + * \warning The raw result of a key agreement algorithm such as finite-field + * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should + * not be used directly as key material. It should instead be passed as + * input to a key derivation algorithm. To chain a key agreement with + * a key derivation, use psa_key_derivation_key_agreement() and other + * functions from the key derivation interface. + * + * \param alg The key agreement algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_RAW_KEY_AGREEMENT(\p alg) + * is true). + * \param private_key Identifier of the private key to use. It must + * allow the usage #PSA_KEY_USAGE_DERIVE. + * \param[in] peer_key Public key of the peer. It must be + * in the same format that psa_import_key() + * accepts. The standard formats for public + * keys are documented in the documentation + * of psa_export_public_key(). + * \param peer_key_length Size of \p peer_key in bytes. + * \param[out] output Buffer where the decrypted message is to + * be written. + * \param output_size Size of the \c output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p alg is not a key agreement algorithm, or + * \p private_key is not compatible with \p alg, + * or \p peer_key is not valid for \p alg or not compatible with + * \p private_key. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p output_size is too small + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not a supported key agreement algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, + mbedtls_svc_key_id_t private_key, + const uint8_t *peer_key, + size_t peer_key_length, + uint8_t *output, + size_t output_size, + size_t *output_length); diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 975abd2bb9..4de78021ef 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -215,6 +215,44 @@ static ssize_t find_cipher_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } +static psa_key_derivation_operation_t key_derivation_operations[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t key_derivation_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t next_key_derivation_operation_handle = 1; + +/* Get a free slot */ +static ssize_t allocate_key_derivation_operation_slot(void) +{ + psasim_client_handle_t handle = next_key_derivation_operation_handle++; + if (next_key_derivation_operation_handle == 0) { /* wrapped around */ + FATAL("Key_derivation operation handle wrapped"); + } + + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (key_derivation_operation_handles[i] == 0) { + key_derivation_operation_handles[i] = handle; + return i; + } + } + + ERROR("All slots are currently used. Unable to allocate a new one."); + + return -1; /* all in use */ +} + +/* Find the slot given the handle */ +static ssize_t find_key_derivation_slot_by_handle(psasim_client_handle_t handle) +{ + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (key_derivation_operation_handles[i] == handle) { + return i; + } + } + + ERROR("Unable to find slot by handle %u", handle); + + return -1; /* not found */ +} + size_t psasim_serialise_begin_needs(void) { /* The serialisation buffer will @@ -394,6 +432,76 @@ int psasim_deserialise_size_t(uint8_t **pos, return 1; } +size_t psasim_serialise_uint16_t_needs(uint16_t value) +{ + return sizeof(value); +} + +int psasim_serialise_uint16_t(uint8_t **pos, + size_t *remaining, + uint16_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_uint16_t(uint8_t **pos, + size_t *remaining, + uint16_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_serialise_uint64_t_needs(uint64_t value) +{ + return sizeof(value); +} + +int psasim_serialise_uint64_t(uint8_t **pos, + size_t *remaining, + uint64_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_uint64_t(uint8_t **pos, + size_t *remaining, + uint64_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + size_t psasim_serialise_buffer_needs(const uint8_t *buffer, size_t buffer_size) { (void) buffer; @@ -496,6 +604,100 @@ int psasim_deserialise_return_buffer(uint8_t **pos, return 1; } +#define SER_TAG_SIZE 4 + +size_t psasim_serialise_psa_key_production_parameters_t_needs( + const psa_key_production_parameters_t *params, + size_t data_length) +{ + /* We will serialise with 4-byte tag = "PKPP" + 4-byte overall length at the beginning, + * followed by size_t data_length, then the actual data from the structure. + */ + return SER_TAG_SIZE + sizeof(uint32_t) + sizeof(data_length) + sizeof(*params) + data_length; +} + +int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos, + size_t *remaining, + const psa_key_production_parameters_t *params, + size_t data_length) +{ + if (data_length > UINT32_MAX / 2) { /* arbitrary limit */ + return 0; /* too big to serialise */ + } + + /* We use 32-bit lengths, which should be enough for any reasonable usage :) */ + /* (the UINT32_MAX / 2 above is an even more conservative check to avoid overflow here) */ + uint32_t len = (uint32_t) (sizeof(data_length) + sizeof(*params) + data_length); + if (*remaining < SER_TAG_SIZE + sizeof(uint32_t) + len) { + return 0; + } + + char tag[SER_TAG_SIZE] = "PKPP"; + + memcpy(*pos, tag, sizeof(tag)); + memcpy(*pos + sizeof(tag), &len, sizeof(len)); + *pos += sizeof(tag) + sizeof(len); + *remaining -= sizeof(tag) + sizeof(len); + + memcpy(*pos, &data_length, sizeof(data_length)); + memcpy(*pos + sizeof(data_length), params, sizeof(*params) + data_length); + *pos += sizeof(data_length) + sizeof(*params) + data_length; + *remaining -= sizeof(data_length) + sizeof(*params) + data_length; + + return 1; +} + +int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, + size_t *remaining, + psa_key_production_parameters_t **params, + size_t *data_length) +{ + if (*remaining < SER_TAG_SIZE + sizeof(uint32_t)) { + return 0; /* can't even be an empty serialisation */ + } + + char tag[SER_TAG_SIZE] = "PKPP"; /* expected */ + uint32_t len; + + memcpy(&len, *pos + sizeof(tag), sizeof(len)); + + if (memcmp(*pos, tag, sizeof(tag)) != 0) { + return 0; /* wrong tag */ + } + + *pos += sizeof(tag) + sizeof(len); + *remaining -= sizeof(tag) + sizeof(len); + + if (*remaining < sizeof(*data_length)) { + return 0; /* missing data_length */ + } + memcpy(data_length, *pos, sizeof(*data_length)); + + if ((size_t)len != (sizeof(data_length) + sizeof(**params) + *data_length)) { + return 0; /* wrong length */ + } + + if (*remaining < sizeof(*data_length) + sizeof(**params) + *data_length) { + return 0; /* not enough data provided */ + } + + *pos += sizeof(data_length); + *remaining -= sizeof(data_length); + + psa_key_production_parameters_t *out = malloc(sizeof(**params) + *data_length); + if (out == NULL) { + return 0; /* allocation failure */ + } + + memcpy(out, *pos, sizeof(*out) + *data_length); + *pos += sizeof(*out) + *data_length; + *remaining -= sizeof(*out) + *data_length; + + *params = out; + + return 1; +} + size_t psasim_serialise_psa_status_t_needs(psa_status_t value) { return psasim_serialise_int_needs(value); @@ -534,6 +736,25 @@ int psasim_deserialise_psa_algorithm_t(uint8_t **pos, return psasim_deserialise_unsigned_int(pos, remaining, value); } +size_t psasim_serialise_psa_key_derivation_step_t_needs(psa_key_derivation_step_t value) +{ + return psasim_serialise_uint16_t_needs(value); +} + +int psasim_serialise_psa_key_derivation_step_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_step_t value) +{ + return psasim_serialise_uint16_t(pos, remaining, value); +} + +int psasim_deserialise_psa_key_derivation_step_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_step_t *value) +{ + return psasim_deserialise_uint16_t(pos, remaining, value); +} + size_t psasim_serialise_psa_hash_operation_t_needs(psa_hash_operation_t value) { return sizeof(value); @@ -941,6 +1162,99 @@ int psasim_server_deserialise_psa_cipher_operation_t(uint8_t **pos, return 1; } +size_t psasim_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_key_derivation_operation_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_operation_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_key_derivation_operation_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_operation_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_server_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t *operation) +{ + (void) operation; + + /* We will actually return a handle */ + return sizeof(psasim_operation_t); +} + +int psasim_server_serialise_psa_key_derivation_operation_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_operation_t *operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(client_operation)) { + return 0; + } + + ssize_t slot = operation - key_derivation_operations; + + client_operation.handle = key_derivation_operation_handles[slot]; + + memcpy(*pos, &client_operation, sizeof(client_operation)); + *pos += sizeof(client_operation); + + return 1; +} + +int psasim_server_deserialise_psa_key_derivation_operation_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_operation_t **operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(psasim_operation_t)) { + return 0; + } + + memcpy(&client_operation, *pos, sizeof(psasim_operation_t)); + *pos += sizeof(psasim_operation_t); + *remaining -= sizeof(psasim_operation_t); + + ssize_t slot; + if (client_operation.handle == 0) { /* We need a new handle */ + slot = allocate_key_derivation_operation_slot(); + } else { + slot = find_key_derivation_slot_by_handle(client_operation.handle); + } + + if (slot < 0) { + return 0; + } + + *operation = &key_derivation_operations[slot]; + + return 1; +} + size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value) { return sizeof(value); @@ -986,4 +1300,6 @@ void psa_sim_serialize_reset(void) memset(mac_operations, 0, sizeof(mac_operations)); memset(cipher_operation_handles, 0, sizeof(cipher_operation_handles)); memset(cipher_operations, 0, sizeof(cipher_operations)); + memset(key_derivation_operation_handles, 0, sizeof(key_derivation_operation_handles)); + memset(key_derivation_operations, 0, sizeof(key_derivation_operations)); } diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 55b2acb3da..1028518dd6 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -222,6 +222,90 @@ int psasim_deserialise_size_t(uint8_t **pos, size_t *remaining, size_t *value); +/** Return how much buffer space is needed by \c psasim_serialise_uint16_t() + * to serialise an `uint16_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_uint16_t() to serialise + * the given value. + */ +size_t psasim_serialise_uint16_t_needs(uint16_t value); + +/** Serialise an `uint16_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_uint16_t(uint8_t **pos, + size_t *remaining, + uint16_t value); + +/** Deserialise an `uint16_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to an `uint16_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_uint16_t(uint8_t **pos, + size_t *remaining, + uint16_t *value); + +/** Return how much buffer space is needed by \c psasim_serialise_uint64_t() + * to serialise an `uint64_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_uint64_t() to serialise + * the given value. + */ +size_t psasim_serialise_uint64_t_needs(uint64_t value); + +/** Serialise an `uint64_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_uint64_t(uint8_t **pos, + size_t *remaining, + uint64_t value); + +/** Deserialise an `uint64_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to an `uint64_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_uint64_t(uint8_t **pos, + size_t *remaining, + uint64_t *value); + /** Return how much space is needed by \c psasim_serialise_buffer() * to serialise a buffer: a (`uint8_t *`, `size_t`) pair. * @@ -289,6 +373,56 @@ int psasim_deserialise_buffer(uint8_t **pos, size_t *remaining, int psasim_deserialise_return_buffer(uint8_t **pos, size_t *remaining, uint8_t *buffer, size_t buffer_length); +/** Return how much space is needed by \c psasim_serialise_psa_key_production_parameters_t() + * to serialise a psa_key_production_parameters_t (a structure with a flexible array member). + * + * \param params Pointer to the struct to be serialised + * (needed in case some serialisations are value- + * dependent). + * \param data_length Number of bytes in the data[] of the struct to be serialised. + * + * \return The number of bytes needed in the serialisation buffer by + * \c psasim_serialise_psa_key_production_parameters_t() to serialise + * the specified structure. + */ +size_t psasim_serialise_psa_key_production_parameters_t_needs( + const psa_key_production_parameters_t *params, + size_t buffer_size); + +/** Serialise a psa_key_production_parameters_t. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param params Pointer to the structure to be serialised. + * \param data_length Number of bytes in the data[] of the struct to be serialised. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos, + size_t *remaining, + const psa_key_production_parameters_t *params, + size_t data_length); + +/** Deserialise a psa_key_production_parameters_t. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the serialisation buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the serialisation buffer. + * \param params Pointer to a `psa_key_production_parameters_t *` to + * receive the address of a newly-allocated structure, + * which the caller must `free()`. + * \param data_length Pointer to a `size_t` to receive the number of + * bytes in the data[] member of the structure deserialised. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, size_t *remaining, + psa_key_production_parameters_t **params, + size_t *buffer_length); + /** Return how much buffer space is needed by \c psasim_serialise_psa_status_t() * to serialise a `psa_status_t`. * @@ -373,6 +507,48 @@ int psasim_deserialise_psa_algorithm_t(uint8_t **pos, size_t *remaining, psa_algorithm_t *value); +/** Return how much buffer space is needed by \c psasim_serialise_psa_key_derivation_step_t() + * to serialise a `psa_key_derivation_step_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_key_derivation_step_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_key_derivation_step_t_needs(psa_key_derivation_step_t value); + +/** Serialise a `psa_key_derivation_step_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_key_derivation_step_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_step_t value); + +/** Deserialise a `psa_key_derivation_step_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_key_derivation_step_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_key_derivation_step_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_step_t *value); + /** Return how much buffer space is needed by \c psasim_serialise_psa_hash_operation_t() * to serialise a `psa_hash_operation_t`. * @@ -751,6 +927,90 @@ int psasim_server_deserialise_psa_cipher_operation_t(uint8_t **pos, size_t *remaining, psa_cipher_operation_t **value); +/** Return how much buffer space is needed by \c psasim_serialise_psa_key_derivation_operation_t() + * to serialise a `psa_key_derivation_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_key_derivation_operation_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t value); + +/** Serialise a `psa_key_derivation_operation_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_key_derivation_operation_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_operation_t value); + +/** Deserialise a `psa_key_derivation_operation_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_key_derivation_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_key_derivation_operation_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_operation_t *value); + +/** Return how much buffer space is needed by \c psasim_server_serialise_psa_key_derivation_operation_t() + * to serialise a `psa_key_derivation_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_key_derivation_operation_t() to serialise + * the given value. + */ +size_t psasim_server_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t *value); + +/** Serialise a `psa_key_derivation_operation_t` into a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_serialise_psa_key_derivation_operation_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_operation_t *value); + +/** Deserialise a `psa_key_derivation_operation_t` from a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_key_derivation_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_deserialise_psa_key_derivation_operation_t(uint8_t **pos, + size_t *remaining, + psa_key_derivation_operation_t **value); + /** Return how much buffer space is needed by \c psasim_serialise_mbedtls_svc_key_id_t() * to serialise a `mbedtls_svc_key_id_t`. * diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 6b23f5c411..43ba661634 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -36,13 +36,16 @@ # are). # my @types = qw(unsigned-int int size_t + uint16_t uint64_t buffer - psa_status_t psa_algorithm_t + psa_key_production_parameters_t + psa_status_t psa_algorithm_t psa_key_derivation_step_t psa_hash_operation_t psa_aead_operation_t psa_key_attributes_t psa_mac_operation_t psa_cipher_operation_t + psa_key_derivation_operation_t mbedtls_svc_key_id_t); grep(s/-/ /g, @types); @@ -51,6 +54,7 @@ my %isa = ( "psa_status_t" => "int", "psa_algorithm_t" => "unsigned int", + "psa_key_derivation_step_t" => "uint16_t", ); if ($which eq "h") { From fb61ab5649a3da4b31f221592e98c9f55978d418 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 16:13:01 +0100 Subject: [PATCH 061/125] psasim: add support for psa_generate_key*() to the simulator Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 2 + psasim/src/psa_sim_crypto_client.c | 144 ++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 172 +++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 105 ++++++++++++++++++ 4 files changed, 423 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index c9b72e6f68..39142c5e58 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -34,6 +34,8 @@ enum { PSA_CIPHER_SET_IV, PSA_CIPHER_UPDATE, PSA_DESTROY_KEY, + PSA_GENERATE_KEY, + PSA_GENERATE_KEY_EXT, PSA_GENERATE_RANDOM, PSA_GET_KEY_ATTRIBUTES, PSA_HASH_ABORT, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 84f2b5a6ab..5b84f2d84b 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -1918,6 +1918,150 @@ psa_status_t psa_destroy_key( } +psa_status_t psa_generate_key( + const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_GENERATE_KEY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_GENERATE_KEY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_mbedtls_svc_key_id_t(&rpos, &rremain, key); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_generate_key_ext( + const psa_key_attributes_t *attributes, + const psa_key_production_parameters_t *params, size_t params_data_length, + mbedtls_svc_key_id_t *key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_production_parameters_t(&pos, &remaining, params, params_data_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_GENERATE_KEY_EXT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_GENERATE_KEY_EXT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_mbedtls_svc_key_id_t(&rpos, &rremain, key); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + psa_status_t psa_generate_random( uint8_t *output, size_t output_size ) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 92ce96a904..5d6b608a90 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -2172,6 +2172,170 @@ int psa_destroy_key_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_generate_key_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_key_attributes_t attributes; + mbedtls_svc_key_id_t key; + + 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_key_attributes_t(&pos, &remaining, &attributes); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_generate_key( + &attributes, + &key + ); + + // 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_mbedtls_svc_key_id_t_needs(key); + + 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_mbedtls_svc_key_id_t(&rpos, &rremain, key); + 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_generate_key_ext_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_key_attributes_t attributes; + psa_key_production_parameters_t *params = NULL; + size_t params_data_length; + mbedtls_svc_key_id_t key; + + 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_key_attributes_t(&pos, &remaining, &attributes); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_production_parameters_t(&pos, &remaining, ¶ms, ¶ms_data_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_generate_key_ext( + &attributes, + params, params_data_length, + &key + ); + + // 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_mbedtls_svc_key_id_t_needs(key); + + 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_mbedtls_svc_key_id_t(&rpos, &rremain, key); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(params); + + return 1; // success + +fail: + free(result); + + free(params); + + return 0; // This shouldn't happen! +} + // Returns 1 for success, 0 for failure int psa_generate_random_wrapper( uint8_t *in_params, size_t in_params_len, @@ -4944,6 +5108,14 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_destroy_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_GENERATE_KEY: + ok = psa_generate_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_GENERATE_KEY_EXT: + ok = psa_generate_key_ext_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_GENERATE_RANDOM: ok = psa_generate_random_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 5510be1fe5..42f7ac7bd1 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -4198,3 +4198,108 @@ sub put_crypto_init_first uint8_t *output, size_t output_size, size_t *output_length); + +/** + * \brief Generate a key or key pair. + * + * The key is generated randomly. + * Its location, usage policy, type and size are taken from \p attributes. + * + * Implementations must reject an attempt to generate a key of size 0. + * + * The following type-specific considerations apply: + * - For RSA keys (#PSA_KEY_TYPE_RSA_KEY_PAIR), + * the public exponent is 65537. + * The modulus is a product of two probabilistic primes + * between 2^{n-1} and 2^n where n is the bit size specified in the + * attributes. + * + * \note This function is equivalent to calling psa_generate_key_ext() + * with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT + * and `params_data_length == 0` (i.e. `params->data` is empty). + * + * \param[in] attributes The attributes for the new key. + * \param[out] key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *key); + +/** + * \brief Generate a key or key pair using custom production parameters. + * + * See the description of psa_generate_key() for the operation of this + * function with the default production parameters. In addition, this function + * supports the following production customizations, described in more detail + * in the documentation of ::psa_key_production_parameters_t: + * + * - RSA keys: generation with a custom public exponent. + * + * \note This function is experimental and may change in future minor + * versions of Mbed TLS. + * + * \param[in] attributes The attributes for the new key. + * \param[in] params Customization parameters for the key generation. + * When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT + * with \p params_data_length = 0, + * this function is equivalent to + * psa_generate_key(). + * \param params_data_length + * Length of `params->data` in bytes. + * \param[out] key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, + const psa_key_production_parameters_t *params, + size_t params_data_length, + mbedtls_svc_key_id_t *key); From 079c654d1b7f25f5915d8189fe6eda861c4460b2 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 16:15:28 +0100 Subject: [PATCH 062/125] psasim: add support for psa_{sign,verify}_{message,hash}() to the simulator Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 4 + psasim/src/psa_sim_crypto_client.c | 336 +++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 422 +++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 221 +++++++++++++++ 4 files changed, 983 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 39142c5e58..1e5739fac7 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -67,6 +67,10 @@ enum { PSA_MAC_VERIFY_FINISH, PSA_MAC_VERIFY_SETUP, PSA_RAW_KEY_AGREEMENT, + PSA_SIGN_HASH, + PSA_SIGN_MESSAGE, + PSA_VERIFY_HASH, + PSA_VERIFY_MESSAGE, }; #endif /* _PSA_FUNCTIONS_CODES_H_ */ diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 5b84f2d84b..8be8b073b7 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -4359,3 +4359,339 @@ psa_status_t psa_raw_key_agreement( return status; } + + +psa_status_t psa_sign_hash( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + uint8_t *signature, size_t signature_size, + size_t *signature_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(hash, hash_length) + + psasim_serialise_buffer_needs(signature, signature_size) + + psasim_serialise_size_t_needs(*signature_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *signature_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_SIGN_HASH, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_SIGN_HASH server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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, signature, signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, signature_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_sign_message( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + uint8_t *signature, size_t signature_size, + size_t *signature_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(signature, signature_size) + + psasim_serialise_size_t_needs(*signature_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, signature, signature_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *signature_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_SIGN_MESSAGE, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_SIGN_MESSAGE server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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, signature, signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, signature_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_verify_hash( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(hash, hash_length) + + psasim_serialise_buffer_needs(signature, signature_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_VERIFY_HASH, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_VERIFY_HASH server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_verify_message( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *signature, size_t signature_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(signature, signature_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, signature, signature_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_VERIFY_MESSAGE, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_VERIFY_MESSAGE server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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(ser_params); + free(ser_result); + + return status; +} diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 5d6b608a90..7ad0d67750 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -4980,6 +4980,412 @@ int psa_raw_key_agreement_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_sign_hash_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *hash = NULL; + size_t hash_length; + uint8_t *signature = NULL; + size_t signature_size; + size_t signature_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &signature_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_sign_hash( + key, + alg, + hash, hash_length, + signature, signature_size, + &signature_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(signature, signature_size) + + psasim_serialise_size_t_needs(signature_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, signature, signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, signature_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(hash); + free(signature); + + return 1; // success + +fail: + free(result); + + free(hash); + free(signature); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_sign_message_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *signature = NULL; + size_t signature_size; + size_t signature_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &signature, &signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &signature_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_sign_message( + key, + alg, + input, input_length, + signature, signature_size, + &signature_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(signature, signature_size) + + psasim_serialise_size_t_needs(signature_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, signature, signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, signature_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(signature); + + return 1; // success + +fail: + free(result); + + free(input); + free(signature); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_verify_hash_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *hash = NULL; + size_t hash_length; + uint8_t *signature = NULL; + size_t signature_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_verify_hash( + key, + alg, + hash, hash_length, + signature, signature_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); + + 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; + + free(hash); + free(signature); + + return 1; // success + +fail: + free(result); + + free(hash); + free(signature); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_verify_message_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *signature = NULL; + size_t signature_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &signature, &signature_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_verify_message( + key, + alg, + input, input_length, + signature, signature_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); + + 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; + + free(input); + free(signature); + + return 1; // success + +fail: + free(result); + + free(input); + free(signature); + + return 0; // This shouldn't happen! +} + psa_status_t psa_crypto_call(psa_msg_t msg) { int ok = 0; @@ -5240,6 +5646,22 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_raw_key_agreement_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_SIGN_HASH: + ok = psa_sign_hash_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_SIGN_MESSAGE: + ok = psa_sign_message_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_VERIFY_HASH: + ok = psa_verify_hash_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_VERIFY_MESSAGE: + ok = psa_verify_message_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; } free(in_params); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 42f7ac7bd1..e641433644 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -4303,3 +4303,224 @@ sub put_crypto_init_first const psa_key_production_parameters_t *params, size_t params_data_length, mbedtls_svc_key_id_t *key); + +/** + * \brief Sign a message with a private key. For hash-and-sign algorithms, + * this includes the hashing step. + * + * \note To perform a multi-part hash-and-sign signature algorithm, first use + * a multi-part hash operation and then pass the resulting hash to + * psa_sign_hash(). PSA_ALG_GET_HASH(\p alg) can be used to determine the + * hash algorithm to use. + * + * \param[in] key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. The key must + * allow the usage #PSA_KEY_USAGE_SIGN_MESSAGE. + * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) + * is true), that is compatible with the type of + * \p key. + * \param[in] input The input message to sign. + * \param[in] input_length Size of the \p input buffer in bytes. + * \param[out] signature Buffer where the signature is to be written. + * \param[in] signature_size Size of the \p signature buffer in bytes. This + * must be appropriate for the selected + * algorithm and key: + * - The required signature size is + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and + * bit-size respectively of key. + * - #PSA_SIGNATURE_MAX_SIZE evaluates to the + * maximum signature size of any supported + * signature algorithm. + * \param[out] signature_length On success, the number of bytes that make up + * the returned signature value. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, + * or it does not permit the requested algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p signature buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length); + +/** \brief Verify the signature of a message with a public key, using + * a hash-and-sign verification algorithm. + * + * \note To perform a multi-part hash-and-sign signature verification + * algorithm, first use a multi-part hash operation to hash the message + * and then pass the resulting hash to psa_verify_hash(). + * PSA_ALG_GET_HASH(\p alg) can be used to determine the hash algorithm + * to use. + * + * \param[in] key Identifier of the key to use for the operation. + * It must be a public key or an asymmetric key + * pair. The key must allow the usage + * #PSA_KEY_USAGE_VERIFY_MESSAGE. + * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) + * is true), that is compatible with the type of + * \p key. + * \param[in] input The message whose signature is to be verified. + * \param[in] input_length Size of the \p input buffer in bytes. + * \param[in] signature Buffer containing the signature to verify. + * \param[in] signature_length Size of the \p signature buffer in bytes. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, + * or it does not permit the requested algorithm. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculation was performed successfully, but the passed signature + * is not a valid signature. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length); + +/** + * \brief Sign a hash or short message with a private key. + * + * Note that to perform a hash-and-sign signature algorithm, you must + * first calculate the hash by calling psa_hash_setup(), psa_hash_update() + * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). + * Then pass the resulting hash as the \p hash + * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) + * to determine the hash algorithm to use. + * + * \param key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. The key must + * allow the usage #PSA_KEY_USAGE_SIGN_HASH. + * \param alg A signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) + * is true), that is compatible with + * the type of \p key. + * \param[in] hash The hash or message to sign. + * \param hash_length Size of the \p hash buffer in bytes. + * \param[out] signature Buffer where the signature is to be written. + * \param signature_size Size of the \p signature buffer in bytes. + * \param[out] signature_length On success, the number of bytes + * that make up the returned signature value. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p signature buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length); + +/** + * \brief Verify the signature of a hash or short message using a public key. + * + * Note that to perform a hash-and-sign signature algorithm, you must + * first calculate the hash by calling psa_hash_setup(), psa_hash_update() + * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). + * Then pass the resulting hash as the \p hash + * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) + * to determine the hash algorithm to use. + * + * \param key Identifier of the key to use for the operation. It + * must be a public key or an asymmetric key pair. The + * key must allow the usage + * #PSA_KEY_USAGE_VERIFY_HASH. + * \param alg A signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) + * is true), that is compatible with + * the type of \p key. + * \param[in] hash The hash or message whose signature is to be + * verified. + * \param hash_length Size of the \p hash buffer in bytes. + * \param[in] signature Buffer containing the signature to verify. + * \param signature_length Size of the \p signature buffer in bytes. + * + * \retval #PSA_SUCCESS + * The signature is valid. + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculation was performed successfully, but the passed + * signature is not a valid signature. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + const uint8_t *signature, + size_t signature_length); From 2bd6bfac76e1ed2d22fe990a33d52c9bbd9d269d Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 16:17:30 +0100 Subject: [PATCH 063/125] psasim: add support for psa_asymmetric_{encrypt,decrypt}() to the simulator Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 2 + psasim/src/psa_sim_crypto_client.c | 196 ++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 250 +++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 122 ++++++++++++++ 4 files changed, 570 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 1e5739fac7..fbbdea2db8 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -24,6 +24,8 @@ enum { PSA_AEAD_UPDATE, PSA_AEAD_UPDATE_AD, PSA_AEAD_VERIFY, + PSA_ASYMMETRIC_DECRYPT, + PSA_ASYMMETRIC_ENCRYPT, PSA_CIPHER_ABORT, PSA_CIPHER_DECRYPT, PSA_CIPHER_DECRYPT_SETUP, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 8be8b073b7..8dd85a317f 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -1133,6 +1133,202 @@ psa_status_t psa_aead_verify( } +psa_status_t psa_asymmetric_decrypt( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, + size_t *output_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(salt, salt_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, salt, salt_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_ASYMMETRIC_DECRYPT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_ASYMMETRIC_DECRYPT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_asymmetric_encrypt( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, + size_t *output_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(salt, salt_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, salt, salt_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_ASYMMETRIC_ENCRYPT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_ASYMMETRIC_ENCRYPT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 7ad0d67750..ae803491ea 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -1261,6 +1261,248 @@ int psa_aead_verify_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_asymmetric_decrypt_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *salt = NULL; + size_t salt_length; + uint8_t *output = NULL; + size_t output_size; + size_t output_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &salt, &salt_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_asymmetric_decrypt( + key, + alg, + input, input_length, + salt, salt_length, + output, output_size, + &output_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(output, output_size) + + psasim_serialise_size_t_needs(output_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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(salt); + free(output); + + return 1; // success + +fail: + free(result); + + free(input); + free(salt); + free(output); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_asymmetric_encrypt_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *salt = NULL; + size_t salt_length; + uint8_t *output = NULL; + size_t output_size; + size_t output_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &salt, &salt_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_asymmetric_encrypt( + key, + alg, + input, input_length, + salt, salt_length, + output, output_size, + &output_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(output, output_size) + + psasim_serialise_size_t_needs(output_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, output, output_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(salt); + free(output); + + return 1; // success + +fail: + free(result); + + free(input); + free(salt); + free(output); + + return 0; // This shouldn't happen! +} + // Returns 1 for success, 0 for failure int psa_cipher_abort_wrapper( uint8_t *in_params, size_t in_params_len, @@ -5474,6 +5716,14 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_aead_verify_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_ASYMMETRIC_DECRYPT: + ok = psa_asymmetric_decrypt_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_ASYMMETRIC_ENCRYPT: + ok = psa_asymmetric_encrypt_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_CIPHER_ABORT: ok = psa_cipher_abort_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index e641433644..82a6249f3b 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -4524,3 +4524,125 @@ sub put_crypto_init_first size_t hash_length, const uint8_t *signature, size_t signature_length); + +/** + * \brief Encrypt a short message with a public key. + * + * \param key Identifier of the key to use for the operation. + * It must be a public key or an asymmetric key + * pair. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. + * \param alg An asymmetric encryption algorithm that is + * compatible with the type of \p key. + * \param[in] input The message to encrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[in] salt A salt or label, if supported by the + * encryption algorithm. + * If the algorithm does not support a + * salt, pass \c NULL. + * If the algorithm supports an optional + * salt and you do not want to pass a salt, + * pass \c NULL. + * + * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is + * supported. + * \param salt_length Size of the \p salt buffer in bytes. + * If \p salt is \c NULL, pass 0. + * \param[out] output Buffer where the encrypted message is to + * be written. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *salt, + size_t salt_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** + * \brief Decrypt a short message with a private key. + * + * \param key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. It must + * allow the usage #PSA_KEY_USAGE_DECRYPT. + * \param alg An asymmetric encryption algorithm that is + * compatible with the type of \p key. + * \param[in] input The message to decrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[in] salt A salt or label, if supported by the + * encryption algorithm. + * If the algorithm does not support a + * salt, pass \c NULL. + * If the algorithm supports an optional + * salt and you do not want to pass a salt, + * pass \c NULL. + * + * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is + * supported. + * \param salt_length Size of the \p salt buffer in bytes. + * If \p salt is \c NULL, pass 0. + * \param[out] output Buffer where the decrypted message is to + * be written. + * \param output_size Size of the \c output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_INVALID_PADDING \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *salt, + size_t salt_length, + uint8_t *output, + size_t output_size, + size_t *output_length); From 1c1005b16b9e0ff3ffb091baea40c11070aa1b89 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 16:26:03 +0100 Subject: [PATCH 064/125] psasim: add support for key functions that don't need psa_key_attributes_t Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 3 + psasim/src/psa_sim_crypto_client.c | 218 ++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 263 +++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 191 +++++++++++++++++++++ 4 files changed, 675 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index fbbdea2db8..04401d11b9 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -36,6 +36,8 @@ enum { PSA_CIPHER_SET_IV, PSA_CIPHER_UPDATE, PSA_DESTROY_KEY, + PSA_EXPORT_KEY, + PSA_EXPORT_PUBLIC_KEY, PSA_GENERATE_KEY, PSA_GENERATE_KEY_EXT, PSA_GENERATE_RANDOM, @@ -68,6 +70,7 @@ enum { PSA_MAC_VERIFY, PSA_MAC_VERIFY_FINISH, PSA_MAC_VERIFY_SETUP, + PSA_PURGE_KEY, PSA_RAW_KEY_AGREEMENT, PSA_SIGN_HASH, PSA_SIGN_MESSAGE, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 8dd85a317f..67a66ff95f 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -2114,6 +2114,166 @@ psa_status_t psa_destroy_key( } +psa_status_t psa_export_key( + mbedtls_svc_key_id_t key, + uint8_t *data, size_t data_size, + size_t *data_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_buffer_needs(data, data_size) + + psasim_serialise_size_t_needs(*data_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, data, data_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *data_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_EXPORT_KEY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_EXPORT_KEY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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, data, data_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, data_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_export_public_key( + mbedtls_svc_key_id_t key, + uint8_t *data, size_t data_size, + size_t *data_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_buffer_needs(data, data_size) + + psasim_serialise_size_t_needs(*data_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, data, data_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *data_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_EXPORT_PUBLIC_KEY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_EXPORT_PUBLIC_KEY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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, data, data_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, data_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *key @@ -4465,6 +4625,64 @@ psa_status_t psa_mac_verify_setup( } +psa_status_t psa_purge_key( + mbedtls_svc_key_id_t key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_PURGE_KEY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_PURGE_KEY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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(ser_params); + free(ser_result); + + return status; +} + + psa_status_t psa_raw_key_agreement( psa_algorithm_t alg, mbedtls_svc_key_id_t private_key, diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index ae803491ea..41b4bc6516 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -2414,6 +2414,194 @@ int psa_destroy_key_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_export_key_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; + mbedtls_svc_key_id_t key; + uint8_t *data = NULL; + size_t data_size; + size_t data_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &data, &data_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &data_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_export_key( + key, + data, data_size, + &data_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(data, data_size) + + psasim_serialise_size_t_needs(data_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, data, data_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, data_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(data); + + return 1; // success + +fail: + free(result); + + free(data); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_export_public_key_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; + mbedtls_svc_key_id_t key; + uint8_t *data = NULL; + size_t data_size; + size_t data_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &data, &data_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &data_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_export_public_key( + key, + data, data_size, + &data_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(data, data_size) + + psasim_serialise_size_t_needs(data_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, data, data_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, data_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(data); + + return 1; // success + +fail: + free(result); + + free(data); + + return 0; // This shouldn't happen! +} + // Returns 1 for success, 0 for failure int psa_generate_key_wrapper( uint8_t *in_params, size_t in_params_len, @@ -5111,6 +5299,69 @@ int psa_mac_verify_setup_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_purge_key_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; + mbedtls_svc_key_id_t key; + + 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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_purge_key( + key + ); + + // 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_raw_key_agreement_wrapper( uint8_t *in_params, size_t in_params_len, @@ -5764,6 +6015,14 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_destroy_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_EXPORT_KEY: + ok = psa_export_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_EXPORT_PUBLIC_KEY: + ok = psa_export_public_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_GENERATE_KEY: ok = psa_generate_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); @@ -5892,6 +6151,10 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_mac_verify_setup_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_PURGE_KEY: + ok = psa_purge_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_RAW_KEY_AGREEMENT: ok = psa_raw_key_agreement_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 82a6249f3b..1c27487b35 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -4646,3 +4646,194 @@ sub put_crypto_init_first uint8_t *output, size_t output_size, size_t *output_length); + +/** Remove non-essential copies of key material from memory. + * + * If the key identifier designates a volatile key, this functions does not do + * anything and returns successfully. + * + * If the key identifier designates a persistent key, then this function will + * free all resources associated with the key in volatile memory. The key + * data in persistent storage is not affected and the key can still be used. + * + * \param key Identifier of the key to purge. + * + * \retval #PSA_SUCCESS + * The key material will have been removed from memory if it is not + * currently required. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not a valid key identifier. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); + +/** + * \brief Export a key in binary format. + * + * The output of this function can be passed to psa_import_key() to + * create an equivalent object. + * + * If the implementation of psa_import_key() supports other formats + * beyond the format specified here, the output from psa_export_key() + * must use the representation specified here, not the original + * representation. + * + * For standard key types, the output format is as follows: + * + * - For symmetric keys (including MAC keys), the format is the + * raw bytes of the key. + * - For DES, the key data consists of 8 bytes. The parity bits must be + * correct. + * - For Triple-DES, the format is the concatenation of the + * two or three DES keys. + * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEY_PAIR), the format + * is the non-encrypted DER encoding of the representation defined by + * PKCS\#1 (RFC 8017) as `RSAPrivateKey`, version 0. + * ``` + * RSAPrivateKey ::= SEQUENCE { + * version INTEGER, -- must be 0 + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * } + * ``` + * - For elliptic curve key pairs (key types for which + * #PSA_KEY_TYPE_IS_ECC_KEY_PAIR is true), the format is + * a representation of the private value as a `ceiling(m/8)`-byte string + * where `m` is the bit size associated with the curve, i.e. the bit size + * of the order of the curve's coordinate field. This byte string is + * in little-endian order for Montgomery curves (curve types + * `PSA_ECC_FAMILY_CURVEXXX`), and in big-endian order for Weierstrass + * curves (curve types `PSA_ECC_FAMILY_SECTXXX`, `PSA_ECC_FAMILY_SECPXXX` + * and `PSA_ECC_FAMILY_BRAINPOOL_PXXX`). + * For Weierstrass curves, this is the content of the `privateKey` field of + * the `ECPrivateKey` format defined by RFC 5915. For Montgomery curves, + * the format is defined by RFC 7748, and output is masked according to §5. + * For twisted Edwards curves, the private key is as defined by RFC 8032 + * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). + * - For Diffie-Hellman key exchange key pairs (key types for which + * #PSA_KEY_TYPE_IS_DH_KEY_PAIR is true), the + * format is the representation of the private key `x` as a big-endian byte + * string. The length of the byte string is the private key size in bytes + * (leading zeroes are not stripped). + * - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is + * true), the format is the same as for psa_export_public_key(). + * + * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set. + * + * \param key Identifier of the key to export. It must allow the + * usage #PSA_KEY_USAGE_EXPORT, unless it is a public + * key. + * \param[out] data Buffer where the key data is to be written. + * \param data_size Size of the \p data buffer in bytes. + * \param[out] data_length On success, the number of bytes + * that make up the key data. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_EXPORT flag. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p data buffer is too small. You can determine a + * sufficient buffer size by calling + * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits) + * where \c type is the key type + * and \c bits is the key size in bits. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_export_key(mbedtls_svc_key_id_t key, + uint8_t *data, + size_t data_size, + size_t *data_length); + +/** + * \brief Export a public key or the public part of a key pair in binary format. + * + * The output of this function can be passed to psa_import_key() to + * create an object that is equivalent to the public key. + * + * This specification supports a single format for each key type. + * Implementations may support other formats as long as the standard + * format is supported. Implementations that support other formats + * should ensure that the formats are clearly unambiguous so as to + * minimize the risk that an invalid input is accidentally interpreted + * according to a different format. + * + * For standard key types, the output format is as follows: + * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of + * the representation defined by RFC 3279 §2.3.1 as `RSAPublicKey`. + * ``` + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER } -- e + * ``` + * - For elliptic curve keys on a twisted Edwards curve (key types for which + * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true and #PSA_KEY_TYPE_ECC_GET_FAMILY + * returns #PSA_ECC_FAMILY_TWISTED_EDWARDS), the public key is as defined + * by RFC 8032 + * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). + * - For other elliptic curve public keys (key types for which + * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed + * representation defined by SEC1 §2.3.3 as the content of an ECPoint. + * Let `m` be the bit size associated with the curve, i.e. the bit size of + * `q` for a curve over `F_q`. The representation consists of: + * - The byte 0x04; + * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; + * - `y_P` as a `ceiling(m/8)`-byte string, big-endian. + * - For Diffie-Hellman key exchange public keys (key types for which + * #PSA_KEY_TYPE_IS_DH_PUBLIC_KEY is true), + * the format is the representation of the public key `y = g^x mod p` as a + * big-endian byte string. The length of the byte string is the length of the + * base prime `p` in bytes. + * + * Exporting a public key object or the public part of a key pair is + * always permitted, regardless of the key's usage flags. + * + * \param key Identifier of the key to export. + * \param[out] data Buffer where the key data is to be written. + * \param data_size Size of the \p data buffer in bytes. + * \param[out] data_length On success, the number of bytes + * that make up the key data. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key is neither a public key nor a key pair. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p data buffer is too small. You can determine a + * sufficient buffer size by calling + * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits) + * where \c type is the key type + * and \c bits is the key size in bits. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, + uint8_t *data, + size_t data_size, + size_t *data_length); From 3e689c8486532f2be06c1ccef3a911d3e8b7f48a Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 17:05:53 +0100 Subject: [PATCH 065/125] psasim: add support for PSA functions that return uint32_t or void Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 43 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 1c27487b35..dfbced1d74 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -529,6 +529,9 @@ sub output_server_wrapper uint8_t *in_params, size_t in_params_len, uint8_t **out_params, size_t *out_params_len) { +EOF + + print $fh <{return}->{name}; my $args = $f->{args}; - print $fh "\n $ret_name = $name(\n"; + if ($ret_name eq "(void)") { + print $fh "\n $name(\n"; + } else { + print $fh "\n $ret_name = $name(\n"; + } print $fh " );\n" if $#$args < 0; # If no arguments, empty arg list @@ -1025,7 +1056,7 @@ sub get_functions my %funcs = (); for (my $i = 0; $i <= $#src; $i++) { my $line = $src[$i]; - if ($line =~ /^psa_status_t (psa_\w*)\(/) { # begin function definition + if ($line =~ /^(psa_status_t|uint32_t|void) (psa_\w*)\(/) { # begin function definition #print "have one $line\n"; while ($line !~ /;/) { $line .= $src[$i + 1]; @@ -1044,9 +1075,13 @@ sub get_functions my $ret_name = ""; $ret_name = "status" if $ret_type eq "psa_status_t"; + $ret_name = "value" if $ret_type eq "uint32_t"; + $ret_name = "(void)" if $ret_type eq "void"; die("ret_name for $ret_type?") unless length($ret_name); my $ret_default = ""; $ret_default = "PSA_ERROR_CORRUPTION_DETECTED" if $ret_type eq "psa_status_t"; + $ret_default = "0" if $ret_type eq "uint32_t"; + $ret_default = "(void)" if $ret_type eq "void"; die("ret_default for $ret_type?") unless length($ret_default); #print "FUNC $func RET_NAME $ret_name RET_TYPE $ret_type ARGS (", join("; ", @args), ")\n"; From b0b20eaf59b069ad7c7980e411a0d1b0100c32d1 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 17:09:11 +0100 Subject: [PATCH 066/125] psasim: add support for psa_{sign,verify}_hash_xxx() and get/set max ops Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 10 + psasim/src/psa_sim_crypto_client.c | 715 +++++++++++++++++++++- psasim/src/psa_sim_crypto_server.c | 938 ++++++++++++++++++++++++++--- psasim/src/psa_sim_generate.pl | 552 +++++++++++++++++ psasim/src/psa_sim_serialise.c | 301 +++++++++ psasim/src/psa_sim_serialise.h | 210 +++++++ psasim/src/psa_sim_serialise.pl | 4 +- 7 files changed, 2622 insertions(+), 108 deletions(-) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 04401d11b9..68d9f031f1 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -51,6 +51,8 @@ enum { PSA_HASH_UPDATE, PSA_HASH_VERIFY, PSA_IMPORT_KEY, + PSA_INTERRUPTIBLE_GET_MAX_OPS, + PSA_INTERRUPTIBLE_SET_MAX_OPS, PSA_KEY_DERIVATION_ABORT, PSA_KEY_DERIVATION_GET_CAPACITY, PSA_KEY_DERIVATION_INPUT_BYTES, @@ -73,8 +75,16 @@ enum { PSA_PURGE_KEY, PSA_RAW_KEY_AGREEMENT, PSA_SIGN_HASH, + PSA_SIGN_HASH_ABORT, + PSA_SIGN_HASH_COMPLETE, + PSA_SIGN_HASH_GET_NUM_OPS, + PSA_SIGN_HASH_START, PSA_SIGN_MESSAGE, PSA_VERIFY_HASH, + PSA_VERIFY_HASH_ABORT, + PSA_VERIFY_HASH_COMPLETE, + PSA_VERIFY_HASH_GET_NUM_OPS, + PSA_VERIFY_HASH_START, PSA_VERIFY_MESSAGE, }; diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 67a66ff95f..36fdfdb761 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -3205,6 +3205,109 @@ psa_status_t psa_import_key( } +uint32_t psa_interruptible_get_max_ops( + void +) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + uint32_t value = 0; + + size_t needed = psasim_serialise_begin_needs() + + 0; + + ser_params = malloc(needed); + if (ser_params == NULL) { + value = 0; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_INTERRUPTIBLE_GET_MAX_OPS, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_INTERRUPTIBLE_GET_MAX_OPS server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_uint32_t(&rpos, &rremain, &value); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return value; +} + + +void psa_interruptible_set_max_ops( + uint32_t max_ops + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_uint32_t_needs(max_ops); + + ser_params = malloc(needed); + if (ser_params == NULL) { + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_uint32_t(&pos, &remaining, max_ops); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_INTERRUPTIBLE_SET_MAX_OPS, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_INTERRUPTIBLE_SET_MAX_OPS server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); +} + + psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation ) @@ -4867,12 +4970,8 @@ psa_status_t psa_sign_hash( } -psa_status_t psa_sign_message( - mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, size_t input_length, - uint8_t *signature, size_t signature_size, - size_t *signature_length +psa_status_t psa_sign_hash_abort( + psa_sign_hash_interruptible_operation_t *operation ) { uint8_t *ser_params = NULL; @@ -4881,11 +4980,7 @@ psa_status_t psa_sign_message( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(signature, signature_size) + - psasim_serialise_size_t_needs(*signature_length); + psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4900,15 +4995,74 @@ psa_status_t psa_sign_message( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + + ok = psa_crypto_call(PSA_SIGN_HASH_ABORT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { + printf("PSA_SIGN_HASH_ABORT server call failed\n"); goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + + uint8_t *rpos = ser_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_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_sign_hash_complete( + psa_sign_hash_interruptible_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(signature, signature_size) + + psasim_serialise_size_t_needs(*signature_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, *operation); if (!ok) { goto fail; } @@ -4921,10 +5075,10 @@ psa_status_t psa_sign_message( goto fail; } - ok = psa_crypto_call(PSA_SIGN_MESSAGE, + ok = psa_crypto_call(PSA_SIGN_HASH_COMPLETE, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_SIGN_MESSAGE server call failed\n"); + printf("PSA_SIGN_HASH_COMPLETE server call failed\n"); goto fail; } @@ -4941,6 +5095,11 @@ psa_status_t psa_sign_message( goto fail; } + ok = psasim_deserialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + ok = psasim_deserialise_return_buffer(&rpos, &rremain, signature, signature_size); if (!ok) { goto fail; @@ -4959,11 +5118,69 @@ psa_status_t psa_sign_message( } -psa_status_t psa_verify_hash( +uint32_t psa_sign_hash_get_num_ops( + const psa_sign_hash_interruptible_operation_t *operation + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + uint32_t value = 0; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation); + + ser_params = malloc(needed); + if (ser_params == NULL) { + value = 0; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_SIGN_HASH_GET_NUM_OPS, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_SIGN_HASH_GET_NUM_OPS server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_uint32_t(&rpos, &rremain, &value); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return value; +} + + +psa_status_t psa_sign_hash_start( + psa_sign_hash_interruptible_operation_t *operation, mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length + const uint8_t *hash, size_t hash_length ) { uint8_t *ser_params = NULL; @@ -4972,10 +5189,10 @@ psa_status_t psa_verify_hash( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation) + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(hash, hash_length) + - psasim_serialise_buffer_needs(signature, signature_length); + psasim_serialise_buffer_needs(hash, hash_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4990,27 +5207,27 @@ psa_status_t psa_verify_hash( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length); + ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_VERIFY_HASH, + ok = psa_crypto_call(PSA_SIGN_HASH_START, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_VERIFY_HASH server call failed\n"); + printf("PSA_SIGN_HASH_START server call failed\n"); goto fail; } @@ -5027,6 +5244,450 @@ psa_status_t psa_verify_hash( goto fail; } + ok = psasim_deserialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_sign_message( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + uint8_t *signature, size_t signature_size, + size_t *signature_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(signature, signature_size) + + psasim_serialise_size_t_needs(*signature_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + 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, signature, signature_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t(&pos, &remaining, *signature_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_SIGN_MESSAGE, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_SIGN_MESSAGE server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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, signature, signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&rpos, &rremain, signature_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_verify_hash( + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(hash, hash_length) + + psasim_serialise_buffer_needs(signature, signature_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_VERIFY_HASH, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_VERIFY_HASH server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_verify_hash_abort( + psa_verify_hash_interruptible_operation_t *operation + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_VERIFY_HASH_ABORT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_VERIFY_HASH_ABORT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_verify_hash_complete( + psa_verify_hash_interruptible_operation_t *operation + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_VERIFY_HASH_COMPLETE, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_VERIFY_HASH_COMPLETE server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +uint32_t psa_verify_hash_get_num_ops( + const psa_verify_hash_interruptible_operation_t *operation + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + uint32_t value = 0; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); + + ser_params = malloc(needed); + if (ser_params == NULL) { + value = 0; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_VERIFY_HASH_GET_NUM_OPS, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_VERIFY_HASH_GET_NUM_OPS server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_uint32_t(&rpos, &rremain, &value); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return value; +} + + +psa_status_t psa_verify_hash_start( + psa_verify_hash_interruptible_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(hash, hash_length) + + psasim_serialise_buffer_needs(signature, signature_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_VERIFY_HASH_START, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_VERIFY_HASH_START server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + fail: free(ser_params); free(ser_result); diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 41b4bc6516..eb313760bf 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -3676,6 +3676,111 @@ int psa_import_key_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_interruptible_get_max_ops_wrapper( + uint8_t *in_params, size_t in_params_len, + uint8_t **out_params, size_t *out_params_len) +{ + uint32_t value = 0; + + uint8_t *result = NULL; + int ok; + + // Now we call the actual target function + + value = psa_interruptible_get_max_ops( + ); + + // NOTE: Should really check there is no overflow as we go along. + size_t result_size = + psasim_serialise_begin_needs() + + psasim_serialise_uint32_t_needs(value); + + 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_uint32_t(&rpos, &rremain, value); + 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_interruptible_set_max_ops_wrapper( + uint8_t *in_params, size_t in_params_len, + uint8_t **out_params, size_t *out_params_len) +{ + uint32_t max_ops; + + 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_uint32_t(&pos, &remaining, &max_ops); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + psa_interruptible_set_max_ops( + max_ops + ); + + // NOTE: Should really check there is no overflow as we go along. + size_t result_size = + psasim_serialise_begin_needs(); + + 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; + } + + *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_key_derivation_abort_wrapper( uint8_t *in_params, size_t in_params_len, @@ -5585,18 +5690,12 @@ int psa_sign_hash_wrapper( } // Returns 1 for success, 0 for failure -int psa_sign_message_wrapper( +int psa_sign_hash_abort_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; - mbedtls_svc_key_id_t key; - psa_algorithm_t alg; - uint8_t *input = NULL; - size_t input_length; - uint8_t *signature = NULL; - size_t signature_size; - size_t signature_length; + psa_sign_hash_interruptible_operation_t *operation; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -5608,17 +5707,79 @@ int psa_sign_message_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + // Now we call the actual target function + + status = psa_sign_hash_abort( + operation + ); + + // 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_server_serialise_psa_sign_hash_interruptible_operation_t_needs(operation); + + 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_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + if (!ok) { + goto fail; + } + + ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + 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_sign_hash_complete_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_sign_hash_interruptible_operation_t *operation; + uint8_t *signature = NULL; + size_t signature_size; + size_t signature_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_server_deserialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } @@ -5635,10 +5796,8 @@ int psa_sign_message_wrapper( // Now we call the actual target function - status = psa_sign_message( - key, - alg, - input, input_length, + status = psa_sign_hash_complete( + operation, signature, signature_size, &signature_length ); @@ -5647,6 +5806,7 @@ int psa_sign_message_wrapper( size_t result_size = psasim_serialise_begin_needs() + psasim_serialise_psa_status_t_needs(status) + + psasim_server_serialise_psa_sign_hash_interruptible_operation_t_needs(operation) + psasim_serialise_buffer_needs(signature, signature_size) + psasim_serialise_size_t_needs(signature_length); @@ -5668,6 +5828,11 @@ int psa_sign_message_wrapper( goto fail; } + ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer(&rpos, &rremain, signature, signature_size); if (!ok) { goto fail; @@ -5681,7 +5846,6 @@ int psa_sign_message_wrapper( *out_params = result; *out_params_len = result_size; - free(input); free(signature); return 1; // success @@ -5689,24 +5853,18 @@ int psa_sign_message_wrapper( fail: free(result); - free(input); free(signature); return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_verify_hash_wrapper( +int psa_sign_hash_get_num_ops_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; - mbedtls_svc_key_id_t key; - psa_algorithm_t alg; - uint8_t *hash = NULL; - size_t hash_length; - uint8_t *signature = NULL; - size_t signature_length; + uint32_t value = 0; + psa_sign_hash_interruptible_operation_t *operation; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -5718,39 +5876,21 @@ int psa_verify_hash_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); - if (!ok) { - goto fail; - } - - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); - if (!ok) { - goto fail; - } - - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); - if (!ok) { - goto fail; - } - - ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length); + ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_verify_hash( - key, - alg, - hash, hash_length, - signature, signature_length + value = psa_sign_hash_get_num_ops( + operation ); // 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_uint32_t_needs(value); result = malloc(result_size); if (result == NULL) { @@ -5765,7 +5905,7 @@ int psa_verify_hash_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_uint32_t(&rpos, &rremain, value); if (!ok) { goto fail; } @@ -5773,32 +5913,25 @@ int psa_verify_hash_wrapper( *out_params = result; *out_params_len = result_size; - free(hash); - free(signature); - return 1; // success fail: free(result); - free(hash); - free(signature); - return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_verify_message_wrapper( +int psa_sign_hash_start_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_sign_hash_interruptible_operation_t *operation; mbedtls_svc_key_id_t key; psa_algorithm_t alg; - uint8_t *input = NULL; - size_t input_length; - uint8_t *signature = NULL; - size_t signature_length; + uint8_t *hash = NULL; + size_t hash_length; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -5810,39 +5943,40 @@ int psa_verify_message_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length); + ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_verify_message( + status = psa_sign_hash_start( + operation, key, alg, - input, input_length, - signature, signature_length + hash, 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_psa_status_t_needs(status) + + psasim_server_serialise_psa_sign_hash_interruptible_operation_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -5862,33 +5996,637 @@ int psa_verify_message_wrapper( goto fail; } + ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + *out_params = result; *out_params_len = result_size; - free(input); - free(signature); + free(hash); return 1; // success fail: free(result); - free(input); - free(signature); + free(hash); return 0; // This shouldn't happen! } -psa_status_t psa_crypto_call(psa_msg_t msg) +// Returns 1 for success, 0 for failure +int psa_sign_message_wrapper( + uint8_t *in_params, size_t in_params_len, + uint8_t **out_params, size_t *out_params_len) { - 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; - } + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *signature = NULL; + size_t signature_size; + size_t signature_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &signature, &signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t(&pos, &remaining, &signature_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_sign_message( + key, + alg, + input, input_length, + signature, signature_size, + &signature_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(signature, signature_size) + + psasim_serialise_size_t_needs(signature_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, signature, signature_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t(&rpos, &rremain, signature_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + free(signature); + + return 1; // success + +fail: + free(result); + + free(input); + free(signature); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_verify_hash_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *hash = NULL; + size_t hash_length; + uint8_t *signature = NULL; + size_t signature_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_verify_hash( + key, + alg, + hash, hash_length, + signature, signature_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); + + 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; + + free(hash); + free(signature); + + return 1; // success + +fail: + free(result); + + free(hash); + free(signature); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_verify_hash_abort_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_verify_hash_interruptible_operation_t *operation; + + 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_server_deserialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_verify_hash_abort( + operation + ); + + // 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_server_serialise_psa_verify_hash_interruptible_operation_t_needs(operation); + + 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_server_serialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + 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_verify_hash_complete_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_verify_hash_interruptible_operation_t *operation; + + 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_server_deserialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_verify_hash_complete( + operation + ); + + // 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_server_serialise_psa_verify_hash_interruptible_operation_t_needs(operation); + + 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_server_serialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + 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_verify_hash_get_num_ops_wrapper( + uint8_t *in_params, size_t in_params_len, + uint8_t **out_params, size_t *out_params_len) +{ + uint32_t value = 0; + psa_verify_hash_interruptible_operation_t *operation; + + 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_server_deserialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + value = psa_verify_hash_get_num_ops( + operation + ); + + // NOTE: Should really check there is no overflow as we go along. + size_t result_size = + psasim_serialise_begin_needs() + + psasim_serialise_uint32_t_needs(value); + + 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_uint32_t(&rpos, &rremain, value); + 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_verify_hash_start_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_verify_hash_interruptible_operation_t *operation; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *hash = NULL; + size_t hash_length; + uint8_t *signature = NULL; + size_t signature_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_server_deserialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_verify_hash_start( + operation, + key, + alg, + hash, hash_length, + signature, signature_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_server_serialise_psa_verify_hash_interruptible_operation_t_needs(operation); + + 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_server_serialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(hash); + free(signature); + + return 1; // success + +fail: + free(result); + + free(hash); + free(signature); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_verify_message_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; + mbedtls_svc_key_id_t key; + psa_algorithm_t alg; + uint8_t *input = NULL; + size_t input_length; + uint8_t *signature = NULL; + size_t signature_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_mbedtls_svc_key_id_t(&pos, &remaining, &key); + 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, &signature, &signature_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_verify_message( + key, + alg, + input, input_length, + signature, signature_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); + + 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; + + free(input); + free(signature); + + return 1; // success + +fail: + free(result); + + free(input); + free(signature); + + 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 || @@ -6075,6 +6813,14 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_import_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_INTERRUPTIBLE_GET_MAX_OPS: + ok = psa_interruptible_get_max_ops_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_INTERRUPTIBLE_SET_MAX_OPS: + ok = psa_interruptible_set_max_ops_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_KEY_DERIVATION_ABORT: ok = psa_key_derivation_abort_wrapper(in_params, in_params_len, &out_params, &out_params_len); @@ -6163,6 +6909,22 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_sign_hash_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_SIGN_HASH_ABORT: + ok = psa_sign_hash_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_SIGN_HASH_COMPLETE: + ok = psa_sign_hash_complete_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_SIGN_HASH_GET_NUM_OPS: + ok = psa_sign_hash_get_num_ops_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_SIGN_HASH_START: + ok = psa_sign_hash_start_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_SIGN_MESSAGE: ok = psa_sign_message_wrapper(in_params, in_params_len, &out_params, &out_params_len); @@ -6171,6 +6933,22 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_verify_hash_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_VERIFY_HASH_ABORT: + ok = psa_verify_hash_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_VERIFY_HASH_COMPLETE: + ok = psa_verify_hash_complete_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_VERIFY_HASH_GET_NUM_OPS: + ok = psa_verify_hash_get_num_ops_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_VERIFY_HASH_START: + ok = psa_verify_hash_start_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_VERIFY_MESSAGE: ok = psa_verify_message_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index dfbced1d74..344ad2594e 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -4872,3 +4872,555 @@ sub put_crypto_init_first uint8_t *data, size_t data_size, size_t *data_length); + +/** + * \brief Set the maximum number of ops allowed to be + * executed by an interruptible function in a + * single call. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note The time taken to execute a single op is + * implementation specific and depends on + * software, hardware, the algorithm, key type and + * curve chosen. Even within a single operation, + * successive ops can take differing amounts of + * time. The only guarantee is that lower values + * for \p max_ops means functions will block for a + * lesser maximum amount of time. The functions + * \c psa_sign_interruptible_get_num_ops() and + * \c psa_verify_interruptible_get_num_ops() are + * provided to help with tuning this value. + * + * \note This value defaults to + * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, which + * means the whole operation will be done in one + * go, regardless of the number of ops required. + * + * \note If more ops are needed to complete a + * computation, #PSA_OPERATION_INCOMPLETE will be + * returned by the function performing the + * computation. It is then the caller's + * responsibility to either call again with the + * same operation context until it returns 0 or an + * error code; or to call the relevant abort + * function if the answer is no longer required. + * + * \note The interpretation of \p max_ops is also + * implementation defined. On a hard real time + * system, this can indicate a hard deadline, as a + * real-time system needs a guarantee of not + * spending more than X time, however care must be + * taken in such an implementation to avoid the + * situation whereby calls just return, not being + * able to do any actual work within the allotted + * time. On a non-real-time system, the + * implementation can be more relaxed, but again + * whether this number should be interpreted as as + * hard or soft limit or even whether a less than + * or equals as regards to ops executed in a + * single call is implementation defined. + * + * \note For keys in local storage when no accelerator + * driver applies, please see also the + * documentation for \c mbedtls_ecp_set_max_ops(), + * which is the internal implementation in these + * cases. + * + * \warning With implementations that interpret this number + * as a hard limit, setting this number too small + * may result in an infinite loop, whereby each + * call results in immediate return with no ops + * done (as there is not enough time to execute + * any), and thus no result will ever be achieved. + * + * \note This only applies to functions whose + * documentation mentions they may return + * #PSA_OPERATION_INCOMPLETE. + * + * \param max_ops The maximum number of ops to be executed in a + * single call. This can be a number from 0 to + * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0 + * is the least amount of work done per call. + */ +void psa_interruptible_set_max_ops(uint32_t max_ops); + +/** + * \brief Get the maximum number of ops allowed to be + * executed by an interruptible function in a + * single call. This will return the last + * value set by + * \c psa_interruptible_set_max_ops() or + * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED if + * that function has never been called. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \return Maximum number of ops allowed to be + * executed by an interruptible function in a + * single call. + */ +uint32_t psa_interruptible_get_max_ops(void); + +/** + * \brief Get the number of ops that a hash signing + * operation has taken so far. If the operation + * has completed, then this will represent the + * number of ops required for the entire + * operation. After initialization or calling + * \c psa_sign_hash_interruptible_abort() on + * the operation, a value of 0 will be returned. + * + * \note This interface is guaranteed re-entrant and + * thus may be called from driver code. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * This is a helper provided to help you tune the + * value passed to \c + * psa_interruptible_set_max_ops(). + * + * \param operation The \c psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \return Number of ops that the operation has taken so + * far. + */ +uint32_t psa_sign_hash_get_num_ops( + const psa_sign_hash_interruptible_operation_t *operation); + +/** + * \brief Get the number of ops that a hash verification + * operation has taken so far. If the operation + * has completed, then this will represent the + * number of ops required for the entire + * operation. After initialization or calling \c + * psa_verify_hash_interruptible_abort() on the + * operation, a value of 0 will be returned. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * This is a helper provided to help you tune the + * value passed to \c + * psa_interruptible_set_max_ops(). + * + * \param operation The \c + * psa_verify_hash_interruptible_operation_t to + * use. This must be initialized first. + * + * \return Number of ops that the operation has taken so + * far. + */ +uint32_t psa_verify_hash_get_num_ops( + const psa_verify_hash_interruptible_operation_t *operation); + +/** + * \brief Start signing a hash or short message with a + * private key, in an interruptible manner. + * + * \see \c psa_sign_hash_complete() + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function combined with \c + * psa_sign_hash_complete() is equivalent to + * \c psa_sign_hash() but + * \c psa_sign_hash_complete() can return early and + * resume according to the limit set with \c + * psa_interruptible_set_max_ops() to reduce the + * maximum time spent in a function call. + * + * \note Users should call \c psa_sign_hash_complete() + * repeatedly on the same context after a + * successful call to this function until \c + * psa_sign_hash_complete() either returns 0 or an + * error. \c psa_sign_hash_complete() will return + * #PSA_OPERATION_INCOMPLETE if there is more work + * to do. Alternatively users can call + * \c psa_sign_hash_abort() at any point if they no + * longer want the result. + * + * \note If this function returns an error status, the + * operation enters an error state and must be + * aborted by calling \c psa_sign_hash_abort(). + * + * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \param key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. The key must + * allow the usage #PSA_KEY_USAGE_SIGN_HASH. + * \param alg A signature algorithm (\c PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) + * is true), that is compatible with + * the type of \p key. + * \param[in] hash The hash or message to sign. + * \param hash_length Size of the \p hash buffer in bytes. + * + * \retval #PSA_SUCCESS + * The operation started successfully - call \c psa_sign_hash_complete() + * with the same context to complete the operation + * + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_SIGN_HASH flag, or it does + * not permit the requested algorithm. + * \retval #PSA_ERROR_BAD_STATE + * An operation has previously been started on this context, and is + * still in progress. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_hash_start( + psa_sign_hash_interruptible_operation_t *operation, + mbedtls_svc_key_id_t key, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length); + +/** + * \brief Continue and eventually complete the action of + * signing a hash or short message with a private + * key, in an interruptible manner. + * + * \see \c psa_sign_hash_start() + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function combined with \c + * psa_sign_hash_start() is equivalent to + * \c psa_sign_hash() but this function can return + * early and resume according to the limit set with + * \c psa_interruptible_set_max_ops() to reduce the + * maximum time spent in a function call. + * + * \note Users should call this function on the same + * operation object repeatedly until it either + * returns 0 or an error. This function will return + * #PSA_OPERATION_INCOMPLETE if there is more work + * to do. Alternatively users can call + * \c psa_sign_hash_abort() at any point if they no + * longer want the result. + * + * \note When this function returns successfully, the + * operation becomes inactive. If this function + * returns an error status, the operation enters an + * error state and must be aborted by calling + * \c psa_sign_hash_abort(). + * + * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first, and have + * had \c psa_sign_hash_start() called with it + * first. + * + * \param[out] signature Buffer where the signature is to be written. + * \param signature_size Size of the \p signature buffer in bytes. This + * must be appropriate for the selected + * algorithm and key: + * - The required signature size is + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c + * key_bits, \c alg) where \c key_type and \c + * key_bits are the type and bit-size + * respectively of key. + * - #PSA_SIGNATURE_MAX_SIZE evaluates to the + * maximum signature size of any supported + * signature algorithm. + * \param[out] signature_length On success, the number of bytes that make up + * the returned signature value. + * + * \retval #PSA_SUCCESS + * Operation completed successfully + * + * \retval #PSA_OPERATION_INCOMPLETE + * Operation was interrupted due to the setting of \c + * psa_interruptible_set_max_ops(). There is still work to be done. + * Call this function again with the same operation object. + * + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p signature buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \c alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \c key. + * + * \retval #PSA_ERROR_BAD_STATE + * An operation was not previously started on this context via + * \c psa_sign_hash_start(). + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has either not been previously initialized by + * psa_crypto_init() or you did not previously call + * psa_sign_hash_start() with this operation object. It is + * implementation-dependent whether a failure to initialize results in + * this error code. + */ +psa_status_t psa_sign_hash_complete( + psa_sign_hash_interruptible_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + +/** + * \brief Abort a sign hash operation. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function is the only function that clears + * the number of ops completed as part of the + * operation. Please ensure you copy this value via + * \c psa_sign_hash_get_num_ops() if required + * before calling. + * + * \note Aborting an operation frees all associated + * resources except for the \p operation structure + * itself. Once aborted, the operation object can + * be reused for another operation by calling \c + * psa_sign_hash_start() again. + * + * \note You may call this function any time after the + * operation object has been initialized. In + * particular, calling \c psa_sign_hash_abort() + * after the operation has already been terminated + * by a call to \c psa_sign_hash_abort() or + * psa_sign_hash_complete() is safe. + * + * \param[in,out] operation Initialized sign hash operation. + * + * \retval #PSA_SUCCESS + * The operation was aborted successfully. + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_hash_abort( + psa_sign_hash_interruptible_operation_t *operation); + +/** + * \brief Start reading and verifying a hash or short + * message, in an interruptible manner. + * + * \see \c psa_verify_hash_complete() + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function combined with \c + * psa_verify_hash_complete() is equivalent to + * \c psa_verify_hash() but \c + * psa_verify_hash_complete() can return early and + * resume according to the limit set with \c + * psa_interruptible_set_max_ops() to reduce the + * maximum time spent in a function. + * + * \note Users should call \c psa_verify_hash_complete() + * repeatedly on the same operation object after a + * successful call to this function until \c + * psa_verify_hash_complete() either returns 0 or + * an error. \c psa_verify_hash_complete() will + * return #PSA_OPERATION_INCOMPLETE if there is + * more work to do. Alternatively users can call + * \c psa_verify_hash_abort() at any point if they + * no longer want the result. + * + * \note If this function returns an error status, the + * operation enters an error state and must be + * aborted by calling \c psa_verify_hash_abort(). + * + * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \param key Identifier of the key to use for the operation. + * The key must allow the usage + * #PSA_KEY_USAGE_VERIFY_HASH. + * \param alg A signature algorithm (\c PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) + * is true), that is compatible with + * the type of \p key. + * \param[in] hash The hash whose signature is to be verified. + * \param hash_length Size of the \p hash buffer in bytes. + * \param[in] signature Buffer containing the signature to verify. + * \param signature_length Size of the \p signature buffer in bytes. + * + * \retval #PSA_SUCCESS + * The operation started successfully - please call \c + * psa_verify_hash_complete() with the same context to complete the + * operation. + * + * \retval #PSA_ERROR_BAD_STATE + * Another operation has already been started on this context, and is + * still in progress. + * + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_VERIFY_HASH flag, or it does + * not permit the requested algorithm. + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_hash_start( + psa_verify_hash_interruptible_operation_t *operation, + mbedtls_svc_key_id_t key, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length); + +/** + * \brief Continue and eventually complete the action of + * reading and verifying a hash or short message + * signed with a private key, in an interruptible + * manner. + * + * \see \c psa_verify_hash_start() + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function combined with \c + * psa_verify_hash_start() is equivalent to + * \c psa_verify_hash() but this function can + * return early and resume according to the limit + * set with \c psa_interruptible_set_max_ops() to + * reduce the maximum time spent in a function + * call. + * + * \note Users should call this function on the same + * operation object repeatedly until it either + * returns 0 or an error. This function will return + * #PSA_OPERATION_INCOMPLETE if there is more work + * to do. Alternatively users can call + * \c psa_verify_hash_abort() at any point if they + * no longer want the result. + * + * \note When this function returns successfully, the + * operation becomes inactive. If this function + * returns an error status, the operation enters an + * error state and must be aborted by calling + * \c psa_verify_hash_abort(). + * + * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t + * to use. This must be initialized first, and have + * had \c psa_verify_hash_start() called with it + * first. + * + * \retval #PSA_SUCCESS + * Operation completed successfully, and the passed signature is valid. + * + * \retval #PSA_OPERATION_INCOMPLETE + * Operation was interrupted due to the setting of \c + * psa_interruptible_set_max_ops(). There is still work to be done. + * Call this function again with the same operation object. + * + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculation was performed successfully, but the passed + * signature is not a valid signature. + * \retval #PSA_ERROR_BAD_STATE + * An operation was not previously started on this context via + * \c psa_verify_hash_start(). + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has either not been previously initialized by + * psa_crypto_init() or you did not previously call + * psa_verify_hash_start() on this object. It is + * implementation-dependent whether a failure to initialize results in + * this error code. + */ +psa_status_t psa_verify_hash_complete( + psa_verify_hash_interruptible_operation_t *operation); + +/** + * \brief Abort a verify hash operation. + * + * \warning This is a beta API, and thus subject to change at + * any point. It is not bound by the usual interface + * stability promises. + * + * \note This function is the only function that clears the + * number of ops completed as part of the operation. + * Please ensure you copy this value via + * \c psa_verify_hash_get_num_ops() if required + * before calling. + * + * \note Aborting an operation frees all associated + * resources except for the operation structure + * itself. Once aborted, the operation object can be + * reused for another operation by calling \c + * psa_verify_hash_start() again. + * + * \note You may call this function any time after the + * operation object has been initialized. + * In particular, calling \c psa_verify_hash_abort() + * after the operation has already been terminated by + * a call to \c psa_verify_hash_abort() or + * psa_verify_hash_complete() is safe. + * + * \param[in,out] operation Initialized verify hash operation. + * + * \retval #PSA_SUCCESS + * The operation was aborted successfully. + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_hash_abort( + psa_verify_hash_interruptible_operation_t *operation); diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 4de78021ef..84e233955b 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -253,6 +253,82 @@ static ssize_t find_key_derivation_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } +static psa_sign_hash_interruptible_operation_t sign_hash_interruptible_operations[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t sign_hash_interruptible_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t next_sign_hash_interruptible_operation_handle = 1; + +/* Get a free slot */ +static ssize_t allocate_sign_hash_interruptible_operation_slot(void) +{ + psasim_client_handle_t handle = next_sign_hash_interruptible_operation_handle++; + if (next_sign_hash_interruptible_operation_handle == 0) { /* wrapped around */ + FATAL("Sign_hash_interruptible operation handle wrapped"); + } + + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (sign_hash_interruptible_operation_handles[i] == 0) { + sign_hash_interruptible_operation_handles[i] = handle; + return i; + } + } + + ERROR("All slots are currently used. Unable to allocate a new one."); + + return -1; /* all in use */ +} + +/* Find the slot given the handle */ +static ssize_t find_sign_hash_interruptible_slot_by_handle(psasim_client_handle_t handle) +{ + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (sign_hash_interruptible_operation_handles[i] == handle) { + return i; + } + } + + ERROR("Unable to find slot by handle %u", handle); + + return -1; /* not found */ +} + +static psa_verify_hash_interruptible_operation_t verify_hash_interruptible_operations[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t verify_hash_interruptible_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t next_verify_hash_interruptible_operation_handle = 1; + +/* Get a free slot */ +static ssize_t allocate_verify_hash_interruptible_operation_slot(void) +{ + psasim_client_handle_t handle = next_verify_hash_interruptible_operation_handle++; + if (next_verify_hash_interruptible_operation_handle == 0) { /* wrapped around */ + FATAL("Verify_hash_interruptible operation handle wrapped"); + } + + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (verify_hash_interruptible_operation_handles[i] == 0) { + verify_hash_interruptible_operation_handles[i] = handle; + return i; + } + } + + ERROR("All slots are currently used. Unable to allocate a new one."); + + return -1; /* all in use */ +} + +/* Find the slot given the handle */ +static ssize_t find_verify_hash_interruptible_slot_by_handle(psasim_client_handle_t handle) +{ + for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) { + if (verify_hash_interruptible_operation_handles[i] == handle) { + return i; + } + } + + ERROR("Unable to find slot by handle %u", handle); + + return -1; /* not found */ +} + size_t psasim_serialise_begin_needs(void) { /* The serialisation buffer will @@ -467,6 +543,41 @@ int psasim_deserialise_uint16_t(uint8_t **pos, return 1; } +size_t psasim_serialise_uint32_t_needs(uint32_t value) +{ + return sizeof(value); +} + +int psasim_serialise_uint32_t(uint8_t **pos, + size_t *remaining, + uint32_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_uint32_t(uint8_t **pos, + size_t *remaining, + uint32_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + size_t psasim_serialise_uint64_t_needs(uint64_t value) { return sizeof(value); @@ -1255,6 +1366,192 @@ int psasim_server_deserialise_psa_key_derivation_operation_t(uint8_t **pos, return 1; } +size_t psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(psa_sign_hash_interruptible_operation_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_sign_hash_interruptible_operation_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_sign_hash_interruptible_operation_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_server_serialise_psa_sign_hash_interruptible_operation_t_needs(psa_sign_hash_interruptible_operation_t *operation) +{ + (void) operation; + + /* We will actually return a handle */ + return sizeof(psasim_operation_t); +} + +int psasim_server_serialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_sign_hash_interruptible_operation_t *operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(client_operation)) { + return 0; + } + + ssize_t slot = operation - sign_hash_interruptible_operations; + + client_operation.handle = sign_hash_interruptible_operation_handles[slot]; + + memcpy(*pos, &client_operation, sizeof(client_operation)); + *pos += sizeof(client_operation); + + return 1; +} + +int psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_sign_hash_interruptible_operation_t **operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(psasim_operation_t)) { + return 0; + } + + memcpy(&client_operation, *pos, sizeof(psasim_operation_t)); + *pos += sizeof(psasim_operation_t); + *remaining -= sizeof(psasim_operation_t); + + ssize_t slot; + if (client_operation.handle == 0) { /* We need a new handle */ + slot = allocate_sign_hash_interruptible_operation_slot(); + } else { + slot = find_sign_hash_interruptible_slot_by_handle(client_operation.handle); + } + + if (slot < 0) { + return 0; + } + + *operation = &sign_hash_interruptible_operations[slot]; + + return 1; +} + +size_t psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(psa_verify_hash_interruptible_operation_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_verify_hash_interruptible_operation_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_verify_hash_interruptible_operation_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + +size_t psasim_server_serialise_psa_verify_hash_interruptible_operation_t_needs(psa_verify_hash_interruptible_operation_t *operation) +{ + (void) operation; + + /* We will actually return a handle */ + return sizeof(psasim_operation_t); +} + +int psasim_server_serialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_verify_hash_interruptible_operation_t *operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(client_operation)) { + return 0; + } + + ssize_t slot = operation - verify_hash_interruptible_operations; + + client_operation.handle = verify_hash_interruptible_operation_handles[slot]; + + memcpy(*pos, &client_operation, sizeof(client_operation)); + *pos += sizeof(client_operation); + + return 1; +} + +int psasim_server_deserialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_verify_hash_interruptible_operation_t **operation) +{ + psasim_operation_t client_operation; + + if (*remaining < sizeof(psasim_operation_t)) { + return 0; + } + + memcpy(&client_operation, *pos, sizeof(psasim_operation_t)); + *pos += sizeof(psasim_operation_t); + *remaining -= sizeof(psasim_operation_t); + + ssize_t slot; + if (client_operation.handle == 0) { /* We need a new handle */ + slot = allocate_verify_hash_interruptible_operation_slot(); + } else { + slot = find_verify_hash_interruptible_slot_by_handle(client_operation.handle); + } + + if (slot < 0) { + return 0; + } + + *operation = &verify_hash_interruptible_operations[slot]; + + return 1; +} + size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value) { return sizeof(value); @@ -1302,4 +1599,8 @@ void psa_sim_serialize_reset(void) memset(cipher_operations, 0, sizeof(cipher_operations)); memset(key_derivation_operation_handles, 0, sizeof(key_derivation_operation_handles)); memset(key_derivation_operations, 0, sizeof(key_derivation_operations)); + memset(sign_hash_interruptible_operation_handles, 0, sizeof(sign_hash_interruptible_operation_handles)); + memset(sign_hash_interruptible_operations, 0, sizeof(sign_hash_interruptible_operations)); + memset(verify_hash_interruptible_operation_handles, 0, sizeof(verify_hash_interruptible_operation_handles)); + memset(verify_hash_interruptible_operations, 0, sizeof(verify_hash_interruptible_operations)); } diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 1028518dd6..4bd7fe954e 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -264,6 +264,48 @@ int psasim_deserialise_uint16_t(uint8_t **pos, size_t *remaining, uint16_t *value); +/** Return how much buffer space is needed by \c psasim_serialise_uint32_t() + * to serialise an `uint32_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_uint32_t() to serialise + * the given value. + */ +size_t psasim_serialise_uint32_t_needs(uint32_t value); + +/** Serialise an `uint32_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_uint32_t(uint8_t **pos, + size_t *remaining, + uint32_t value); + +/** Deserialise an `uint32_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to an `uint32_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_uint32_t(uint8_t **pos, + size_t *remaining, + uint32_t *value); + /** Return how much buffer space is needed by \c psasim_serialise_uint64_t() * to serialise an `uint64_t`. * @@ -1011,6 +1053,174 @@ int psasim_server_deserialise_psa_key_derivation_operation_t(uint8_t **pos, size_t *remaining, psa_key_derivation_operation_t **value); +/** Return how much buffer space is needed by \c psasim_serialise_psa_sign_hash_interruptible_operation_t() + * to serialise a `psa_sign_hash_interruptible_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_sign_hash_interruptible_operation_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(psa_sign_hash_interruptible_operation_t value); + +/** Serialise a `psa_sign_hash_interruptible_operation_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_sign_hash_interruptible_operation_t value); + +/** Deserialise a `psa_sign_hash_interruptible_operation_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_sign_hash_interruptible_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_sign_hash_interruptible_operation_t *value); + +/** Return how much buffer space is needed by \c psasim_server_serialise_psa_sign_hash_interruptible_operation_t() + * to serialise a `psa_sign_hash_interruptible_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_sign_hash_interruptible_operation_t() to serialise + * the given value. + */ +size_t psasim_server_serialise_psa_sign_hash_interruptible_operation_t_needs(psa_sign_hash_interruptible_operation_t *value); + +/** Serialise a `psa_sign_hash_interruptible_operation_t` into a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_serialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_sign_hash_interruptible_operation_t *value); + +/** Deserialise a `psa_sign_hash_interruptible_operation_t` from a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_sign_hash_interruptible_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_sign_hash_interruptible_operation_t **value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_verify_hash_interruptible_operation_t() + * to serialise a `psa_verify_hash_interruptible_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_verify_hash_interruptible_operation_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(psa_verify_hash_interruptible_operation_t value); + +/** Serialise a `psa_verify_hash_interruptible_operation_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_verify_hash_interruptible_operation_t value); + +/** Deserialise a `psa_verify_hash_interruptible_operation_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_verify_hash_interruptible_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_verify_hash_interruptible_operation_t *value); + +/** Return how much buffer space is needed by \c psasim_server_serialise_psa_verify_hash_interruptible_operation_t() + * to serialise a `psa_verify_hash_interruptible_operation_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_verify_hash_interruptible_operation_t() to serialise + * the given value. + */ +size_t psasim_server_serialise_psa_verify_hash_interruptible_operation_t_needs(psa_verify_hash_interruptible_operation_t *value); + +/** Serialise a `psa_verify_hash_interruptible_operation_t` into a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_serialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_verify_hash_interruptible_operation_t *value); + +/** Deserialise a `psa_verify_hash_interruptible_operation_t` from a buffer on the server side. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_verify_hash_interruptible_operation_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_server_deserialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, + size_t *remaining, + psa_verify_hash_interruptible_operation_t **value); + /** Return how much buffer space is needed by \c psasim_serialise_mbedtls_svc_key_id_t() * to serialise a `mbedtls_svc_key_id_t`. * diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 43ba661634..ed5dd9a25b 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -36,7 +36,7 @@ # are). # my @types = qw(unsigned-int int size_t - uint16_t uint64_t + uint16_t uint32_t uint64_t buffer psa_key_production_parameters_t psa_status_t psa_algorithm_t psa_key_derivation_step_t @@ -46,6 +46,8 @@ psa_mac_operation_t psa_cipher_operation_t psa_key_derivation_operation_t + psa_sign_hash_interruptible_operation_t + psa_verify_hash_interruptible_operation_t mbedtls_svc_key_id_t); grep(s/-/ /g, @types); From 5c66a73efff76635e8182fbdea1046fdce7aa7db Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 17:18:35 +0100 Subject: [PATCH 067/125] psasim: add support for psa_copy_key() Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 1 + psasim/src/psa_sim_crypto_client.c | 75 ++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 87 ++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 92 ++++++++++++++++++++++++++++++ 4 files changed, 255 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 68d9f031f1..44b2a99f84 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -35,6 +35,7 @@ enum { PSA_CIPHER_GENERATE_IV, PSA_CIPHER_SET_IV, PSA_CIPHER_UPDATE, + PSA_COPY_KEY, PSA_DESTROY_KEY, PSA_EXPORT_KEY, PSA_EXPORT_PUBLIC_KEY, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 36fdfdb761..9f3ef08e08 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -2056,6 +2056,81 @@ psa_status_t psa_cipher_update( } +psa_status_t psa_copy_key( + mbedtls_svc_key_id_t source_key, + const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *target_key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(source_key) + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*target_key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, source_key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *target_key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_COPY_KEY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_COPY_KEY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_mbedtls_svc_key_id_t(&rpos, &rremain, target_key); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key ) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index eb313760bf..29fc5213a6 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -2351,6 +2351,89 @@ int psa_cipher_update_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_copy_key_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; + mbedtls_svc_key_id_t source_key; + psa_key_attributes_t attributes; + mbedtls_svc_key_id_t target_key; + + 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_mbedtls_svc_key_id_t(&pos, &remaining, &source_key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &target_key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_copy_key( + source_key, + &attributes, + &target_key + ); + + // 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_mbedtls_svc_key_id_t_needs(target_key); + + 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_mbedtls_svc_key_id_t(&rpos, &rremain, target_key); + 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_destroy_key_wrapper( uint8_t *in_params, size_t in_params_len, @@ -6749,6 +6832,10 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_cipher_update_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_COPY_KEY: + ok = psa_copy_key_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_DESTROY_KEY: ok = psa_destroy_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 344ad2594e..9dafd0c834 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -5424,3 +5424,95 @@ sub put_crypto_init_first */ psa_status_t psa_verify_hash_abort( psa_verify_hash_interruptible_operation_t *operation); + +/** Make a copy of a key. + * + * Copy key material from one location to another. + * + * This function is primarily useful to copy a key from one location + * to another, since it populates a key using the material from + * another key which may have a different lifetime. + * + * This function may be used to share a key with a different party, + * subject to implementation-defined restrictions on key sharing. + * + * The policy on the source key must have the usage flag + * #PSA_KEY_USAGE_COPY set. + * This flag is sufficient to permit the copy if the key has the lifetime + * #PSA_KEY_LIFETIME_VOLATILE or #PSA_KEY_LIFETIME_PERSISTENT. + * Some secure elements do not provide a way to copy a key without + * making it extractable from the secure element. If a key is located + * in such a secure element, then the key must have both usage flags + * #PSA_KEY_USAGE_COPY and #PSA_KEY_USAGE_EXPORT in order to make + * a copy of the key outside the secure element. + * + * The resulting key may only be used in a way that conforms to + * both the policy of the original key and the policy specified in + * the \p attributes parameter: + * - The usage flags on the resulting key are the bitwise-and of the + * usage flags on the source policy and the usage flags in \p attributes. + * - If both allow the same algorithm or wildcard-based + * algorithm policy, the resulting key has the same algorithm policy. + * - If either of the policies allows an algorithm and the other policy + * allows a wildcard-based algorithm policy that includes this algorithm, + * the resulting key allows the same algorithm. + * - If the policies do not allow any algorithm in common, this function + * fails with the status #PSA_ERROR_INVALID_ARGUMENT. + * + * The effect of this function on implementation-defined attributes is + * implementation-defined. + * + * \param source_key The key to copy. It must allow the usage + * #PSA_KEY_USAGE_COPY. If a private or secret key is + * being copied outside of a secure element it must + * also allow #PSA_KEY_USAGE_EXPORT. + * \param[in] attributes The attributes for the new key. + * They are used as follows: + * - The key type and size may be 0. If either is + * nonzero, it must match the corresponding + * attribute of the source key. + * - The key location (the lifetime and, for + * persistent keys, the key identifier) is + * used directly. + * - The policy constraints (usage flags and + * algorithm policy) are combined from + * the source key and \p attributes so that + * both sets of restrictions apply, as + * described in the documentation of this function. + * \param[out] target_key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE + * \p source_key is invalid. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The lifetime or identifier in \p attributes are invalid, or + * the policy constraints on the source and specified in + * \p attributes are incompatible, or + * \p attributes specifies a key type or key size + * which does not match the attributes of the source key. + * \retval #PSA_ERROR_NOT_PERMITTED + * The source key does not have the #PSA_KEY_USAGE_COPY usage flag, or + * the source key is not exportable and its lifetime does not + * allow copying it to the target's lifetime. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, + const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *target_key); From 7f751a9520c975d42973f61d121f724a171d2f7a Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 17:23:39 +0100 Subject: [PATCH 068/125] psasim: add support for psa_reset_key_attributes() Signed-off-by: Tom Cosgrove --- psasim/src/psa_functions_codes.h | 1 + psasim/src/psa_sim_crypto_client.c | 54 ++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 66 ++++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 14 +++++++ 4 files changed, 135 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 44b2a99f84..bc1b84442a 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -75,6 +75,7 @@ enum { PSA_MAC_VERIFY_SETUP, PSA_PURGE_KEY, PSA_RAW_KEY_AGREEMENT, + PSA_RESET_KEY_ATTRIBUTES, PSA_SIGN_HASH, PSA_SIGN_HASH_ABORT, PSA_SIGN_HASH_COMPLETE, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 9f3ef08e08..091e354b19 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -4953,6 +4953,60 @@ psa_status_t psa_raw_key_agreement( } +void psa_reset_key_attributes( + psa_key_attributes_t *attributes + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + + size_t needed = psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes); + + ser_params = malloc(needed); + if (ser_params == NULL) { + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_RESET_KEY_ATTRIBUTES, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_RESET_KEY_ATTRIBUTES server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_attributes_t(&rpos, &rremain, attributes); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); +} + + psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key, psa_algorithm_t alg, diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 29fc5213a6..03e36c06e1 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -5661,6 +5661,68 @@ int psa_raw_key_agreement_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_reset_key_attributes_wrapper( + uint8_t *in_params, size_t in_params_len, + uint8_t **out_params, size_t *out_params_len) +{ + psa_key_attributes_t attributes; + + 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_key_attributes_t(&pos, &remaining, &attributes); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + psa_reset_key_attributes( + &attributes + ); + + // NOTE: Should really check there is no overflow as we go along. + size_t result_size = + psasim_serialise_begin_needs(); + psasim_serialise_psa_key_attributes_t_needs(attributes); + + 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_key_attributes_t(&rpos, &rremain, attributes); + 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_sign_hash_wrapper( uint8_t *in_params, size_t in_params_len, @@ -6992,6 +7054,10 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_raw_key_agreement_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_RESET_KEY_ATTRIBUTES: + ok = psa_reset_key_attributes_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_SIGN_HASH: ok = psa_sign_hash_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 9dafd0c834..5673b677a3 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -5516,3 +5516,17 @@ sub put_crypto_init_first psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *target_key); + +/** Reset a key attribute structure to a freshly initialized state. + * + * You must initialize the attribute structure as described in the + * documentation of the type #psa_key_attributes_t before calling this + * function. Once the structure has been initialized, you may call this + * function at any time. + * + * This function frees any auxiliary resources that the structure + * may contain. + * + * \param[in,out] attributes The attribute structure to reset. + */ +void psa_reset_key_attributes(psa_key_attributes_t *attributes); From c819e53b56818e05d2a9598008dd63faff998936 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Fri, 21 Jun 2024 20:28:17 +0100 Subject: [PATCH 069/125] psasim: have the generator script check for type = "void" rather than name = "(void)" Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_generate.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 5673b677a3..a0ee76a801 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -531,7 +531,7 @@ sub output_server_wrapper { EOF - print $fh <{return}->{type}; my $ret_name = $f->{return}->{name}; my $args = $f->{args}; - if ($ret_name eq "(void)") { + if ($ret_type eq "void") { print $fh "\n $name(\n"; } else { print $fh "\n $ret_name = $name(\n"; From 874e820ea262b6edafa2c47190f3d946e29273e7 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 13:13:17 +0200 Subject: [PATCH 070/125] psasim: merge all AUT programs into a single executable This makes both building and testing much faster. Signed-off-by: Valerio Setti --- psasim/Makefile | 19 ++++--- psasim/src/aut_main.c | 53 +++++++++++++++++++ .../{aut_psa_aead_demo.c => aut_psa_aead.c} | 12 ++--- psasim/src/aut_psa_hash.c | 40 ++------------ psasim/src/aut_psa_hash_compute.c | 42 ++------------- psasim/test/run_test.sh | 12 +++-- 6 files changed, 86 insertions(+), 92 deletions(-) create mode 100644 psasim/src/aut_main.c rename psasim/src/{aut_psa_aead_demo.c => aut_psa_aead.c} (98%) diff --git a/psasim/Makefile b/psasim/Makefile index a7e22e131e..4b0c46e47c 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -1,5 +1,3 @@ -MAIN ?= src/client.c - CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L ifeq ($(DEBUG),1) @@ -16,11 +14,15 @@ 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 \ - $(MAIN) \ +PSA_CLIENT_COMMON_SRC = src/psa_ff_client.c \ src/psa_sim_crypto_client.c \ src/psa_sim_serialise.c +PSA_CLIENT_BASE_SRC = $(PSA_CLIENT_COMMON_SRC) src/client.c + +PSA_CLIENT_FULL_SRC = $(PSA_CLIENT_COMMON_SRC) \ + $(wildcard src/aut_*.c) + PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ @@ -35,8 +37,11 @@ all: test/seedfile: dd if=/dev/urandom of=./test/seedfile bs=64 count=1 -test/psa_client: $(PSA_CLIENT_SRC) $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ +test/psa_client_base: $(PSA_CLIENT_BASE_SRC) $(GENERATED_H_FILES) + $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_BASE_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ + +test/psa_client_full: $(PSA_CLIENT_FULL_SRC) $(GENERATED_H_FILES) + $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_FULL_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ test/psa_partition: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) test/seedfile $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_SERVER_SRC) $(LIBPSASERVER) $(LDFLAGS) -o $@ @@ -56,7 +61,7 @@ libpsaclient libpsaserver: $(MAKE) -C $(MBEDTLS_ROOT_PATH) clean clean: - rm -f test/psa_client test/psa_partition + rm -f test/psa_client_base test/psa_client_full test/psa_partition rm -f $(PARTITION_SERVER_BOOTSTRAP) rm -rf libpsaclient libpsaserver rm -rf include/psa_manifest diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c new file mode 100644 index 0000000000..e1012a5f42 --- /dev/null +++ b/psasim/src/aut_main.c @@ -0,0 +1,53 @@ +/** + * This is the base AUT that exectues all other AUTs meant to test PSA APIs + * through PSASIM. + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* First include Mbed TLS headers to get the Mbed TLS configuration and + * platform definitions that we'll use in this program. Also include + * standard C headers for functions we'll use here. */ +#include "mbedtls/build_info.h" + +#include "psa/crypto.h" + +#include +#include +#include + +int psa_hash_compute_main(void); +int psa_hash_main(void); +int psa_aead_main(char *cipher_name); + +#define TEST_MODULE(main_func) \ + do { \ + char title[128] = { 0 }; \ + char separator[128] = { 0 }; \ + int title_len = snprintf(title, sizeof(title), "=== Test: %s ===", #main_func); \ + memset(separator, '=', title_len); \ + printf("%s\n%s\n%s\n", separator, title, separator); \ + ret = main_func; \ + if (ret != 0) { \ + goto exit; \ + } \ + } while (0) + +int main() +{ + int ret; + + TEST_MODULE(psa_hash_compute_main()); + TEST_MODULE(psa_hash_main()); + + TEST_MODULE(psa_aead_main("aes128-gcm")); + TEST_MODULE(psa_aead_main("aes256-gcm")); + TEST_MODULE(psa_aead_main("aes128-gcm_8")); + TEST_MODULE(psa_aead_main("chachapoly")); + +exit: + return (ret != 0) ? 1 : 0; +} diff --git a/psasim/src/aut_psa_aead_demo.c b/psasim/src/aut_psa_aead.c similarity index 98% rename from psasim/src/aut_psa_aead_demo.c rename to psasim/src/aut_psa_aead.c index 4a46c4039c..aa9dfb0950 100644 --- a/psasim/src/aut_psa_aead_demo.c +++ b/psasim/src/aut_psa_aead.c @@ -46,7 +46,7 @@ !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ !defined(MBEDTLS_CHACHAPOLY_C) || \ defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)) -int main(void) +int psa_aead_main(void) { printf("MBEDTLS_PSA_CRYPTO_CLIENT or " "MBEDTLS_PSA_CRYPTO_C and/or " @@ -257,21 +257,15 @@ static psa_status_t aead_demo(const char *info) /* * Main function */ -int main(int argc, char **argv) +int psa_aead_main(char *cipher_name) { psa_status_t status = PSA_SUCCESS; - /* Check usage */ - if (argc != 2) { - puts(usage); - return EXIT_FAILURE; - } - /* Initialize the PSA crypto library. */ PSA_CHECK(psa_crypto_init()); /* Run the demo */ - PSA_CHECK(aead_demo(argv[1])); + PSA_CHECK(aead_demo(cipher_name)); /* Deinitialize the PSA crypto library. */ mbedtls_psa_crypto_free(); diff --git a/psasim/src/aut_psa_hash.c b/psasim/src/aut_psa_hash.c index 6c2c07e062..0446e7a76a 100644 --- a/psasim/src/aut_psa_hash.c +++ b/psasim/src/aut_psa_hash.c @@ -1,13 +1,4 @@ /* - * Example computing a SHA-256 hash using the PSA Crypto API - * - * The example computes the SHA-256 hash of a test string using the - * one-shot API call psa_hash_compute() and the using multi-part - * operation, which requires psa_hash_setup(), psa_hash_update() and - * psa_hash_finish(). The multi-part operation is popular on embedded - * devices where a rolling hash needs to be computed. - * - * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ @@ -20,33 +11,13 @@ #include "mbedtls/build_info.h" #include "mbedtls/platform.h" -/* Information about hashing with the PSA API can be - * found here: - * https://arm-software.github.io/psa-api/crypto/1.1/api/ops/hashes.html - * - * The algorithm used by this demo is SHA 256. - * Please see include/psa/crypto_values.h to see the other - * algorithms that are supported by Mbed TLS. - * If you switch to a different algorithm you will need to update - * the hash data in the EXAMPLE_HASH_VALUE macro below. */ - -#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ - (!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256)) -int main(void) -{ - mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256" - "not defined, and not MBEDTLS_PSA_CRYPTO_CLIENT.\r\n"); - return EXIT_SUCCESS; -} -#else - #define HASH_ALG PSA_ALG_SHA_256 -const uint8_t sample_message[] = "Hello World!"; +static const uint8_t sample_message[] = "Hello World!"; /* sample_message is terminated with a null byte which is not part of * the message itself so we make sure to subtract it in order to get * the message length. */ -const size_t sample_message_length = sizeof(sample_message) - 1; +static const size_t sample_message_length = sizeof(sample_message) - 1; #define EXPECTED_HASH_VALUE { \ 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \ @@ -54,10 +25,10 @@ const size_t sample_message_length = sizeof(sample_message) - 1; 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \ } -const uint8_t expected_hash[] = EXPECTED_HASH_VALUE; -const size_t expected_hash_len = sizeof(expected_hash); +static const uint8_t expected_hash[] = EXPECTED_HASH_VALUE; +static const size_t expected_hash_len = sizeof(expected_hash); -int main(void) +int psa_hash_main(void) { psa_status_t status; uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)]; @@ -157,4 +128,3 @@ int main(void) psa_hash_abort(&cloned_hash_operation); return EXIT_FAILURE; } -#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */ diff --git a/psasim/src/aut_psa_hash_compute.c b/psasim/src/aut_psa_hash_compute.c index 70c3e5be4f..959e0c38ab 100644 --- a/psasim/src/aut_psa_hash_compute.c +++ b/psasim/src/aut_psa_hash_compute.c @@ -1,15 +1,4 @@ /* - * API(s) under test: psa_hash_compute() - * - * Taken from programs/psa/psa_hash.c, and calls to all hash APIs - * but psa_hash_compute() removed. - * - * Example computing a SHA-256 hash using the PSA Crypto API - * - * The example computes the SHA-256 hash of a test string using the - * one-shot API call psa_hash_compute(). - * - * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ @@ -22,33 +11,13 @@ #include "mbedtls/build_info.h" #include "mbedtls/platform.h" -/* Information about hashing with the PSA API can be - * found here: - * https://arm-software.github.io/psa-api/crypto/1.1/api/ops/hashes.html - * - * The algorithm used by this demo is SHA 256. - * Please see include/psa/crypto_values.h to see the other - * algorithms that are supported by Mbed TLS. - * If you switch to a different algorithm you will need to update - * the hash data in the EXAMPLE_HASH_VALUE macro below. */ - -#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ - (!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256)) -int main(void) -{ - mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256" - "not defined, and not MBEDTLS_PSA_CRYPTO_CLIENT.\r\n"); - return EXIT_SUCCESS; -} -#else - #define HASH_ALG PSA_ALG_SHA_256 -const uint8_t sample_message[] = "Hello World!"; +static const uint8_t sample_message[] = "Hello World!"; /* sample_message is terminated with a null byte which is not part of * the message itself so we make sure to subtract it in order to get * the message length. */ -const size_t sample_message_length = sizeof(sample_message) - 1; +static const size_t sample_message_length = sizeof(sample_message) - 1; #define EXPECTED_HASH_VALUE { \ 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \ @@ -56,10 +25,10 @@ const size_t sample_message_length = sizeof(sample_message) - 1; 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \ } -const uint8_t expected_hash[] = EXPECTED_HASH_VALUE; -const size_t expected_hash_len = sizeof(expected_hash); +static const uint8_t expected_hash[] = EXPECTED_HASH_VALUE; +static const size_t expected_hash_len = sizeof(expected_hash); -int main(void) +int psa_hash_compute_main(void) { psa_status_t status; uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)]; @@ -110,4 +79,3 @@ int main(void) cleanup: return EXIT_FAILURE; } -#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */ diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh index 45a317a24e..7c1011ead2 100755 --- a/psasim/test/run_test.sh +++ b/psasim/test/run_test.sh @@ -13,6 +13,9 @@ set -e cd "$(dirname "$0")" +CLIENT_BIN=$1 +shift + function clean_run() { rm -f psa_notify_* pkill psa_partition || true @@ -30,8 +33,9 @@ function wait_for_server_startup() { clean_run -./psa_partition -k & -SERV_PID=$! +./psa_partition & wait_for_server_startup -./psa_client "$@" -wait $SERV_PID +./$CLIENT_BIN "$@" + +# Kill server once client exited +pkill psa_partition From 2ea5fddb4c6cf7b910abd29f438f44a816fffa78 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 13:44:12 +0200 Subject: [PATCH 071/125] psasim: add AUT for psa_generate_random() Signed-off-by: Valerio Setti --- psasim/src/aut_main.c | 3 +++ psasim/src/aut_psa_random.c | 47 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 psasim/src/aut_psa_random.c diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c index e1012a5f42..c4940c339a 100644 --- a/psasim/src/aut_main.c +++ b/psasim/src/aut_main.c @@ -22,6 +22,7 @@ int psa_hash_compute_main(void); int psa_hash_main(void); int psa_aead_main(char *cipher_name); +int psa_random_main(void); #define TEST_MODULE(main_func) \ do { \ @@ -48,6 +49,8 @@ int main() TEST_MODULE(psa_aead_main("aes128-gcm_8")); TEST_MODULE(psa_aead_main("chachapoly")); + TEST_MODULE(psa_random_main()); + exit: return (ret != 0) ? 1 : 0; } diff --git a/psasim/src/aut_psa_random.c b/psasim/src/aut_psa_random.c new file mode 100644 index 0000000000..5880c4deb9 --- /dev/null +++ b/psasim/src/aut_psa_random.c @@ -0,0 +1,47 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "mbedtls/build_info.h" + +#include +#include +#include +#include + +#include "mbedtls/entropy.h" + +#define BUFFER_SIZE 100 + +int psa_random_main(void) +{ + psa_status_t status; + uint8_t output[BUFFER_SIZE] = { 0 }; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + status = psa_generate_random(output, BUFFER_SIZE); + if (status != PSA_SUCCESS) { + printf("psa_generate_random failed\n"); + return EXIT_FAILURE; + } + + printf("Random bytes generated:\n"); + + for (size_t j = 0; j < BUFFER_SIZE; j++) { + if (j % 8 == 0) { + printf("\n "); + } + printf("%02x ", output[j]); + } + + printf("\n"); + + mbedtls_psa_crypto_free(); + return 0; +} From fb89b18262cb038d4673f3fd6b1ff76ba22257cd Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 13:57:49 +0200 Subject: [PATCH 072/125] psasim: add AUT for MAC Signed-off-by: Valerio Setti --- psasim/src/aut_main.c | 3 + psasim/src/aut_psa_mac.c | 162 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 psasim/src/aut_psa_mac.c diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c index c4940c339a..7d1d2c00fc 100644 --- a/psasim/src/aut_main.c +++ b/psasim/src/aut_main.c @@ -23,6 +23,7 @@ int psa_hash_compute_main(void); int psa_hash_main(void); int psa_aead_main(char *cipher_name); int psa_random_main(void); +int psa_mac_main(void); #define TEST_MODULE(main_func) \ do { \ @@ -51,6 +52,8 @@ int main() TEST_MODULE(psa_random_main()); + TEST_MODULE(psa_mac_main()); + exit: return (ret != 0) ? 1 : 0; } diff --git a/psasim/src/aut_psa_mac.c b/psasim/src/aut_psa_mac.c new file mode 100644 index 0000000000..18b4b571a3 --- /dev/null +++ b/psasim/src/aut_psa_mac.c @@ -0,0 +1,162 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa/crypto.h" +#include +#include +#include + +#include "mbedtls/build_info.h" + +/* constant-time buffer comparison */ +static inline int safer_memcmp(const void *a, const void *b, size_t n) +{ + size_t i; + volatile const unsigned char *A = (volatile const unsigned char *) a; + volatile const unsigned char *B = (volatile const unsigned char *) b; + volatile unsigned char diff = 0; + + for (i = 0; i < n; i++) { + /* Read volatile data in order before computing diff. + * This avoids IAR compiler warning: + * 'the order of volatile accesses is undefined ..' */ + unsigned char x = A[i], y = B[i]; + diff |= x ^ y; + } + + return diff; +} + + +int psa_mac_main(void) +{ + uint8_t input[] = "Hello World!"; + psa_status_t status; + size_t mac_size_real = 0; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + uint8_t mac[PSA_MAC_MAX_SIZE]; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + const uint8_t key_bytes[16] = "kkkkkkkkkkkkkkkk"; + const uint8_t mbedtls_test_hmac_sha256[] = { + 0xae, 0x72, 0x34, 0x5a, 0x10, 0x36, 0xfb, 0x71, + 0x35, 0x3c, 0x7d, 0x6c, 0x81, 0x98, 0x52, 0x86, + 0x00, 0x4a, 0x43, 0x7c, 0x2d, 0xb3, 0x1a, 0xd8, + 0x67, 0xb1, 0xad, 0x11, 0x4d, 0x18, 0x49, 0x8b + }; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_MESSAGE | + PSA_KEY_USAGE_SIGN_HASH | + PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); + + status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id); + if (status != PSA_SUCCESS) { + printf("psa_import_key failed\n"); + return EXIT_FAILURE; + } + + /* Single-part MAC operation with psa_mac_compute() */ + status = psa_mac_compute(key_id, + PSA_ALG_HMAC(PSA_ALG_SHA_256), + input, + sizeof(input), + mac, + sizeof(mac), + &mac_size_real); + if (status != PSA_SUCCESS) { + printf("psa_mac_compute failed\n"); + return EXIT_FAILURE; + } + + printf("HMAC-SHA-256(%s) with psa_mac_compute():\n", input); + + for (size_t j = 0; j < mac_size_real; j++) { + if (j % 8 == 0) { + printf("\n "); + } + printf("%02x ", mac[j]); + } + + printf("\n"); + + if (safer_memcmp(mac, + mbedtls_test_hmac_sha256, + mac_size_real + ) != 0) { + printf("\nMAC verified incorrectly!\n"); + } else { + printf("\nMAC verified correctly!\n"); + } + + psa_destroy_key(key_id); + + status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id); + if (status != PSA_SUCCESS) { + printf("psa_import_key failed\n"); + return EXIT_FAILURE; + } + + /* Single-part MAC operation with psa_mac_verify() */ + status = psa_mac_verify(key_id, + PSA_ALG_HMAC(PSA_ALG_SHA_256), + input, + sizeof(input), + mbedtls_test_hmac_sha256, + sizeof(mbedtls_test_hmac_sha256)); + if (status != PSA_SUCCESS) { + printf("psa_mac_verify failed\n"); + return EXIT_FAILURE; + } else { + printf("psa_mac_verify passed successfully\n"); + } + + psa_destroy_key(key_id); + + status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id); + if (status != PSA_SUCCESS) { + printf("psa_import_key failed\n"); + return EXIT_FAILURE; + } + + /* Multi-part MAC operation */ + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + if (status != PSA_SUCCESS) { + printf("psa_mac_sign_setup failed\n"); + return EXIT_FAILURE; + } + + status = psa_mac_update(&operation, input, sizeof(input)); + if (status != PSA_SUCCESS) { + printf("psa_mac_update failed\n"); + return EXIT_FAILURE; + } + + status = psa_mac_sign_finish(&operation, mac, sizeof(mac), &mac_size_real); + if (status != PSA_SUCCESS) { + printf("psa_mac_sign_finish failed\n"); + return EXIT_FAILURE; + } + + if (safer_memcmp(mac, + mbedtls_test_hmac_sha256, + mac_size_real + ) != 0) { + printf("MAC, calculated with multi-part MAC operation, verified incorrectly!\n"); + } else { + printf("MAC, calculated with multi-part MAC operation, verified correctly!\n"); + } + + psa_destroy_key(key_id); + mbedtls_psa_crypto_free(); + return EXIT_SUCCESS; +} From 6aff2a2e228e6030041fade7bb755ec3da80d769 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 14:46:08 +0200 Subject: [PATCH 073/125] psasim: add AUT for key generation and raw key agreement Signed-off-by: Valerio Setti --- psasim/src/aut_main.c | 2 + psasim/src/aut_psa_key_agreement.c | 146 +++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 psasim/src/aut_psa_key_agreement.c diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c index 7d1d2c00fc..9604964082 100644 --- a/psasim/src/aut_main.c +++ b/psasim/src/aut_main.c @@ -24,6 +24,7 @@ int psa_hash_main(void); int psa_aead_main(char *cipher_name); int psa_random_main(void); int psa_mac_main(void); +int psa_key_agreement_main(void); #define TEST_MODULE(main_func) \ do { \ @@ -53,6 +54,7 @@ int main() TEST_MODULE(psa_random_main()); TEST_MODULE(psa_mac_main()); + TEST_MODULE(psa_key_agreement_main()); exit: return (ret != 0) ? 1 : 0; diff --git a/psasim/src/aut_psa_key_agreement.c b/psasim/src/aut_psa_key_agreement.c new file mode 100644 index 0000000000..4a0aab1477 --- /dev/null +++ b/psasim/src/aut_psa_key_agreement.c @@ -0,0 +1,146 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + + +#include "psa/crypto.h" +#include +#include +#include +#include "mbedtls/build_info.h" +#include "mbedtls/debug.h" +#include "mbedtls/platform.h" + +#define BUFFER_SIZE 500 + +#define SERVER_PK_VALUE { \ + 0x04, 0xde, 0xa5, 0xe4, 0x5d, 0x0e, 0xa3, 0x7f, 0xc5, \ + 0x66, 0x23, 0x2a, 0x50, 0x8f, 0x4a, 0xd2, 0x0e, 0xa1, \ + 0x3d, 0x47, 0xe4, 0xbf, 0x5f, 0xa4, 0xd5, 0x4a, 0x57, \ + 0xa0, 0xba, 0x01, 0x20, 0x42, 0x08, 0x70, 0x97, 0x49, \ + 0x6e, 0xfc, 0x58, 0x3f, 0xed, 0x8b, 0x24, 0xa5, 0xb9, \ + 0xbe, 0x9a, 0x51, 0xde, 0x06, 0x3f, 0x5a, 0x00, 0xa8, \ + 0xb6, 0x98, 0xa1, 0x6f, 0xd7, 0xf2, 0x9b, 0x54, 0x85, \ + 0xf3, 0x20 \ +} + +#define KEY_BITS 256 + +int psa_key_agreement_main(void) +{ + psa_status_t status; + psa_key_attributes_t client_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t server_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t client_key_id = 0; + psa_key_id_t server_key_id = 0; + uint8_t client_pk[BUFFER_SIZE] = { 0 }; + size_t client_pk_len; + size_t key_bits; + psa_key_type_t key_type; + + const uint8_t server_pk[] = SERVER_PK_VALUE; + uint8_t derived_key[BUFFER_SIZE] = { 0 }; + size_t derived_key_len; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + psa_set_key_usage_flags(&client_attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&client_attributes, PSA_ALG_ECDH); + psa_set_key_type(&client_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&client_attributes, KEY_BITS); + + /* Generate ephemeral key pair */ + status = psa_generate_key(&client_attributes, &client_key_id); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_generate_key failed\n"); + return EXIT_FAILURE; + } + status = psa_export_public_key(client_key_id, + client_pk, sizeof(client_pk), + &client_pk_len); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_export_public_key failed\n"); + return EXIT_FAILURE; + } + + mbedtls_printf("Client Public Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", client_pk_len); + + for (size_t j = 0; j < client_pk_len; j++) { + if (j % 8 == 0) { + mbedtls_printf("\n "); + } + mbedtls_printf("%02x ", client_pk[j]); + } + mbedtls_printf("\n\n"); + + psa_set_key_usage_flags(&server_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&server_attributes, PSA_ALG_ECDSA_ANY); + psa_set_key_type(&server_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + + /* Import server public key */ + status = psa_import_key(&server_attributes, server_pk, sizeof(server_pk), &server_key_id); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_import_key failed\n"); + return EXIT_FAILURE; + } + + status = psa_get_key_attributes(server_key_id, &check_attributes); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_get_key_attributes failed\n"); + return EXIT_FAILURE; + } + + key_bits = psa_get_key_bits(&check_attributes); + if (key_bits != 256) { + mbedtls_printf("Incompatible key size!\n"); + return EXIT_FAILURE; + } + + key_type = psa_get_key_type(&check_attributes); + if (key_type != PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)) { + mbedtls_printf("Unsupported key type!\n"); + return EXIT_FAILURE; + } + + mbedtls_printf("Server Public Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", sizeof(server_pk)); + + for (size_t j = 0; j < sizeof(server_pk); j++) { + if (j % 8 == 0) { + mbedtls_printf("\n "); + } + mbedtls_printf("%02x ", server_pk[j]); + } + mbedtls_printf("\n\n"); + + /* Generate ECDHE derived key */ + status = psa_raw_key_agreement(PSA_ALG_ECDH, // algorithm + client_key_id, // client secret key + server_pk, sizeof(server_pk), // server public key + derived_key, sizeof(derived_key), // buffer to store derived key + &derived_key_len); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_raw_key_agreement failed\n"); + return EXIT_FAILURE; + } + + mbedtls_printf("Derived Key (%" MBEDTLS_PRINTF_SIZET " bytes):\n", derived_key_len); + + for (size_t j = 0; j < derived_key_len; j++) { + if (j % 8 == 0) { + mbedtls_printf("\n "); + } + mbedtls_printf("%02x ", derived_key[j]); + } + mbedtls_printf("\n"); + + psa_destroy_key(server_key_id); + psa_destroy_key(client_key_id); + mbedtls_psa_crypto_free(); + return EXIT_SUCCESS; +} From 7f27ef7609026f6a0f9e7cf41a4579b1e31bbfa3 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 14:50:54 +0200 Subject: [PATCH 074/125] psasim: add AUT for PSA sign and verify Signed-off-by: Valerio Setti --- psasim/src/aut_main.c | 2 + psasim/src/aut_psa_sign_verify.c | 93 ++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 psasim/src/aut_psa_sign_verify.c diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c index 9604964082..3eee631619 100644 --- a/psasim/src/aut_main.c +++ b/psasim/src/aut_main.c @@ -25,6 +25,7 @@ int psa_aead_main(char *cipher_name); int psa_random_main(void); int psa_mac_main(void); int psa_key_agreement_main(void); +int psa_sign_verify_main(void); #define TEST_MODULE(main_func) \ do { \ @@ -55,6 +56,7 @@ int main() TEST_MODULE(psa_mac_main()); TEST_MODULE(psa_key_agreement_main()); + TEST_MODULE(psa_sign_verify_main()); exit: return (ret != 0) ? 1 : 0; diff --git a/psasim/src/aut_psa_sign_verify.c b/psasim/src/aut_psa_sign_verify.c new file mode 100644 index 0000000000..98df9e5162 --- /dev/null +++ b/psasim/src/aut_psa_sign_verify.c @@ -0,0 +1,93 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + + +#include "psa/crypto.h" +#include +#include +#include + +#include "mbedtls/build_info.h" +#include "mbedtls/platform.h" + +#define KEY_BYTES_VALUE { \ + 0x49, 0xc9, 0xa8, 0xc1, 0x8c, 0x4b, 0x88, 0x56, 0x38, 0xc4, 0x31, 0xcf, \ + 0x1d, 0xf1, 0xc9, 0x94, 0x13, 0x16, 0x09, 0xb5, 0x80, 0xd4, 0xfd, 0x43, \ + 0xa0, 0xca, 0xb1, 0x7d, 0xb2, 0xf1, 0x3e, 0xee \ +} + +#define PLAINTEXT_VALUE "Hello World!" + +/* SHA-256(plaintext) */ +#define HASH_VALUE { \ + 0x5a, 0x09, 0xe8, 0xfa, 0x9c, 0x77, 0x80, 0x7b, 0x24, 0xe9, 0x9c, 0x9c, \ + 0xf9, 0x99, 0xde, 0xbf, 0xad, 0x84, 0x41, 0xe2, 0x69, 0xeb, 0x96, 0x0e, \ + 0x20, 0x1f, 0x61, 0xfc, 0x3d, 0xe2, 0x0d, 0x5a \ +} + +int psa_sign_verify_main(void) +{ + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + uint8_t signature[PSA_SIGNATURE_MAX_SIZE] = { 0 }; + size_t signature_length; + const uint8_t key_bytes[] = KEY_BYTES_VALUE; + const uint8_t plaintext[] = PLAINTEXT_VALUE; + const uint8_t hash[] = HASH_VALUE; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + psa_set_key_usage_flags(&attributes, + PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + + status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_import_key failed\n"); + return EXIT_FAILURE; + } + + status = psa_sign_hash(key_id, // key handle + PSA_ALG_ECDSA(PSA_ALG_SHA_256), // signature algorithm + hash, sizeof(hash), // hash of the message + signature, sizeof(signature), // signature (as output) + &signature_length); // length of signature output + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_sign_hash failed\n"); + return EXIT_FAILURE; + } + + mbedtls_printf("ECDSA-SHA256 signature of SHA-256('%s'):\n", plaintext); + + for (size_t j = 0; j < signature_length; j++) { + if (j % 8 == 0) { + mbedtls_printf("\n "); + } + mbedtls_printf("%02x ", signature[j]); + } + + mbedtls_printf("\n"); + + status = psa_verify_hash(key_id, // key handle + PSA_ALG_ECDSA(PSA_ALG_SHA_256), // signature algorithm + hash, sizeof(hash), // hash of message + signature, signature_length); // signature + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_verify_hash failed\n"); + return EXIT_FAILURE; + } else { + mbedtls_printf("\nSignature verification successful!\n"); + } + + psa_destroy_key(key_id); + mbedtls_psa_crypto_free(); + return EXIT_SUCCESS; +} From a334b507a8190556d13ac29d25fadab82cecb1ec Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 14:59:34 +0200 Subject: [PATCH 075/125] psasim: add AUT for symmetric encryption/decryption Signed-off-by: Valerio Setti --- psasim/src/aut_main.c | 12 +- ...{aut_psa_aead.c => aut_psa_aead_encrypt.c} | 52 +-------- psasim/src/aut_psa_aead_encrypt_decrypt.c | 109 ++++++++++++++++++ 3 files changed, 117 insertions(+), 56 deletions(-) rename psasim/src/{aut_psa_aead.c => aut_psa_aead_encrypt.c} (77%) create mode 100644 psasim/src/aut_psa_aead_encrypt_decrypt.c diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c index 3eee631619..b0f96bee8b 100644 --- a/psasim/src/aut_main.c +++ b/psasim/src/aut_main.c @@ -21,7 +21,8 @@ int psa_hash_compute_main(void); int psa_hash_main(void); -int psa_aead_main(char *cipher_name); +int psa_aead_encrypt_main(char *cipher_name); +int psa_aead_encrypt_decrypt_main(void); int psa_random_main(void); int psa_mac_main(void); int psa_key_agreement_main(void); @@ -47,16 +48,17 @@ int main() TEST_MODULE(psa_hash_compute_main()); TEST_MODULE(psa_hash_main()); - TEST_MODULE(psa_aead_main("aes128-gcm")); - TEST_MODULE(psa_aead_main("aes256-gcm")); - TEST_MODULE(psa_aead_main("aes128-gcm_8")); - TEST_MODULE(psa_aead_main("chachapoly")); + TEST_MODULE(psa_aead_encrypt_main("aes128-gcm")); + TEST_MODULE(psa_aead_encrypt_main("aes256-gcm")); + TEST_MODULE(psa_aead_encrypt_main("aes128-gcm_8")); + TEST_MODULE(psa_aead_encrypt_main("chachapoly")); TEST_MODULE(psa_random_main()); TEST_MODULE(psa_mac_main()); TEST_MODULE(psa_key_agreement_main()); TEST_MODULE(psa_sign_verify_main()); + TEST_MODULE(psa_aead_encrypt_decrypt_main()); exit: return (ret != 0) ? 1 : 0; diff --git a/psasim/src/aut_psa_aead.c b/psasim/src/aut_psa_aead_encrypt.c similarity index 77% rename from psasim/src/aut_psa_aead.c rename to psasim/src/aut_psa_aead_encrypt.c index aa9dfb0950..64463f57fc 100644 --- a/psasim/src/aut_psa_aead.c +++ b/psasim/src/aut_psa_aead_encrypt.c @@ -1,37 +1,8 @@ -/** - * PSA API multi-part AEAD demonstration. - * - * This program AEAD-encrypts a message, using the algorithm and key size - * specified on the command line, using the multi-part API. - * - * It comes with a companion program cipher/cipher_aead_demo.c, which does the - * same operations with the legacy Cipher API. The goal is that comparing the - * two programs will help people migrating to the PSA Crypto API. - * - * When used with multi-part AEAD operations, the `mbedtls_cipher_context` - * serves a triple purpose (1) hold the key, (2) store the algorithm when no - * operation is active, and (3) save progress information for the current - * operation. With PSA those roles are held by disinct objects: (1) a - * psa_key_id_t to hold the key, a (2) psa_algorithm_t to represent the - * algorithm, and (3) a psa_operation_t for multi-part progress. - * - * On the other hand, with PSA, the algorithms encodes the desired tag length; - * with Cipher the desired tag length needs to be tracked separately. - * - * This program and its companion cipher/cipher_aead_demo.c illustrate this by - * doing the same sequence of multi-part AEAD computation with both APIs; - * looking at the two side by side should make the differences and - * similarities clear. - */ - /* * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ -/* First include Mbed TLS headers to get the Mbed TLS configuration and - * platform definitions that we'll use in this program. Also include - * standard C headers for functions we'll use here. */ #include "mbedtls/build_info.h" #include "psa/crypto.h" @@ -40,25 +11,6 @@ #include #include -/* If the build options we need are not enabled, compile a placeholder. */ -#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \ - (!defined(MBEDTLS_PSA_CRYPTO_C) || \ - !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_GCM_C) || \ - !defined(MBEDTLS_CHACHAPOLY_C) || \ - defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)) -int psa_aead_main(void) -{ - printf("MBEDTLS_PSA_CRYPTO_CLIENT or " - "MBEDTLS_PSA_CRYPTO_C and/or " - "MBEDTLS_AES_C and/or MBEDTLS_GCM_C and/or " - "MBEDTLS_CHACHAPOLY_C not defined, and/or " - "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined\r\n"); - return 0; -} -#else - -/* The real program starts here. */ - const char usage[] = "Usage: aead_demo [aes128-gcm|aes256-gcm|aes128-gcm_8|chachapoly]"; @@ -257,7 +209,7 @@ static psa_status_t aead_demo(const char *info) /* * Main function */ -int psa_aead_main(char *cipher_name) +int psa_aead_encrypt_main(char *cipher_name) { psa_status_t status = PSA_SUCCESS; @@ -273,5 +225,3 @@ int psa_aead_main(char *cipher_name) exit: return status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE; } - -#endif diff --git a/psasim/src/aut_psa_aead_encrypt_decrypt.c b/psasim/src/aut_psa_aead_encrypt_decrypt.c new file mode 100644 index 0000000000..ca090ccc66 --- /dev/null +++ b/psasim/src/aut_psa_aead_encrypt_decrypt.c @@ -0,0 +1,109 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa/crypto.h" +#include +#include +#include + +#define BUFFER_SIZE 500 + +static void print_bytestr(const uint8_t *bytes, size_t len) +{ + for (unsigned int idx = 0; idx < len; idx++) { + printf("%02X", bytes[idx]); + } +} + +int psa_aead_encrypt_decrypt_main(void) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + uint8_t encrypt[BUFFER_SIZE] = { 0 }; + uint8_t decrypt[BUFFER_SIZE] = { 0 }; + const uint8_t plaintext[] = "Hello World!"; + const uint8_t key_bytes[32] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + uint8_t nonce[PSA_AEAD_NONCE_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CCM)]; + size_t nonce_length = sizeof(nonce); + size_t ciphertext_length; + size_t plaintext_length; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + psa_set_key_usage_flags(&attributes, + PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CCM); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 256); + + status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id); + if (status != PSA_SUCCESS) { + printf("psa_import_key failed\n"); + return EXIT_FAILURE; + } + + status = psa_generate_random(nonce, nonce_length); + if (status != PSA_SUCCESS) { + printf("psa_generate_random failed\n"); + return EXIT_FAILURE; + } + + status = psa_aead_encrypt(key_id, // key + PSA_ALG_CCM, // algorithm + nonce, nonce_length, // nonce + NULL, 0, // additional data + plaintext, sizeof(plaintext), // plaintext + encrypt, sizeof(encrypt), // ciphertext + &ciphertext_length); // length of output + if (status != PSA_SUCCESS) { + printf("psa_aead_encrypt failed\n"); + return EXIT_FAILURE; + } + + printf("AES-CCM encryption:\n"); + printf("- Plaintext: '%s':\n", plaintext); + printf("- Key: "); + print_bytestr(key_bytes, sizeof(key_bytes)); + printf("\n- Nonce: "); + print_bytestr(nonce, nonce_length); + printf("\n- No additional data\n"); + printf("- Ciphertext:\n"); + + for (size_t j = 0; j < ciphertext_length; j++) { + if (j % 8 == 0) { + printf("\n "); + } + printf("%02x ", encrypt[j]); + } + + printf("\n"); + + status = psa_aead_decrypt(key_id, // key + PSA_ALG_CCM, // algorithm + nonce, nonce_length, // nonce + NULL, 0, // additional data + encrypt, ciphertext_length, // ciphertext + decrypt, sizeof(decrypt), // plaintext + &plaintext_length); // length of output + if (status != PSA_SUCCESS) { + printf("psa_aead_decrypt failed\n"); + return EXIT_FAILURE; + } + + if (memcmp(plaintext, decrypt, sizeof(plaintext)) != 0) { + printf("\nEncryption/Decryption failed!\n"); + } else { + printf("\nEncryption/Decryption successful!\n"); + } + + psa_destroy_key(key_id); + mbedtls_psa_crypto_free(); + return 0; +} From d521ec5da1d009bf881bfca0dfef8253cbffa63a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 15:09:33 +0200 Subject: [PATCH 076/125] psasim: add AUT for key derivation Signed-off-by: Valerio Setti --- psasim/src/aut_main.c | 2 + psasim/src/aut_psa_hkdf.c | 121 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 psasim/src/aut_psa_hkdf.c diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c index b0f96bee8b..f0cd1a09b3 100644 --- a/psasim/src/aut_main.c +++ b/psasim/src/aut_main.c @@ -27,6 +27,7 @@ int psa_random_main(void); int psa_mac_main(void); int psa_key_agreement_main(void); int psa_sign_verify_main(void); +int psa_hkdf_main(void); #define TEST_MODULE(main_func) \ do { \ @@ -59,6 +60,7 @@ int main() TEST_MODULE(psa_key_agreement_main()); TEST_MODULE(psa_sign_verify_main()); TEST_MODULE(psa_aead_encrypt_decrypt_main()); + TEST_MODULE(psa_hkdf_main()); exit: return (ret != 0) ? 1 : 0; diff --git a/psasim/src/aut_psa_hkdf.c b/psasim/src/aut_psa_hkdf.c new file mode 100644 index 0000000000..891fdb3f92 --- /dev/null +++ b/psasim/src/aut_psa_hkdf.c @@ -0,0 +1,121 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa/crypto.h" +#include +#include +#include +#include "mbedtls/build_info.h" + +int psa_hkdf_main(void) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; + + /* Example test vector from RFC 5869 */ + + /* Input keying material (IKM) */ + unsigned char ikm[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; + + unsigned char salt[] = + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; + + /* Context and application specific information, which can be of zero length */ + unsigned char info[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; + + /* Expected OKM based on the RFC 5869-provided test vector */ + unsigned char expected_okm[] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, + 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, + 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, + 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, + 0x58, 0x65 }; + + /* The output size of the HKDF function depends on the hash function used. + * In our case we use SHA-256, which produces a 32 byte fingerprint. + * Therefore, we allocate a buffer of 32 bytes to hold the output keying + * material (OKM). + */ + unsigned char output[32]; + + psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256); + + printf("PSA Crypto API: HKDF SHA-256 example\n\n"); + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&attributes, PSA_ALG_HKDF(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE); + + status = psa_import_key(&attributes, ikm, sizeof(ikm), &key_id); + if (status != PSA_SUCCESS) { + printf("psa_import_key failed\n"); + return EXIT_FAILURE; + } + + status = psa_key_derivation_setup(&operation, alg); + if (status != PSA_SUCCESS) { + printf("psa_key_derivation_setup failed"); + return EXIT_FAILURE; + } + + status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_SALT, + salt, sizeof(salt)); + if (status != PSA_SUCCESS) { + printf("psa_key_derivation_input_bytes (salt) failed"); + return EXIT_FAILURE; + } + + status = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_SECRET, + key_id); + if (status != PSA_SUCCESS) { + printf("psa_key_derivation_input_key failed"); + return EXIT_FAILURE; + } + + status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_INFO, + info, sizeof(info)); + if (status != PSA_SUCCESS) { + printf("psa_key_derivation_input_bytes (info) failed"); + return EXIT_FAILURE; + } + + status = psa_key_derivation_output_bytes(&operation, output, sizeof(output)); + if (status != PSA_SUCCESS) { + printf("psa_key_derivation_output_bytes failed"); + return EXIT_FAILURE; + } + + status = psa_key_derivation_abort(&operation); + if (status != PSA_SUCCESS) { + printf("psa_key_derivation_abort failed"); + return EXIT_FAILURE; + } + + printf("OKM: \n"); + + for (size_t j = 0; j < sizeof(output); j++) { + if (output[j] != expected_okm[j]) { + printf("\n --- Unexpected outcome!\n"); + return EXIT_FAILURE; + } + + if (j % 8 == 0) { + printf("\n "); + } + printf("%02x ", output[j]); + } + + printf("\n"); + mbedtls_psa_crypto_free(); + return EXIT_SUCCESS; +} From 5d507461fd71254892ac99c3941f43bbc45e11d1 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 16:37:27 +0200 Subject: [PATCH 077/125] psasim: add AUT for cipher encryption/decryption Signed-off-by: Valerio Setti --- psasim/src/aut_main.c | 4 +- psasim/src/aut_psa_cipher_encrypt_decrypt.c | 81 +++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 psasim/src/aut_psa_cipher_encrypt_decrypt.c diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c index f0cd1a09b3..2c4a8fb90d 100644 --- a/psasim/src/aut_main.c +++ b/psasim/src/aut_main.c @@ -23,6 +23,7 @@ int psa_hash_compute_main(void); int psa_hash_main(void); int psa_aead_encrypt_main(char *cipher_name); int psa_aead_encrypt_decrypt_main(void); +int psa_cipher_encrypt_decrypt_main(void); int psa_random_main(void); int psa_mac_main(void); int psa_key_agreement_main(void); @@ -53,13 +54,14 @@ int main() TEST_MODULE(psa_aead_encrypt_main("aes256-gcm")); TEST_MODULE(psa_aead_encrypt_main("aes128-gcm_8")); TEST_MODULE(psa_aead_encrypt_main("chachapoly")); + TEST_MODULE(psa_aead_encrypt_decrypt_main()); + TEST_MODULE(psa_cipher_encrypt_decrypt_main()); TEST_MODULE(psa_random_main()); TEST_MODULE(psa_mac_main()); TEST_MODULE(psa_key_agreement_main()); TEST_MODULE(psa_sign_verify_main()); - TEST_MODULE(psa_aead_encrypt_decrypt_main()); TEST_MODULE(psa_hkdf_main()); exit: diff --git a/psasim/src/aut_psa_cipher_encrypt_decrypt.c b/psasim/src/aut_psa_cipher_encrypt_decrypt.c new file mode 100644 index 0000000000..a923feb618 --- /dev/null +++ b/psasim/src/aut_psa_cipher_encrypt_decrypt.c @@ -0,0 +1,81 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa/crypto.h" +#include +#include +#include + +#define BUFFER_SIZE 4096 + +static void print_bytestr(const uint8_t *bytes, size_t len) +{ + for (unsigned int idx = 0; idx < len; idx++) { + printf("%02X", bytes[idx]); + } +} + +int psa_cipher_encrypt_decrypt_main(void) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + uint8_t original[BUFFER_SIZE] = { 0 }; + uint8_t encrypt[BUFFER_SIZE] = { 0 }; + uint8_t decrypt[BUFFER_SIZE] = { 0 }; + const uint8_t key_bytes[32] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + size_t encrypted_length; + size_t decrypted_length; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + status = psa_generate_random(original, sizeof(original)); + if (status != PSA_SUCCESS) { + printf("psa_generate_random() failed\n"); + return EXIT_FAILURE; + } + + psa_set_key_usage_flags(&attributes, + PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 256); + + status = psa_import_key(&attributes, key_bytes, sizeof(key_bytes), &key_id); + if (status != PSA_SUCCESS) { + printf("psa_import_key failed\n"); + return EXIT_FAILURE; + } + + status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, + original, sizeof(original), + encrypt, sizeof(encrypt), &encrypted_length); + if (status != PSA_SUCCESS) { + printf("psa_cipher_encrypt failed\n"); + return EXIT_FAILURE; + } + + status = psa_cipher_decrypt(key_id, PSA_ALG_ECB_NO_PADDING, + encrypt, encrypted_length, + decrypt, sizeof(decrypt), &decrypted_length); + if (status != PSA_SUCCESS) { + printf("psa_cipher_decrypt failed\n"); + return EXIT_FAILURE; + } + + if (memcmp(original, decrypt, sizeof(original)) != 0) { + printf("\nEncryption/Decryption failed!\n"); + } else { + printf("\nEncryption/Decryption successful!\n"); + } + + psa_destroy_key(key_id); + mbedtls_psa_crypto_free(); + return 0; +} From 0bd5bacc9ceea6bc14770a5bef1a3d89c830a683 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 24 Jun 2024 17:38:10 +0200 Subject: [PATCH 078/125] psasim: add AUT for asymmetric encryption/decryption Signed-off-by: Valerio Setti --- psasim/src/aut_main.c | 2 + .../src/aut_psa_asymmetric_encrypt_decrypt.c | 81 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 psasim/src/aut_psa_asymmetric_encrypt_decrypt.c diff --git a/psasim/src/aut_main.c b/psasim/src/aut_main.c index 2c4a8fb90d..ed198790c6 100644 --- a/psasim/src/aut_main.c +++ b/psasim/src/aut_main.c @@ -24,6 +24,7 @@ int psa_hash_main(void); int psa_aead_encrypt_main(char *cipher_name); int psa_aead_encrypt_decrypt_main(void); int psa_cipher_encrypt_decrypt_main(void); +int psa_asymmetric_encrypt_decrypt_main(void); int psa_random_main(void); int psa_mac_main(void); int psa_key_agreement_main(void); @@ -56,6 +57,7 @@ int main() TEST_MODULE(psa_aead_encrypt_main("chachapoly")); TEST_MODULE(psa_aead_encrypt_decrypt_main()); TEST_MODULE(psa_cipher_encrypt_decrypt_main()); + TEST_MODULE(psa_asymmetric_encrypt_decrypt_main()); TEST_MODULE(psa_random_main()); diff --git a/psasim/src/aut_psa_asymmetric_encrypt_decrypt.c b/psasim/src/aut_psa_asymmetric_encrypt_decrypt.c new file mode 100644 index 0000000000..02d8cf486d --- /dev/null +++ b/psasim/src/aut_psa_asymmetric_encrypt_decrypt.c @@ -0,0 +1,81 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "psa/crypto.h" +#include +#include +#include + +#define KEY_BITS 4096 +#define BUFFER_SIZE PSA_BITS_TO_BYTES(KEY_BITS) + +static void print_bytestr(const uint8_t *bytes, size_t len) +{ + for (unsigned int idx = 0; idx < len; idx++) { + printf("%02X", bytes[idx]); + } +} + +int psa_asymmetric_encrypt_decrypt_main(void) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + uint8_t original[BUFFER_SIZE/2] = { 0 }; + uint8_t encrypt[BUFFER_SIZE] = { 0 }; + uint8_t decrypt[BUFFER_SIZE] = { 0 }; + size_t encrypted_length; + size_t decrypted_length; + + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + printf("psa_crypto_init failed\n"); + return EXIT_FAILURE; + } + + status = psa_generate_random(original, sizeof(original)); + if (status != PSA_SUCCESS) { + printf("psa_generate_random() failed\n"); + return EXIT_FAILURE; + } + + psa_set_key_usage_flags(&attributes, + PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT); + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&attributes, KEY_BITS); + + status = psa_generate_key(&attributes, &key_id); + if (status != PSA_SUCCESS) { + printf("psa_generate_key failed (%d)\n", status); + return EXIT_FAILURE; + } + + status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, + original, sizeof(original), NULL, 0, + encrypt, sizeof(encrypt), &encrypted_length); + if (status != PSA_SUCCESS) { + printf("psa_asymmetric_encrypt failed (%d)\n", status); + return EXIT_FAILURE; + } + + status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, + encrypt, encrypted_length, NULL, 0, + decrypt, sizeof(decrypt), &decrypted_length); + if (status != PSA_SUCCESS) { + printf("psa_cipher_decrypt failed (%d)\n", status); + return EXIT_FAILURE; + } + + if (memcmp(original, decrypt, sizeof(original)) != 0) { + printf("\nEncryption/Decryption failed!\n"); + } else { + printf("\nEncryption/Decryption successful!\n"); + } + + psa_destroy_key(key_id); + mbedtls_psa_crypto_free(); + return 0; +} From 39865e31442e1ceb4afd04c70500f3cf2e88b436 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 25 Jun 2024 13:49:38 +0200 Subject: [PATCH 079/125] psasim: fix max line length in generated files Prevent generated files from having lines longer than 100 chars which would trigger CI failures on code style checks. Signed-off-by: Valerio Setti --- psasim/src/psa_sim_crypto_client.c | 2264 +++++++++++++++++++--------- psasim/src/psa_sim_crypto_server.c | 1598 +++++++++++++++----- psasim/src/psa_sim_generate.pl | 55 +- psasim/src/psa_sim_serialise.c | 161 +- psasim/src/psa_sim_serialise.h | 75 +- psasim/src/psa_sim_serialise.pl | 26 +- 6 files changed, 2979 insertions(+), 1200 deletions(-) diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 091e354b19..28dff38d02 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -134,8 +134,9 @@ psa_status_t psa_aead_abort( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -150,7 +151,9 @@ psa_status_t psa_aead_abort( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -170,12 +173,16 @@ psa_status_t psa_aead_abort( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -203,14 +210,15 @@ psa_status_t psa_aead_decrypt( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(nonce, nonce_length) + - psasim_serialise_buffer_needs(additional_data, additional_data_length) + - psasim_serialise_buffer_needs(ciphertext, ciphertext_length) + - psasim_serialise_buffer_needs(plaintext, plaintext_size) + - psasim_serialise_size_t_needs(*plaintext_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(nonce, nonce_length) + + psasim_serialise_buffer_needs(additional_data, additional_data_length) + + psasim_serialise_buffer_needs(ciphertext, ciphertext_length) + + psasim_serialise_buffer_needs(plaintext, plaintext_size) + + psasim_serialise_size_t_needs(*plaintext_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -225,31 +233,45 @@ psa_status_t psa_aead_decrypt( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, nonce, nonce_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + nonce, nonce_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, additional_data, additional_data_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + additional_data, additional_data_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, ciphertext, ciphertext_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + ciphertext, ciphertext_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, plaintext, plaintext_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + plaintext, plaintext_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *plaintext_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *plaintext_length); if (!ok) { goto fail; } @@ -269,17 +291,23 @@ psa_status_t psa_aead_decrypt( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, plaintext, plaintext_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + plaintext, plaintext_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, plaintext_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + plaintext_length); if (!ok) { goto fail; } @@ -303,10 +331,11 @@ psa_status_t psa_aead_decrypt_setup( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); ser_params = malloc(needed); if (ser_params == NULL) { @@ -321,15 +350,21 @@ psa_status_t psa_aead_decrypt_setup( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } @@ -349,12 +384,16 @@ psa_status_t psa_aead_decrypt_setup( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -382,14 +421,15 @@ psa_status_t psa_aead_encrypt( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(nonce, nonce_length) + - psasim_serialise_buffer_needs(additional_data, additional_data_length) + - psasim_serialise_buffer_needs(plaintext, plaintext_length) + - psasim_serialise_buffer_needs(ciphertext, ciphertext_size) + - psasim_serialise_size_t_needs(*ciphertext_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(nonce, nonce_length) + + psasim_serialise_buffer_needs(additional_data, additional_data_length) + + psasim_serialise_buffer_needs(plaintext, plaintext_length) + + psasim_serialise_buffer_needs(ciphertext, ciphertext_size) + + psasim_serialise_size_t_needs(*ciphertext_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -404,31 +444,45 @@ psa_status_t psa_aead_encrypt( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, nonce, nonce_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + nonce, nonce_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, additional_data, additional_data_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + additional_data, additional_data_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, plaintext, plaintext_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + plaintext, plaintext_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, ciphertext, ciphertext_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + ciphertext, ciphertext_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *ciphertext_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *ciphertext_length); if (!ok) { goto fail; } @@ -448,17 +502,23 @@ psa_status_t psa_aead_encrypt( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, ciphertext, ciphertext_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + ciphertext, ciphertext_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, ciphertext_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + ciphertext_length); if (!ok) { goto fail; } @@ -482,10 +542,11 @@ psa_status_t psa_aead_encrypt_setup( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); ser_params = malloc(needed); if (ser_params == NULL) { @@ -500,15 +561,21 @@ psa_status_t psa_aead_encrypt_setup( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } @@ -528,12 +595,16 @@ psa_status_t psa_aead_encrypt_setup( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -559,12 +630,13 @@ psa_status_t psa_aead_finish( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(ciphertext, ciphertext_size) + - psasim_serialise_size_t_needs(*ciphertext_length) + - psasim_serialise_buffer_needs(tag, tag_size) + - psasim_serialise_size_t_needs(*tag_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(ciphertext, ciphertext_size) + + psasim_serialise_size_t_needs(*ciphertext_length) + + psasim_serialise_buffer_needs(tag, tag_size) + + psasim_serialise_size_t_needs(*tag_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -579,23 +651,33 @@ psa_status_t psa_aead_finish( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, ciphertext, ciphertext_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + ciphertext, ciphertext_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *ciphertext_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *ciphertext_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, tag, tag_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + tag, tag_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *tag_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *tag_length); if (!ok) { goto fail; } @@ -615,32 +697,44 @@ psa_status_t psa_aead_finish( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, ciphertext, ciphertext_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + ciphertext, ciphertext_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, ciphertext_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + ciphertext_length); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, tag, tag_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + tag, tag_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, tag_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + tag_length); if (!ok) { goto fail; } @@ -664,10 +758,11 @@ psa_status_t psa_aead_generate_nonce( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(nonce, nonce_size) + - psasim_serialise_size_t_needs(*nonce_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(nonce, nonce_size) + + psasim_serialise_size_t_needs(*nonce_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -682,15 +777,21 @@ psa_status_t psa_aead_generate_nonce( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, nonce, nonce_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + nonce, nonce_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *nonce_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *nonce_length); if (!ok) { goto fail; } @@ -710,22 +811,30 @@ psa_status_t psa_aead_generate_nonce( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, nonce, nonce_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + nonce, nonce_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, nonce_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + nonce_length); if (!ok) { goto fail; } @@ -749,10 +858,11 @@ psa_status_t psa_aead_set_lengths( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_size_t_needs(ad_length) + - psasim_serialise_size_t_needs(plaintext_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_size_t_needs(ad_length) + + psasim_serialise_size_t_needs(plaintext_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -767,15 +877,21 @@ psa_status_t psa_aead_set_lengths( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, ad_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + ad_length); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, plaintext_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + plaintext_length); if (!ok) { goto fail; } @@ -795,12 +911,16 @@ psa_status_t psa_aead_set_lengths( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -823,9 +943,10 @@ psa_status_t psa_aead_set_nonce( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(nonce, nonce_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(nonce, nonce_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -840,11 +961,15 @@ psa_status_t psa_aead_set_nonce( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, nonce, nonce_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + nonce, nonce_length); if (!ok) { goto fail; } @@ -864,12 +989,16 @@ psa_status_t psa_aead_set_nonce( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -894,11 +1023,12 @@ psa_status_t psa_aead_update( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(output, output_size) + - psasim_serialise_size_t_needs(*output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -913,19 +1043,27 @@ psa_status_t psa_aead_update( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *output_length); if (!ok) { goto fail; } @@ -945,22 +1083,30 @@ psa_status_t psa_aead_update( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -983,9 +1129,10 @@ psa_status_t psa_aead_update_ad( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(input, input_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1000,11 +1147,15 @@ psa_status_t psa_aead_update_ad( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } @@ -1024,12 +1175,16 @@ psa_status_t psa_aead_update_ad( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1054,11 +1209,12 @@ psa_status_t psa_aead_verify( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_aead_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(plaintext, plaintext_size) + - psasim_serialise_size_t_needs(*plaintext_length) + - psasim_serialise_buffer_needs(tag, tag_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_aead_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(plaintext, plaintext_size) + + psasim_serialise_size_t_needs(*plaintext_length) + + psasim_serialise_buffer_needs(tag, tag_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1073,19 +1229,27 @@ psa_status_t psa_aead_verify( if (!ok) { goto fail; } - ok = psasim_serialise_psa_aead_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_aead_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, plaintext, plaintext_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + plaintext, plaintext_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *plaintext_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *plaintext_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, tag, tag_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + tag, tag_length); if (!ok) { goto fail; } @@ -1105,22 +1269,30 @@ psa_status_t psa_aead_verify( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, plaintext, plaintext_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + plaintext, plaintext_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, plaintext_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + plaintext_length); if (!ok) { goto fail; } @@ -1147,13 +1319,14 @@ psa_status_t psa_asymmetric_decrypt( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(salt, salt_length) + - psasim_serialise_buffer_needs(output, output_size) + - psasim_serialise_size_t_needs(*output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(salt, salt_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1168,27 +1341,39 @@ psa_status_t psa_asymmetric_decrypt( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, salt, salt_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + salt, salt_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *output_length); if (!ok) { goto fail; } @@ -1208,17 +1393,23 @@ psa_status_t psa_asymmetric_decrypt( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1245,13 +1436,14 @@ psa_status_t psa_asymmetric_encrypt( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(salt, salt_length) + - psasim_serialise_buffer_needs(output, output_size) + - psasim_serialise_size_t_needs(*output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(salt, salt_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1266,27 +1458,39 @@ psa_status_t psa_asymmetric_encrypt( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, salt, salt_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + salt, salt_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *output_length); if (!ok) { goto fail; } @@ -1306,17 +1510,23 @@ psa_status_t psa_asymmetric_encrypt( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1338,8 +1548,9 @@ psa_status_t psa_cipher_abort( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_cipher_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_cipher_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1354,7 +1565,9 @@ psa_status_t psa_cipher_abort( if (!ok) { goto fail; } - ok = psasim_serialise_psa_cipher_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_cipher_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -1374,12 +1587,16 @@ psa_status_t psa_cipher_abort( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1405,12 +1622,13 @@ psa_status_t psa_cipher_decrypt( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(output, output_size) + - psasim_serialise_size_t_needs(*output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1425,23 +1643,33 @@ psa_status_t psa_cipher_decrypt( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *output_length); if (!ok) { goto fail; } @@ -1461,17 +1689,23 @@ psa_status_t psa_cipher_decrypt( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1495,10 +1729,11 @@ psa_status_t psa_cipher_decrypt_setup( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_cipher_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_cipher_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1513,15 +1748,21 @@ psa_status_t psa_cipher_decrypt_setup( if (!ok) { goto fail; } - ok = psasim_serialise_psa_cipher_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_cipher_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } @@ -1541,12 +1782,16 @@ psa_status_t psa_cipher_decrypt_setup( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1572,12 +1817,13 @@ psa_status_t psa_cipher_encrypt( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(output, output_size) + - psasim_serialise_size_t_needs(*output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1592,23 +1838,33 @@ psa_status_t psa_cipher_encrypt( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *output_length); if (!ok) { goto fail; } @@ -1628,17 +1884,23 @@ psa_status_t psa_cipher_encrypt( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1662,10 +1924,11 @@ psa_status_t psa_cipher_encrypt_setup( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_cipher_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_cipher_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1680,15 +1943,21 @@ psa_status_t psa_cipher_encrypt_setup( if (!ok) { goto fail; } - ok = psasim_serialise_psa_cipher_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_cipher_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } @@ -1708,12 +1977,16 @@ psa_status_t psa_cipher_encrypt_setup( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1737,10 +2010,11 @@ psa_status_t psa_cipher_finish( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_cipher_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(output, output_size) + - psasim_serialise_size_t_needs(*output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_cipher_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1755,15 +2029,21 @@ psa_status_t psa_cipher_finish( if (!ok) { goto fail; } - ok = psasim_serialise_psa_cipher_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_cipher_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *output_length); if (!ok) { goto fail; } @@ -1783,22 +2063,30 @@ psa_status_t psa_cipher_finish( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1822,10 +2110,11 @@ psa_status_t psa_cipher_generate_iv( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_cipher_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(iv, iv_size) + - psasim_serialise_size_t_needs(*iv_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_cipher_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(iv, iv_size) + + psasim_serialise_size_t_needs(*iv_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1840,15 +2129,21 @@ psa_status_t psa_cipher_generate_iv( if (!ok) { goto fail; } - ok = psasim_serialise_psa_cipher_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_cipher_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, iv, iv_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + iv, iv_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *iv_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *iv_length); if (!ok) { goto fail; } @@ -1868,22 +2163,30 @@ psa_status_t psa_cipher_generate_iv( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, iv, iv_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + iv, iv_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, iv_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + iv_length); if (!ok) { goto fail; } @@ -1906,9 +2209,10 @@ psa_status_t psa_cipher_set_iv( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_cipher_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(iv, iv_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_cipher_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(iv, iv_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1923,11 +2227,15 @@ psa_status_t psa_cipher_set_iv( if (!ok) { goto fail; } - ok = psasim_serialise_psa_cipher_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_cipher_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, iv, iv_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + iv, iv_length); if (!ok) { goto fail; } @@ -1947,12 +2255,16 @@ psa_status_t psa_cipher_set_iv( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1977,11 +2289,12 @@ psa_status_t psa_cipher_update( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_cipher_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(output, output_size) + - psasim_serialise_size_t_needs(*output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_cipher_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -1996,19 +2309,27 @@ psa_status_t psa_cipher_update( if (!ok) { goto fail; } - ok = psasim_serialise_psa_cipher_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_cipher_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *output_length); if (!ok) { goto fail; } @@ -2028,22 +2349,30 @@ psa_status_t psa_cipher_update( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -2067,10 +2396,11 @@ psa_status_t psa_copy_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(source_key) + - psasim_serialise_psa_key_attributes_t_needs(*attributes) + - psasim_serialise_mbedtls_svc_key_id_t_needs(*target_key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(source_key) + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*target_key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2085,15 +2415,21 @@ psa_status_t psa_copy_key( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, source_key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + source_key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *target_key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + *target_key); if (!ok) { goto fail; } @@ -2113,12 +2449,16 @@ psa_status_t psa_copy_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, target_key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + target_key); if (!ok) { goto fail; } @@ -2140,8 +2480,9 @@ psa_status_t psa_destroy_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2156,7 +2497,9 @@ psa_status_t psa_destroy_key( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } @@ -2176,7 +2519,9 @@ psa_status_t psa_destroy_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } @@ -2200,10 +2545,11 @@ psa_status_t psa_export_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_buffer_needs(data, data_size) + - psasim_serialise_size_t_needs(*data_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_buffer_needs(data, data_size) + + psasim_serialise_size_t_needs(*data_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2218,15 +2564,21 @@ psa_status_t psa_export_key( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, data, data_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + data, data_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *data_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *data_length); if (!ok) { goto fail; } @@ -2246,17 +2598,23 @@ psa_status_t psa_export_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, data, data_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + data, data_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, data_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + data_length); if (!ok) { goto fail; } @@ -2280,10 +2638,11 @@ psa_status_t psa_export_public_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_buffer_needs(data, data_size) + - psasim_serialise_size_t_needs(*data_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_buffer_needs(data, data_size) + + psasim_serialise_size_t_needs(*data_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2298,15 +2657,21 @@ psa_status_t psa_export_public_key( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, data, data_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + data, data_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *data_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *data_length); if (!ok) { goto fail; } @@ -2326,17 +2691,23 @@ psa_status_t psa_export_public_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, data, data_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + data, data_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, data_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + data_length); if (!ok) { goto fail; } @@ -2359,9 +2730,10 @@ psa_status_t psa_generate_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_attributes_t_needs(*attributes) + - psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2376,11 +2748,15 @@ psa_status_t psa_generate_key( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + *key); if (!ok) { goto fail; } @@ -2400,12 +2776,16 @@ psa_status_t psa_generate_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -2429,10 +2809,11 @@ psa_status_t psa_generate_key_ext( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_attributes_t_needs(*attributes) + - psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) + - psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2447,15 +2828,21 @@ psa_status_t psa_generate_key_ext( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_production_parameters_t(&pos, &remaining, params, params_data_length); + ok = psasim_serialise_psa_key_production_parameters_t( + &pos, &remaining, + params, params_data_length); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + *key); if (!ok) { goto fail; } @@ -2475,12 +2862,16 @@ psa_status_t psa_generate_key_ext( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -2502,8 +2893,9 @@ psa_status_t psa_generate_random( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_buffer_needs(output, output_size); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_buffer_needs(output, output_size); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2518,7 +2910,9 @@ psa_status_t psa_generate_random( if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } @@ -2538,12 +2932,16 @@ psa_status_t psa_generate_random( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } @@ -2566,9 +2964,10 @@ psa_status_t psa_get_key_attributes( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_key_attributes_t_needs(*attributes); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_key_attributes_t_needs(*attributes); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2583,11 +2982,15 @@ psa_status_t psa_get_key_attributes( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } @@ -2607,12 +3010,16 @@ psa_status_t psa_get_key_attributes( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&rpos, &rremain, attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &rpos, &rremain, + attributes); if (!ok) { goto fail; } @@ -2634,8 +3041,9 @@ psa_status_t psa_hash_abort( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2650,7 +3058,9 @@ psa_status_t psa_hash_abort( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -2670,12 +3080,16 @@ psa_status_t psa_hash_abort( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -2698,9 +3112,10 @@ psa_status_t psa_hash_clone( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*source_operation) + - psasim_serialise_psa_hash_operation_t_needs(*target_operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*source_operation) + + psasim_serialise_psa_hash_operation_t_needs(*target_operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2715,11 +3130,15 @@ psa_status_t psa_hash_clone( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&pos, &remaining, *source_operation); + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *source_operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&pos, &remaining, *target_operation); + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *target_operation); if (!ok) { goto fail; } @@ -2739,12 +3158,16 @@ psa_status_t psa_hash_clone( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&rpos, &rremain, target_operation); + ok = psasim_deserialise_psa_hash_operation_t( + &rpos, &rremain, + target_operation); if (!ok) { goto fail; } @@ -2768,10 +3191,11 @@ psa_status_t psa_hash_compare( 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_length); + 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_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2786,15 +3210,21 @@ psa_status_t psa_hash_compare( if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_length); if (!ok) { goto fail; } @@ -2814,7 +3244,9 @@ psa_status_t psa_hash_compare( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } @@ -2839,11 +3271,12 @@ psa_status_t psa_hash_compute( 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); + 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); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2858,19 +3291,27 @@ psa_status_t psa_hash_compute( if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *hash_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *hash_length); if (!ok) { goto fail; } @@ -2890,17 +3331,23 @@ psa_status_t psa_hash_compute( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, hash, hash_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + hash, hash_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, hash_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + hash_length); if (!ok) { goto fail; } @@ -2924,10 +3371,11 @@ psa_status_t psa_hash_finish( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(hash, hash_size) + - psasim_serialise_size_t_needs(*hash_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(hash, hash_size) + + psasim_serialise_size_t_needs(*hash_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2942,15 +3390,21 @@ psa_status_t psa_hash_finish( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *hash_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *hash_length); if (!ok) { goto fail; } @@ -2970,22 +3424,30 @@ psa_status_t psa_hash_finish( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, hash, hash_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + hash, hash_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, hash_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + hash_length); if (!ok) { goto fail; } @@ -3008,9 +3470,10 @@ psa_status_t psa_hash_setup( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation) + - psasim_serialise_psa_algorithm_t_needs(alg); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation) + + psasim_serialise_psa_algorithm_t_needs(alg); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3025,11 +3488,15 @@ psa_status_t psa_hash_setup( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } @@ -3049,12 +3516,16 @@ psa_status_t psa_hash_setup( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3077,9 +3548,10 @@ psa_status_t psa_hash_update( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(input, input_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3094,11 +3566,15 @@ psa_status_t psa_hash_update( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } @@ -3118,12 +3594,16 @@ psa_status_t psa_hash_update( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3146,9 +3626,10 @@ psa_status_t psa_hash_verify( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(hash, hash_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(hash, hash_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3163,11 +3644,15 @@ psa_status_t psa_hash_verify( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_length); if (!ok) { goto fail; } @@ -3187,12 +3672,16 @@ psa_status_t psa_hash_verify( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3216,10 +3705,11 @@ psa_status_t psa_import_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_attributes_t_needs(*attributes) + - psasim_serialise_buffer_needs(data, data_length) + - psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_buffer_needs(data, data_length) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3234,15 +3724,21 @@ psa_status_t psa_import_key( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, data, data_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + data, data_length); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + *key); if (!ok) { goto fail; } @@ -3262,12 +3758,16 @@ psa_status_t psa_import_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -3282,15 +3782,16 @@ psa_status_t psa_import_key( uint32_t psa_interruptible_get_max_ops( void -) + ) { uint8_t *ser_params = NULL; uint8_t *ser_result = NULL; size_t result_length; uint32_t value = 0; - size_t needed = psasim_serialise_begin_needs() + - 0; + size_t needed = + psasim_serialise_begin_needs() + + 0; ser_params = malloc(needed); if (ser_params == NULL) { @@ -3321,7 +3822,9 @@ uint32_t psa_interruptible_get_max_ops( goto fail; } - ok = psasim_deserialise_uint32_t(&rpos, &rremain, &value); + ok = psasim_deserialise_uint32_t( + &rpos, &rremain, + &value); if (!ok) { goto fail; } @@ -3342,8 +3845,9 @@ void psa_interruptible_set_max_ops( uint8_t *ser_result = NULL; size_t result_length; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_uint32_t_needs(max_ops); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_uint32_t_needs(max_ops); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3357,7 +3861,9 @@ void psa_interruptible_set_max_ops( if (!ok) { goto fail; } - ok = psasim_serialise_uint32_t(&pos, &remaining, max_ops); + ok = psasim_serialise_uint32_t( + &pos, &remaining, + max_ops); if (!ok) { goto fail; } @@ -3392,8 +3898,9 @@ psa_status_t psa_key_derivation_abort( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3408,7 +3915,9 @@ psa_status_t psa_key_derivation_abort( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -3428,12 +3937,16 @@ psa_status_t psa_key_derivation_abort( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3456,9 +3969,10 @@ psa_status_t psa_key_derivation_get_capacity( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_size_t_needs(*capacity); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_size_t_needs(*capacity); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3473,11 +3987,15 @@ psa_status_t psa_key_derivation_get_capacity( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *capacity); + ok = psasim_serialise_size_t( + &pos, &remaining, + *capacity); if (!ok) { goto fail; } @@ -3497,12 +4015,16 @@ psa_status_t psa_key_derivation_get_capacity( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, capacity); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + capacity); if (!ok) { goto fail; } @@ -3526,10 +4048,11 @@ psa_status_t psa_key_derivation_input_bytes( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_psa_key_derivation_step_t_needs(step) + - psasim_serialise_buffer_needs(data, data_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_derivation_step_t_needs(step) + + psasim_serialise_buffer_needs(data, data_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3544,15 +4067,21 @@ psa_status_t psa_key_derivation_input_bytes( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step); + ok = psasim_serialise_psa_key_derivation_step_t( + &pos, &remaining, + step); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, data, data_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + data, data_length); if (!ok) { goto fail; } @@ -3572,12 +4101,16 @@ psa_status_t psa_key_derivation_input_bytes( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3601,10 +4134,11 @@ psa_status_t psa_key_derivation_input_integer( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_psa_key_derivation_step_t_needs(step) + - psasim_serialise_uint64_t_needs(value); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_derivation_step_t_needs(step) + + psasim_serialise_uint64_t_needs(value); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3619,15 +4153,21 @@ psa_status_t psa_key_derivation_input_integer( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step); + ok = psasim_serialise_psa_key_derivation_step_t( + &pos, &remaining, + step); if (!ok) { goto fail; } - ok = psasim_serialise_uint64_t(&pos, &remaining, value); + ok = psasim_serialise_uint64_t( + &pos, &remaining, + value); if (!ok) { goto fail; } @@ -3647,12 +4187,16 @@ psa_status_t psa_key_derivation_input_integer( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3676,10 +4220,11 @@ psa_status_t psa_key_derivation_input_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_psa_key_derivation_step_t_needs(step) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_derivation_step_t_needs(step) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3694,15 +4239,21 @@ psa_status_t psa_key_derivation_input_key( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step); + ok = psasim_serialise_psa_key_derivation_step_t( + &pos, &remaining, + step); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } @@ -3722,12 +4273,16 @@ psa_status_t psa_key_derivation_input_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3752,11 +4307,12 @@ psa_status_t psa_key_derivation_key_agreement( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_psa_key_derivation_step_t_needs(step) + - psasim_serialise_mbedtls_svc_key_id_t_needs(private_key) + - psasim_serialise_buffer_needs(peer_key, peer_key_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_derivation_step_t_needs(step) + + psasim_serialise_mbedtls_svc_key_id_t_needs(private_key) + + psasim_serialise_buffer_needs(peer_key, peer_key_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3771,19 +4327,27 @@ psa_status_t psa_key_derivation_key_agreement( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_step_t(&pos, &remaining, step); + ok = psasim_serialise_psa_key_derivation_step_t( + &pos, &remaining, + step); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, private_key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + private_key); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, peer_key, peer_key_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + peer_key, peer_key_length); if (!ok) { goto fail; } @@ -3803,12 +4367,16 @@ psa_status_t psa_key_derivation_key_agreement( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3831,9 +4399,10 @@ psa_status_t psa_key_derivation_output_bytes( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(output, output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(output, output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3848,11 +4417,15 @@ psa_status_t psa_key_derivation_output_bytes( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_length); if (!ok) { goto fail; } @@ -3872,17 +4445,23 @@ psa_status_t psa_key_derivation_output_bytes( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_length); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_length); if (!ok) { goto fail; } @@ -3906,10 +4485,11 @@ psa_status_t psa_key_derivation_output_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_attributes_t_needs(*attributes) + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3924,15 +4504,21 @@ psa_status_t psa_key_derivation_output_key( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + *key); if (!ok) { goto fail; } @@ -3952,17 +4538,23 @@ psa_status_t psa_key_derivation_output_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -3987,11 +4579,12 @@ psa_status_t psa_key_derivation_output_key_ext( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_attributes_t_needs(*attributes) + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) + - psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4006,19 +4599,27 @@ psa_status_t psa_key_derivation_output_key_ext( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_production_parameters_t(&pos, &remaining, params, params_data_length); + ok = psasim_serialise_psa_key_production_parameters_t( + &pos, &remaining, + params, params_data_length); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, *key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + *key); if (!ok) { goto fail; } @@ -4038,17 +4639,23 @@ psa_status_t psa_key_derivation_output_key_ext( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -4071,9 +4678,10 @@ psa_status_t psa_key_derivation_set_capacity( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_size_t_needs(capacity); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_size_t_needs(capacity); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4088,11 +4696,15 @@ psa_status_t psa_key_derivation_set_capacity( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, capacity); + ok = psasim_serialise_size_t( + &pos, &remaining, + capacity); if (!ok) { goto fail; } @@ -4112,12 +4724,16 @@ psa_status_t psa_key_derivation_set_capacity( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4140,9 +4756,10 @@ psa_status_t psa_key_derivation_setup( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_psa_algorithm_t_needs(alg); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + + psasim_serialise_psa_algorithm_t_needs(alg); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4157,11 +4774,15 @@ psa_status_t psa_key_derivation_setup( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_derivation_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_key_derivation_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } @@ -4181,12 +4802,16 @@ psa_status_t psa_key_derivation_setup( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4208,8 +4833,9 @@ psa_status_t psa_mac_abort( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_mac_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_mac_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4224,7 +4850,9 @@ psa_status_t psa_mac_abort( if (!ok) { goto fail; } - ok = psasim_serialise_psa_mac_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_mac_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -4244,12 +4872,16 @@ psa_status_t psa_mac_abort( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4275,12 +4907,13 @@ psa_status_t psa_mac_compute( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(mac, mac_size) + - psasim_serialise_size_t_needs(*mac_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(mac, mac_size) + + psasim_serialise_size_t_needs(*mac_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4295,23 +4928,33 @@ psa_status_t psa_mac_compute( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, mac, mac_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + mac, mac_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *mac_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *mac_length); if (!ok) { goto fail; } @@ -4331,17 +4974,23 @@ psa_status_t psa_mac_compute( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, mac, mac_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + mac, mac_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, mac_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + mac_length); if (!ok) { goto fail; } @@ -4365,10 +5014,11 @@ psa_status_t psa_mac_sign_finish( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_mac_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(mac, mac_size) + - psasim_serialise_size_t_needs(*mac_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_mac_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(mac, mac_size) + + psasim_serialise_size_t_needs(*mac_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4383,15 +5033,21 @@ psa_status_t psa_mac_sign_finish( if (!ok) { goto fail; } - ok = psasim_serialise_psa_mac_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_mac_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, mac, mac_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + mac, mac_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *mac_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *mac_length); if (!ok) { goto fail; } @@ -4411,22 +5067,30 @@ psa_status_t psa_mac_sign_finish( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, mac, mac_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + mac, mac_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, mac_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + mac_length); if (!ok) { goto fail; } @@ -4450,10 +5114,11 @@ psa_status_t psa_mac_sign_setup( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_mac_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_mac_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4468,15 +5133,21 @@ psa_status_t psa_mac_sign_setup( if (!ok) { goto fail; } - ok = psasim_serialise_psa_mac_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_mac_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } @@ -4496,12 +5167,16 @@ psa_status_t psa_mac_sign_setup( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4524,9 +5199,10 @@ psa_status_t psa_mac_update( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_mac_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(input, input_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_mac_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4541,11 +5217,15 @@ psa_status_t psa_mac_update( if (!ok) { goto fail; } - ok = psasim_serialise_psa_mac_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_mac_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } @@ -4565,12 +5245,16 @@ psa_status_t psa_mac_update( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4595,11 +5279,12 @@ psa_status_t psa_mac_verify( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(mac, mac_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(mac, mac_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4614,19 +5299,27 @@ psa_status_t psa_mac_verify( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, mac, mac_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + mac, mac_length); if (!ok) { goto fail; } @@ -4646,7 +5339,9 @@ psa_status_t psa_mac_verify( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } @@ -4669,9 +5364,10 @@ psa_status_t psa_mac_verify_finish( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_mac_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(mac, mac_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_mac_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(mac, mac_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4686,11 +5382,15 @@ psa_status_t psa_mac_verify_finish( if (!ok) { goto fail; } - ok = psasim_serialise_psa_mac_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_mac_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, mac, mac_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + mac, mac_length); if (!ok) { goto fail; } @@ -4710,12 +5410,16 @@ psa_status_t psa_mac_verify_finish( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4739,10 +5443,11 @@ psa_status_t psa_mac_verify_setup( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_mac_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_mac_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4757,15 +5462,21 @@ psa_status_t psa_mac_verify_setup( if (!ok) { goto fail; } - ok = psasim_serialise_psa_mac_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_mac_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } @@ -4785,12 +5496,16 @@ psa_status_t psa_mac_verify_setup( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4812,8 +5527,9 @@ psa_status_t psa_purge_key( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4828,7 +5544,9 @@ psa_status_t psa_purge_key( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } @@ -4848,7 +5566,9 @@ psa_status_t psa_purge_key( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } @@ -4874,12 +5594,13 @@ psa_status_t psa_raw_key_agreement( 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_mbedtls_svc_key_id_t_needs(private_key) + - psasim_serialise_buffer_needs(peer_key, peer_key_length) + - psasim_serialise_buffer_needs(output, output_size) + - psasim_serialise_size_t_needs(*output_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_mbedtls_svc_key_id_t_needs(private_key) + + psasim_serialise_buffer_needs(peer_key, peer_key_length) + + psasim_serialise_buffer_needs(output, output_size) + + psasim_serialise_size_t_needs(*output_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4894,23 +5615,33 @@ psa_status_t psa_raw_key_agreement( if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, private_key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + private_key); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, peer_key, peer_key_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + peer_key, peer_key_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, output, output_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *output_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *output_length); if (!ok) { goto fail; } @@ -4930,17 +5661,23 @@ psa_status_t psa_raw_key_agreement( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, output, output_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, output_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -4961,8 +5698,9 @@ void psa_reset_key_attributes( uint8_t *ser_result = NULL; size_t result_length; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_attributes_t_needs(*attributes); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes); ser_params = malloc(needed); if (ser_params == NULL) { @@ -4976,7 +5714,9 @@ void psa_reset_key_attributes( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes); + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } @@ -4996,7 +5736,9 @@ void psa_reset_key_attributes( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&rpos, &rremain, attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &rpos, &rremain, + attributes); if (!ok) { goto fail; } @@ -5020,12 +5762,13 @@ psa_status_t psa_sign_hash( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(hash, hash_length) + - psasim_serialise_buffer_needs(signature, signature_size) + - psasim_serialise_size_t_needs(*signature_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(hash, hash_length) + + psasim_serialise_buffer_needs(signature, signature_size) + + psasim_serialise_size_t_needs(*signature_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5040,23 +5783,33 @@ psa_status_t psa_sign_hash( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *signature_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *signature_length); if (!ok) { goto fail; } @@ -5076,17 +5829,23 @@ psa_status_t psa_sign_hash( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, signature, signature_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, signature_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + signature_length); if (!ok) { goto fail; } @@ -5108,8 +5867,9 @@ psa_status_t psa_sign_hash_abort( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5124,7 +5884,9 @@ psa_status_t psa_sign_hash_abort( if (!ok) { goto fail; } - ok = psasim_serialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_sign_hash_interruptible_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -5144,12 +5906,16 @@ psa_status_t psa_sign_hash_abort( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_sign_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5173,10 +5939,11 @@ psa_status_t psa_sign_hash_complete( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(signature, signature_size) + - psasim_serialise_size_t_needs(*signature_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(signature, signature_size) + + psasim_serialise_size_t_needs(*signature_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5191,15 +5958,21 @@ psa_status_t psa_sign_hash_complete( if (!ok) { goto fail; } - ok = psasim_serialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_sign_hash_interruptible_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *signature_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *signature_length); if (!ok) { goto fail; } @@ -5219,22 +5992,30 @@ psa_status_t psa_sign_hash_complete( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_sign_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, signature, signature_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, signature_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + signature_length); if (!ok) { goto fail; } @@ -5256,8 +6037,9 @@ uint32_t psa_sign_hash_get_num_ops( size_t result_length; uint32_t value = 0; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5272,7 +6054,9 @@ uint32_t psa_sign_hash_get_num_ops( if (!ok) { goto fail; } - ok = psasim_serialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_sign_hash_interruptible_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -5292,7 +6076,9 @@ uint32_t psa_sign_hash_get_num_ops( goto fail; } - ok = psasim_deserialise_uint32_t(&rpos, &rremain, &value); + ok = psasim_deserialise_uint32_t( + &rpos, &rremain, + &value); if (!ok) { goto fail; } @@ -5317,11 +6103,12 @@ psa_status_t psa_sign_hash_start( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(hash, hash_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(hash, hash_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5336,19 +6123,27 @@ psa_status_t psa_sign_hash_start( if (!ok) { goto fail; } - ok = psasim_serialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_sign_hash_interruptible_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_length); if (!ok) { goto fail; } @@ -5368,12 +6163,16 @@ psa_status_t psa_sign_hash_start( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_sign_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5399,12 +6198,13 @@ psa_status_t psa_sign_message( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(signature, signature_size) + - psasim_serialise_size_t_needs(*signature_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(signature, signature_size) + + psasim_serialise_size_t_needs(*signature_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5419,23 +6219,33 @@ psa_status_t psa_sign_message( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_size); + ok = psasim_serialise_buffer( + &pos, &remaining, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&pos, &remaining, *signature_length); + ok = psasim_serialise_size_t( + &pos, &remaining, + *signature_length); if (!ok) { goto fail; } @@ -5455,17 +6265,23 @@ psa_status_t psa_sign_message( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_return_buffer(&rpos, &rremain, signature, signature_size); + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&rpos, &rremain, signature_length); + ok = psasim_deserialise_size_t( + &rpos, &rremain, + signature_length); if (!ok) { goto fail; } @@ -5490,11 +6306,12 @@ psa_status_t psa_verify_hash( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(hash, hash_length) + - psasim_serialise_buffer_needs(signature, signature_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(hash, hash_length) + + psasim_serialise_buffer_needs(signature, signature_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5509,19 +6326,27 @@ psa_status_t psa_verify_hash( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + signature, signature_length); if (!ok) { goto fail; } @@ -5541,7 +6366,9 @@ psa_status_t psa_verify_hash( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } @@ -5563,8 +6390,9 @@ psa_status_t psa_verify_hash_abort( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5579,7 +6407,9 @@ psa_status_t psa_verify_hash_abort( if (!ok) { goto fail; } - ok = psasim_serialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_verify_hash_interruptible_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -5599,12 +6429,16 @@ psa_status_t psa_verify_hash_abort( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_verify_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5626,8 +6460,9 @@ psa_status_t psa_verify_hash_complete( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5642,7 +6477,9 @@ psa_status_t psa_verify_hash_complete( if (!ok) { goto fail; } - ok = psasim_serialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_verify_hash_interruptible_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -5662,12 +6499,16 @@ psa_status_t psa_verify_hash_complete( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_verify_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5689,8 +6530,9 @@ uint32_t psa_verify_hash_get_num_ops( size_t result_length; uint32_t value = 0; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5705,7 +6547,9 @@ uint32_t psa_verify_hash_get_num_ops( if (!ok) { goto fail; } - ok = psasim_serialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_verify_hash_interruptible_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } @@ -5725,7 +6569,9 @@ uint32_t psa_verify_hash_get_num_ops( goto fail; } - ok = psasim_deserialise_uint32_t(&rpos, &rremain, &value); + ok = psasim_deserialise_uint32_t( + &rpos, &rremain, + &value); if (!ok) { goto fail; } @@ -5751,12 +6597,13 @@ psa_status_t psa_verify_hash_start( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation) + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(hash, hash_length) + - psasim_serialise_buffer_needs(signature, signature_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(hash, hash_length) + + psasim_serialise_buffer_needs(signature, signature_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5771,23 +6618,33 @@ psa_status_t psa_verify_hash_start( if (!ok) { goto fail; } - ok = psasim_serialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, *operation); + ok = psasim_serialise_psa_verify_hash_interruptible_operation_t( + &pos, &remaining, + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, hash, hash_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + signature, signature_length); if (!ok) { goto fail; } @@ -5807,12 +6664,16 @@ psa_status_t psa_verify_hash_start( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_deserialise_psa_verify_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5837,11 +6698,12 @@ psa_status_t psa_verify_message( size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_algorithm_t_needs(alg) + - psasim_serialise_buffer_needs(input, input_length) + - psasim_serialise_buffer_needs(signature, signature_length); + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(signature, signature_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -5856,19 +6718,27 @@ psa_status_t psa_verify_message( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&pos, &remaining, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t(&pos, &remaining, alg); + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, input, input_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&pos, &remaining, signature, signature_length); + ok = psasim_serialise_buffer( + &pos, &remaining, + signature, signature_length); if (!ok) { goto fail; } @@ -5888,7 +6758,9 @@ psa_status_t psa_verify_message( goto fail; } - ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status); + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); if (!ok) { goto fail; } diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 03e36c06e1..52597516cf 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -54,7 +54,9 @@ int psa_crypto_init_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } @@ -88,7 +90,9 @@ int psa_aead_abort_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -118,12 +122,16 @@ int psa_aead_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -167,37 +175,51 @@ int psa_aead_decrypt_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &nonce, &nonce_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &nonce, &nonce_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &additional_data, &additional_data_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &additional_data, &additional_data_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &ciphertext, &ciphertext_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &ciphertext, &ciphertext_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &plaintext, &plaintext_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &plaintext, &plaintext_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &plaintext_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &plaintext_length); if (!ok) { goto fail; } @@ -234,17 +256,23 @@ int psa_aead_decrypt_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, plaintext, plaintext_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + plaintext, plaintext_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, plaintext_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + plaintext_length); if (!ok) { goto fail; } @@ -290,17 +318,23 @@ int psa_aead_decrypt_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } @@ -332,12 +366,16 @@ int psa_aead_decrypt_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -381,37 +419,51 @@ int psa_aead_encrypt_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &nonce, &nonce_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &nonce, &nonce_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &additional_data, &additional_data_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &additional_data, &additional_data_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &plaintext, &plaintext_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &plaintext, &plaintext_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &ciphertext, &ciphertext_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &ciphertext, &ciphertext_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &ciphertext_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &ciphertext_length); if (!ok) { goto fail; } @@ -448,17 +500,23 @@ int psa_aead_encrypt_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, ciphertext, ciphertext_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + ciphertext, ciphertext_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, ciphertext_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + ciphertext_length); if (!ok) { goto fail; } @@ -504,17 +562,23 @@ int psa_aead_encrypt_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } @@ -546,12 +610,16 @@ int psa_aead_encrypt_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -591,27 +659,37 @@ int psa_aead_finish_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &ciphertext, &ciphertext_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &ciphertext, &ciphertext_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &ciphertext_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &ciphertext_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &tag, &tag_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &tag, &tag_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &tag_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &tag_length); if (!ok) { goto fail; } @@ -649,32 +727,44 @@ int psa_aead_finish_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, ciphertext, ciphertext_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + ciphertext, ciphertext_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, ciphertext_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + ciphertext_length); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, tag, tag_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + tag, tag_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, tag_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + tag_length); if (!ok) { goto fail; } @@ -717,17 +807,23 @@ int psa_aead_generate_nonce_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &nonce, &nonce_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &nonce, &nonce_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &nonce_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &nonce_length); if (!ok) { goto fail; } @@ -761,22 +857,30 @@ int psa_aead_generate_nonce_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, nonce, nonce_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + nonce, nonce_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, nonce_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + nonce_length); if (!ok) { goto fail; } @@ -816,17 +920,23 @@ int psa_aead_set_lengths_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &ad_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &ad_length); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &plaintext_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &plaintext_length); if (!ok) { goto fail; } @@ -858,12 +968,16 @@ int psa_aead_set_lengths_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -899,12 +1013,16 @@ int psa_aead_set_nonce_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &nonce, &nonce_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &nonce, &nonce_length); if (!ok) { goto fail; } @@ -935,12 +1053,16 @@ int psa_aead_set_nonce_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -983,22 +1105,30 @@ int psa_aead_update_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &output_length); if (!ok) { goto fail; } @@ -1033,22 +1163,30 @@ int psa_aead_update_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1090,12 +1228,16 @@ int psa_aead_update_ad_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } @@ -1126,12 +1268,16 @@ int psa_aead_update_ad_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1174,22 +1320,30 @@ int psa_aead_verify_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_aead_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_aead_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &plaintext, &plaintext_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &plaintext, &plaintext_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &plaintext_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &plaintext_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &tag, &tag_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &tag, &tag_length); if (!ok) { goto fail; } @@ -1224,22 +1378,30 @@ int psa_aead_verify_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_aead_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_aead_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, plaintext, plaintext_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + plaintext, plaintext_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, plaintext_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + plaintext_length); if (!ok) { goto fail; } @@ -1287,32 +1449,44 @@ int psa_asymmetric_decrypt_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &salt, &salt_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &salt, &salt_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &output_length); if (!ok) { goto fail; } @@ -1348,17 +1522,23 @@ int psa_asymmetric_decrypt_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1408,32 +1588,44 @@ int psa_asymmetric_encrypt_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &salt, &salt_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &salt, &salt_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &output_length); if (!ok) { goto fail; } @@ -1469,17 +1661,23 @@ int psa_asymmetric_encrypt_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1521,7 +1719,9 @@ int psa_cipher_abort_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_cipher_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -1551,12 +1751,16 @@ int psa_cipher_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1596,27 +1800,37 @@ int psa_cipher_decrypt_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &output_length); if (!ok) { goto fail; } @@ -1651,17 +1865,23 @@ int psa_cipher_decrypt_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1703,17 +1923,23 @@ int psa_cipher_decrypt_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_cipher_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } @@ -1745,12 +1971,16 @@ int psa_cipher_decrypt_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1790,27 +2020,37 @@ int psa_cipher_encrypt_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &output_length); if (!ok) { goto fail; } @@ -1845,17 +2085,23 @@ int psa_cipher_encrypt_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -1897,17 +2143,23 @@ int psa_cipher_encrypt_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_cipher_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } @@ -1939,12 +2191,16 @@ int psa_cipher_encrypt_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -1981,17 +2237,23 @@ int psa_cipher_finish_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_cipher_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &output_length); if (!ok) { goto fail; } @@ -2025,22 +2287,30 @@ int psa_cipher_finish_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -2081,17 +2351,23 @@ int psa_cipher_generate_iv_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_cipher_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &iv, &iv_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &iv, &iv_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &iv_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &iv_length); if (!ok) { goto fail; } @@ -2125,22 +2401,30 @@ int psa_cipher_generate_iv_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, iv, iv_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + iv, iv_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, iv_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + iv_length); if (!ok) { goto fail; } @@ -2180,12 +2464,16 @@ int psa_cipher_set_iv_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_cipher_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &iv, &iv_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &iv, &iv_length); if (!ok) { goto fail; } @@ -2216,12 +2504,16 @@ int psa_cipher_set_iv_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -2264,22 +2556,30 @@ int psa_cipher_update_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_cipher_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_cipher_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &output_length); if (!ok) { goto fail; } @@ -2314,22 +2614,30 @@ int psa_cipher_update_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_cipher_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_cipher_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -2371,17 +2679,23 @@ int psa_copy_key_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &source_key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &source_key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &target_key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &target_key); if (!ok) { goto fail; } @@ -2413,12 +2727,16 @@ int psa_copy_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, target_key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + target_key); if (!ok) { goto fail; } @@ -2452,7 +2770,9 @@ int psa_destroy_key_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } @@ -2481,7 +2801,9 @@ int psa_destroy_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } @@ -2518,17 +2840,23 @@ int psa_export_key_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &data, &data_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &data, &data_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &data_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &data_length); if (!ok) { goto fail; } @@ -2561,17 +2889,23 @@ int psa_export_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, data, data_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + data, data_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, data_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + data_length); if (!ok) { goto fail; } @@ -2612,17 +2946,23 @@ int psa_export_public_key_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &data, &data_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &data, &data_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &data_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &data_length); if (!ok) { goto fail; } @@ -2655,17 +2995,23 @@ int psa_export_public_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, data, data_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + data, data_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, data_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + data_length); if (!ok) { goto fail; } @@ -2704,12 +3050,16 @@ int psa_generate_key_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } @@ -2740,12 +3090,16 @@ int psa_generate_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -2782,17 +3136,23 @@ int psa_generate_key_ext_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_production_parameters_t(&pos, &remaining, ¶ms, ¶ms_data_length); + ok = psasim_deserialise_psa_key_production_parameters_t( + &pos, &remaining, + ¶ms, ¶ms_data_length); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } @@ -2824,12 +3184,16 @@ int psa_generate_key_ext_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -2868,7 +3232,9 @@ int psa_generate_random_wrapper( goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } @@ -2898,12 +3264,16 @@ int psa_generate_random_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } @@ -2942,12 +3312,16 @@ int psa_get_key_attributes_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } @@ -2978,12 +3352,16 @@ int psa_get_key_attributes_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&rpos, &rremain, attributes); + ok = psasim_serialise_psa_key_attributes_t( + &rpos, &rremain, + attributes); if (!ok) { goto fail; } @@ -3017,7 +3395,9 @@ int psa_hash_abort_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -3047,12 +3427,16 @@ int psa_hash_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3087,12 +3471,16 @@ int psa_hash_clone_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &source_operation); + ok = psasim_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &source_operation); if (!ok) { goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &target_operation); + ok = psasim_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &target_operation); if (!ok) { goto fail; } @@ -3123,12 +3511,16 @@ int psa_hash_clone_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, target_operation); + ok = psasim_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + target_operation); if (!ok) { goto fail; } @@ -3166,17 +3558,23 @@ int psa_hash_compare_wrapper( goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_length); if (!ok) { goto fail; } @@ -3207,7 +3605,9 @@ int psa_hash_compare_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } @@ -3252,22 +3652,30 @@ int psa_hash_compute_wrapper( goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &hash_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &hash_length); if (!ok) { goto fail; } @@ -3301,17 +3709,23 @@ int psa_hash_compute_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, hash, hash_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + hash, hash_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, hash_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + hash_length); if (!ok) { goto fail; } @@ -3354,17 +3768,23 @@ int psa_hash_finish_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &hash_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &hash_length); if (!ok) { goto fail; } @@ -3398,22 +3818,30 @@ int psa_hash_finish_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, hash, hash_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + hash, hash_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, hash_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + hash_length); if (!ok) { goto fail; } @@ -3452,12 +3880,16 @@ int psa_hash_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } @@ -3488,12 +3920,16 @@ int psa_hash_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3529,12 +3965,16 @@ int psa_hash_update_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } @@ -3565,12 +4005,16 @@ int psa_hash_update_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3610,12 +4054,16 @@ int psa_hash_verify_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_length); if (!ok) { goto fail; } @@ -3646,12 +4094,16 @@ int psa_hash_verify_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3692,17 +4144,23 @@ int psa_import_key_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &data, &data_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &data, &data_length); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } @@ -3734,12 +4192,16 @@ int psa_import_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -3792,7 +4254,9 @@ int psa_interruptible_get_max_ops_wrapper( goto fail; } - ok = psasim_serialise_uint32_t(&rpos, &rremain, value); + ok = psasim_serialise_uint32_t( + &rpos, &rremain, + value); if (!ok) { goto fail; } @@ -3825,7 +4289,9 @@ int psa_interruptible_set_max_ops_wrapper( goto fail; } - ok = psasim_deserialise_uint32_t(&pos, &remaining, &max_ops); + ok = psasim_deserialise_uint32_t( + &pos, &remaining, + &max_ops); if (!ok) { goto fail; } @@ -3882,7 +4348,9 @@ int psa_key_derivation_abort_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -3912,12 +4380,16 @@ int psa_key_derivation_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -3952,12 +4424,16 @@ int psa_key_derivation_get_capacity_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &capacity); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &capacity); if (!ok) { goto fail; } @@ -3988,12 +4464,16 @@ int psa_key_derivation_get_capacity_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, capacity); + ok = psasim_serialise_size_t( + &rpos, &rremain, + capacity); if (!ok) { goto fail; } @@ -4030,17 +4510,23 @@ int psa_key_derivation_input_bytes_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_step_t(&pos, &remaining, &step); + ok = psasim_deserialise_psa_key_derivation_step_t( + &pos, &remaining, + &step); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &data, &data_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &data, &data_length); if (!ok) { goto fail; } @@ -4072,12 +4558,16 @@ int psa_key_derivation_input_bytes_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4117,17 +4607,23 @@ int psa_key_derivation_input_integer_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_step_t(&pos, &remaining, &step); + ok = psasim_deserialise_psa_key_derivation_step_t( + &pos, &remaining, + &step); if (!ok) { goto fail; } - ok = psasim_deserialise_uint64_t(&pos, &remaining, &value); + ok = psasim_deserialise_uint64_t( + &pos, &remaining, + &value); if (!ok) { goto fail; } @@ -4159,12 +4655,16 @@ int psa_key_derivation_input_integer_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4200,17 +4700,23 @@ int psa_key_derivation_input_key_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_step_t(&pos, &remaining, &step); + ok = psasim_deserialise_psa_key_derivation_step_t( + &pos, &remaining, + &step); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } @@ -4242,12 +4748,16 @@ int psa_key_derivation_input_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4285,22 +4795,30 @@ int psa_key_derivation_key_agreement_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_derivation_step_t(&pos, &remaining, &step); + ok = psasim_deserialise_psa_key_derivation_step_t( + &pos, &remaining, + &step); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &private_key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &private_key); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &peer_key, &peer_key_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &peer_key, &peer_key_length); if (!ok) { goto fail; } @@ -4333,12 +4851,16 @@ int psa_key_derivation_key_agreement_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4378,12 +4900,16 @@ int psa_key_derivation_output_bytes_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_length); if (!ok) { goto fail; } @@ -4415,17 +4941,23 @@ int psa_key_derivation_output_bytes_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_length); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_length); if (!ok) { goto fail; } @@ -4465,17 +4997,23 @@ int psa_key_derivation_output_key_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } @@ -4508,17 +5046,23 @@ int psa_key_derivation_output_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -4556,22 +5100,30 @@ int psa_key_derivation_output_key_ext_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_production_parameters_t(&pos, &remaining, ¶ms, ¶ms_data_length); + ok = psasim_deserialise_psa_key_production_parameters_t( + &pos, &remaining, + ¶ms, ¶ms_data_length); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } @@ -4605,17 +5157,23 @@ int psa_key_derivation_output_key_ext_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t(&rpos, &rremain, key); + ok = psasim_serialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -4654,12 +5212,16 @@ int psa_key_derivation_set_capacity_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &capacity); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &capacity); if (!ok) { goto fail; } @@ -4690,12 +5252,16 @@ int psa_key_derivation_set_capacity_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4730,12 +5296,16 @@ int psa_key_derivation_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_key_derivation_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_key_derivation_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } @@ -4766,12 +5336,16 @@ int psa_key_derivation_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_key_derivation_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_key_derivation_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4805,7 +5379,9 @@ int psa_mac_abort_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_mac_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -4835,12 +5411,16 @@ int psa_mac_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -4880,27 +5460,37 @@ int psa_mac_compute_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &mac, &mac_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &mac, &mac_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &mac_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &mac_length); if (!ok) { goto fail; } @@ -4935,17 +5525,23 @@ int psa_mac_compute_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, mac, mac_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + mac, mac_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, mac_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + mac_length); if (!ok) { goto fail; } @@ -4988,17 +5584,23 @@ int psa_mac_sign_finish_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_mac_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &mac, &mac_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &mac, &mac_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &mac_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &mac_length); if (!ok) { goto fail; } @@ -5032,22 +5634,30 @@ int psa_mac_sign_finish_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, mac, mac_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + mac, mac_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, mac_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + mac_length); if (!ok) { goto fail; } @@ -5087,17 +5697,23 @@ int psa_mac_sign_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_mac_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } @@ -5129,12 +5745,16 @@ int psa_mac_sign_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5170,12 +5790,16 @@ int psa_mac_update_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_mac_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } @@ -5206,12 +5830,16 @@ int psa_mac_update_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5254,22 +5882,30 @@ int psa_mac_verify_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &mac, &mac_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &mac, &mac_length); if (!ok) { goto fail; } @@ -5301,7 +5937,9 @@ int psa_mac_verify_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } @@ -5343,12 +5981,16 @@ int psa_mac_verify_finish_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_mac_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &mac, &mac_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &mac, &mac_length); if (!ok) { goto fail; } @@ -5379,12 +6021,16 @@ int psa_mac_verify_finish_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5424,17 +6070,23 @@ int psa_mac_verify_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_mac_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_mac_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } @@ -5466,12 +6118,16 @@ int psa_mac_verify_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_mac_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_mac_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5505,7 +6161,9 @@ int psa_purge_key_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } @@ -5534,7 +6192,9 @@ int psa_purge_key_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } @@ -5574,27 +6234,37 @@ int psa_raw_key_agreement_wrapper( goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &private_key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &private_key); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &peer_key, &peer_key_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &peer_key, &peer_key_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &output, &output_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &output, &output_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &output_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &output_length); if (!ok) { goto fail; } @@ -5629,17 +6299,23 @@ int psa_raw_key_agreement_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, output, output_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, output_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + output_length); if (!ok) { goto fail; } @@ -5678,7 +6354,9 @@ int psa_reset_key_attributes_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes); + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } @@ -5691,7 +6369,7 @@ int psa_reset_key_attributes_wrapper( // NOTE: Should really check there is no overflow as we go along. size_t result_size = - psasim_serialise_begin_needs(); + psasim_serialise_begin_needs() + psasim_serialise_psa_key_attributes_t_needs(attributes); result = malloc(result_size); @@ -5707,7 +6385,9 @@ int psa_reset_key_attributes_wrapper( goto fail; } - ok = psasim_serialise_psa_key_attributes_t(&rpos, &rremain, attributes); + ok = psasim_serialise_psa_key_attributes_t( + &rpos, &rremain, + attributes); if (!ok) { goto fail; } @@ -5747,27 +6427,37 @@ int psa_sign_hash_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &signature, &signature_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &signature_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &signature_length); if (!ok) { goto fail; } @@ -5802,17 +6492,23 @@ int psa_sign_hash_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, signature, signature_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, signature_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + signature_length); if (!ok) { goto fail; } @@ -5852,7 +6548,9 @@ int psa_sign_hash_abort_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -5882,12 +6580,16 @@ int psa_sign_hash_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -5924,17 +6626,23 @@ int psa_sign_hash_complete_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &signature, &signature_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &signature_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &signature_length); if (!ok) { goto fail; } @@ -5968,22 +6676,30 @@ int psa_sign_hash_complete_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, signature, signature_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, signature_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + signature_length); if (!ok) { goto fail; } @@ -6021,7 +6737,9 @@ int psa_sign_hash_get_num_ops_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -6050,7 +6768,9 @@ int psa_sign_hash_get_num_ops_wrapper( goto fail; } - ok = psasim_serialise_uint32_t(&rpos, &rremain, value); + ok = psasim_serialise_uint32_t( + &rpos, &rremain, + value); if (!ok) { goto fail; } @@ -6088,22 +6808,30 @@ int psa_sign_hash_start_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_sign_hash_interruptible_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_length); if (!ok) { goto fail; } @@ -6136,12 +6864,16 @@ int psa_sign_hash_start_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -6185,27 +6917,37 @@ int psa_sign_message_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_size); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &signature, &signature_size); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t(&pos, &remaining, &signature_length); + ok = psasim_deserialise_size_t( + &pos, &remaining, + &signature_length); if (!ok) { goto fail; } @@ -6240,17 +6982,23 @@ int psa_sign_message_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_serialise_buffer(&rpos, &rremain, signature, signature_size); + ok = psasim_serialise_buffer( + &rpos, &rremain, + signature, signature_size); if (!ok) { goto fail; } - ok = psasim_serialise_size_t(&rpos, &rremain, signature_length); + ok = psasim_serialise_size_t( + &rpos, &rremain, + signature_length); if (!ok) { goto fail; } @@ -6295,22 +7043,30 @@ int psa_verify_hash_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &signature, &signature_length); if (!ok) { goto fail; } @@ -6342,7 +7098,9 @@ int psa_verify_hash_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } @@ -6382,7 +7140,9 @@ int psa_verify_hash_abort_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_verify_hash_interruptible_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -6412,12 +7172,16 @@ int psa_verify_hash_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -6451,7 +7215,9 @@ int psa_verify_hash_complete_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_verify_hash_interruptible_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -6481,12 +7247,16 @@ int psa_verify_hash_complete_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -6520,7 +7290,9 @@ int psa_verify_hash_get_num_ops_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_verify_hash_interruptible_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } @@ -6549,7 +7321,9 @@ int psa_verify_hash_get_num_ops_wrapper( goto fail; } - ok = psasim_serialise_uint32_t(&rpos, &rremain, value); + ok = psasim_serialise_uint32_t( + &rpos, &rremain, + value); if (!ok) { goto fail; } @@ -6589,27 +7363,37 @@ int psa_verify_hash_start_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_verify_hash_interruptible_operation_t(&pos, &remaining, &operation); + ok = psasim_server_deserialise_psa_verify_hash_interruptible_operation_t( + &pos, &remaining, + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &hash, &hash_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &signature, &signature_length); if (!ok) { goto fail; } @@ -6643,12 +7427,16 @@ int psa_verify_hash_start_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t(&rpos, &rremain, operation); + ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t( + &rpos, &rremain, + operation); if (!ok) { goto fail; } @@ -6693,22 +7481,30 @@ int psa_verify_message_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t(&pos, &remaining, &key); + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_algorithm_t(&pos, &remaining, &alg); + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &input, &input_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer(&pos, &remaining, &signature, &signature_length); + ok = psasim_deserialise_buffer( + &pos, &remaining, + &signature, &signature_length); if (!ok) { goto fail; } @@ -6740,7 +7536,9 @@ int psa_verify_message_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t(&rpos, &rremain, status); + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); if (!ok) { goto fail; } diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index a0ee76a801..ac238070c3 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -606,7 +606,9 @@ sub output_server_wrapper my ($n1, $n2) = split(/,\s*/, $argname); print $fh <{is_output}, @$args); - my $sep1 = ($ret_type eq "void") ? ";" : " +"; + my $sep1 = (($ret_type eq "void") and ($#outputs < 0)) ? ";" : " +"; print $fh <{args}; @@ -803,12 +818,12 @@ sub output_client $argtype =~ s/^const //; print $fh <[$i]; diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 84e233955b..e655e078f3 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -63,8 +63,10 @@ typedef struct psasim_operation_s { #define MAX_LIVE_HANDLES_PER_CLASS 100 /* this many slots */ -static psa_hash_operation_t hash_operations[MAX_LIVE_HANDLES_PER_CLASS]; -static psasim_client_handle_t hash_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psa_hash_operation_t hash_operations[ + MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t hash_operation_handles[ + MAX_LIVE_HANDLES_PER_CLASS]; static psasim_client_handle_t next_hash_operation_handle = 1; /* Get a free slot */ @@ -101,8 +103,10 @@ static ssize_t find_hash_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } -static psa_aead_operation_t aead_operations[MAX_LIVE_HANDLES_PER_CLASS]; -static psasim_client_handle_t aead_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psa_aead_operation_t aead_operations[ + MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t aead_operation_handles[ + MAX_LIVE_HANDLES_PER_CLASS]; static psasim_client_handle_t next_aead_operation_handle = 1; /* Get a free slot */ @@ -139,8 +143,10 @@ static ssize_t find_aead_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } -static psa_mac_operation_t mac_operations[MAX_LIVE_HANDLES_PER_CLASS]; -static psasim_client_handle_t mac_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psa_mac_operation_t mac_operations[ + MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t mac_operation_handles[ + MAX_LIVE_HANDLES_PER_CLASS]; static psasim_client_handle_t next_mac_operation_handle = 1; /* Get a free slot */ @@ -177,8 +183,10 @@ static ssize_t find_mac_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } -static psa_cipher_operation_t cipher_operations[MAX_LIVE_HANDLES_PER_CLASS]; -static psasim_client_handle_t cipher_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psa_cipher_operation_t cipher_operations[ + MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t cipher_operation_handles[ + MAX_LIVE_HANDLES_PER_CLASS]; static psasim_client_handle_t next_cipher_operation_handle = 1; /* Get a free slot */ @@ -215,8 +223,10 @@ static ssize_t find_cipher_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } -static psa_key_derivation_operation_t key_derivation_operations[MAX_LIVE_HANDLES_PER_CLASS]; -static psasim_client_handle_t key_derivation_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psa_key_derivation_operation_t key_derivation_operations[ + MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t key_derivation_operation_handles[ + MAX_LIVE_HANDLES_PER_CLASS]; static psasim_client_handle_t next_key_derivation_operation_handle = 1; /* Get a free slot */ @@ -253,8 +263,10 @@ static ssize_t find_key_derivation_slot_by_handle(psasim_client_handle_t handle) return -1; /* not found */ } -static psa_sign_hash_interruptible_operation_t sign_hash_interruptible_operations[MAX_LIVE_HANDLES_PER_CLASS]; -static psasim_client_handle_t sign_hash_interruptible_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psa_sign_hash_interruptible_operation_t sign_hash_interruptible_operations[ + MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t sign_hash_interruptible_operation_handles[ + MAX_LIVE_HANDLES_PER_CLASS]; static psasim_client_handle_t next_sign_hash_interruptible_operation_handle = 1; /* Get a free slot */ @@ -291,8 +303,10 @@ static ssize_t find_sign_hash_interruptible_slot_by_handle(psasim_client_handle_ return -1; /* not found */ } -static psa_verify_hash_interruptible_operation_t verify_hash_interruptible_operations[MAX_LIVE_HANDLES_PER_CLASS]; -static psasim_client_handle_t verify_hash_interruptible_operation_handles[MAX_LIVE_HANDLES_PER_CLASS]; +static psa_verify_hash_interruptible_operation_t verify_hash_interruptible_operations[ + MAX_LIVE_HANDLES_PER_CLASS]; +static psasim_client_handle_t verify_hash_interruptible_operation_handles[ + MAX_LIVE_HANDLES_PER_CLASS]; static psasim_client_handle_t next_verify_hash_interruptible_operation_handle = 1; /* Get a free slot */ @@ -403,7 +417,8 @@ int psasim_deserialise_begin(uint8_t **pos, size_t *remaining) return 1; } -size_t psasim_serialise_unsigned_int_needs(unsigned int value) +size_t psasim_serialise_unsigned_int_needs( + unsigned int value) { return sizeof(value); } @@ -438,7 +453,8 @@ int psasim_deserialise_unsigned_int(uint8_t **pos, return 1; } -size_t psasim_serialise_int_needs(int value) +size_t psasim_serialise_int_needs( + int value) { return sizeof(value); } @@ -473,7 +489,8 @@ int psasim_deserialise_int(uint8_t **pos, return 1; } -size_t psasim_serialise_size_t_needs(size_t value) +size_t psasim_serialise_size_t_needs( + size_t value) { return sizeof(value); } @@ -508,7 +525,8 @@ int psasim_deserialise_size_t(uint8_t **pos, return 1; } -size_t psasim_serialise_uint16_t_needs(uint16_t value) +size_t psasim_serialise_uint16_t_needs( + uint16_t value) { return sizeof(value); } @@ -543,7 +561,8 @@ int psasim_deserialise_uint16_t(uint8_t **pos, return 1; } -size_t psasim_serialise_uint32_t_needs(uint32_t value) +size_t psasim_serialise_uint32_t_needs( + uint32_t value) { return sizeof(value); } @@ -578,7 +597,8 @@ int psasim_deserialise_uint32_t(uint8_t **pos, return 1; } -size_t psasim_serialise_uint64_t_needs(uint64_t value) +size_t psasim_serialise_uint64_t_needs( + uint64_t value) { return sizeof(value); } @@ -784,7 +804,7 @@ int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, } memcpy(data_length, *pos, sizeof(*data_length)); - if ((size_t)len != (sizeof(data_length) + sizeof(**params) + *data_length)) { + if ((size_t) len != (sizeof(data_length) + sizeof(**params) + *data_length)) { return 0; /* wrong length */ } @@ -809,7 +829,8 @@ int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, return 1; } -size_t psasim_serialise_psa_status_t_needs(psa_status_t value) +size_t psasim_serialise_psa_status_t_needs( + psa_status_t value) { return psasim_serialise_int_needs(value); } @@ -828,7 +849,8 @@ int psasim_deserialise_psa_status_t(uint8_t **pos, return psasim_deserialise_int(pos, remaining, value); } -size_t psasim_serialise_psa_algorithm_t_needs(psa_algorithm_t value) +size_t psasim_serialise_psa_algorithm_t_needs( + psa_algorithm_t value) { return psasim_serialise_unsigned_int_needs(value); } @@ -847,7 +869,8 @@ int psasim_deserialise_psa_algorithm_t(uint8_t **pos, return psasim_deserialise_unsigned_int(pos, remaining, value); } -size_t psasim_serialise_psa_key_derivation_step_t_needs(psa_key_derivation_step_t value) +size_t psasim_serialise_psa_key_derivation_step_t_needs( + psa_key_derivation_step_t value) { return psasim_serialise_uint16_t_needs(value); } @@ -866,7 +889,8 @@ int psasim_deserialise_psa_key_derivation_step_t(uint8_t **pos, return psasim_deserialise_uint16_t(pos, remaining, value); } -size_t psasim_serialise_psa_hash_operation_t_needs(psa_hash_operation_t value) +size_t psasim_serialise_psa_hash_operation_t_needs( + psa_hash_operation_t value) { return sizeof(value); } @@ -901,7 +925,8 @@ int psasim_deserialise_psa_hash_operation_t(uint8_t **pos, return 1; } -size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *operation) +size_t psasim_server_serialise_psa_hash_operation_t_needs( + psa_hash_operation_t *operation) { (void) operation; @@ -959,7 +984,8 @@ int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos, return 1; } -size_t psasim_serialise_psa_aead_operation_t_needs(psa_aead_operation_t value) +size_t psasim_serialise_psa_aead_operation_t_needs( + psa_aead_operation_t value) { return sizeof(value); } @@ -994,7 +1020,8 @@ int psasim_deserialise_psa_aead_operation_t(uint8_t **pos, return 1; } -size_t psasim_server_serialise_psa_aead_operation_t_needs(psa_aead_operation_t *operation) +size_t psasim_server_serialise_psa_aead_operation_t_needs( + psa_aead_operation_t *operation) { (void) operation; @@ -1052,7 +1079,8 @@ int psasim_server_deserialise_psa_aead_operation_t(uint8_t **pos, return 1; } -size_t psasim_serialise_psa_key_attributes_t_needs(psa_key_attributes_t value) +size_t psasim_serialise_psa_key_attributes_t_needs( + psa_key_attributes_t value) { return sizeof(value); } @@ -1087,7 +1115,8 @@ int psasim_deserialise_psa_key_attributes_t(uint8_t **pos, return 1; } -size_t psasim_serialise_psa_mac_operation_t_needs(psa_mac_operation_t value) +size_t psasim_serialise_psa_mac_operation_t_needs( + psa_mac_operation_t value) { return sizeof(value); } @@ -1122,7 +1151,8 @@ int psasim_deserialise_psa_mac_operation_t(uint8_t **pos, return 1; } -size_t psasim_server_serialise_psa_mac_operation_t_needs(psa_mac_operation_t *operation) +size_t psasim_server_serialise_psa_mac_operation_t_needs( + psa_mac_operation_t *operation) { (void) operation; @@ -1180,7 +1210,8 @@ int psasim_server_deserialise_psa_mac_operation_t(uint8_t **pos, return 1; } -size_t psasim_serialise_psa_cipher_operation_t_needs(psa_cipher_operation_t value) +size_t psasim_serialise_psa_cipher_operation_t_needs( + psa_cipher_operation_t value) { return sizeof(value); } @@ -1215,7 +1246,8 @@ int psasim_deserialise_psa_cipher_operation_t(uint8_t **pos, return 1; } -size_t psasim_server_serialise_psa_cipher_operation_t_needs(psa_cipher_operation_t *operation) +size_t psasim_server_serialise_psa_cipher_operation_t_needs( + psa_cipher_operation_t *operation) { (void) operation; @@ -1273,7 +1305,8 @@ int psasim_server_deserialise_psa_cipher_operation_t(uint8_t **pos, return 1; } -size_t psasim_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t value) +size_t psasim_serialise_psa_key_derivation_operation_t_needs( + psa_key_derivation_operation_t value) { return sizeof(value); } @@ -1308,7 +1341,8 @@ int psasim_deserialise_psa_key_derivation_operation_t(uint8_t **pos, return 1; } -size_t psasim_server_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t *operation) +size_t psasim_server_serialise_psa_key_derivation_operation_t_needs( + psa_key_derivation_operation_t *operation) { (void) operation; @@ -1366,7 +1400,8 @@ int psasim_server_deserialise_psa_key_derivation_operation_t(uint8_t **pos, return 1; } -size_t psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(psa_sign_hash_interruptible_operation_t value) +size_t psasim_serialise_psa_sign_hash_interruptible_operation_t_needs( + psa_sign_hash_interruptible_operation_t value) { return sizeof(value); } @@ -1401,7 +1436,8 @@ int psasim_deserialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, return 1; } -size_t psasim_server_serialise_psa_sign_hash_interruptible_operation_t_needs(psa_sign_hash_interruptible_operation_t *operation) +size_t psasim_server_serialise_psa_sign_hash_interruptible_operation_t_needs( + psa_sign_hash_interruptible_operation_t *operation) { (void) operation; @@ -1459,7 +1495,8 @@ int psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(uint8_t ** return 1; } -size_t psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(psa_verify_hash_interruptible_operation_t value) +size_t psasim_serialise_psa_verify_hash_interruptible_operation_t_needs( + psa_verify_hash_interruptible_operation_t value) { return sizeof(value); } @@ -1494,7 +1531,8 @@ int psasim_deserialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, return 1; } -size_t psasim_server_serialise_psa_verify_hash_interruptible_operation_t_needs(psa_verify_hash_interruptible_operation_t *operation) +size_t psasim_server_serialise_psa_verify_hash_interruptible_operation_t_needs( + psa_verify_hash_interruptible_operation_t *operation) { (void) operation; @@ -1552,7 +1590,8 @@ int psasim_server_deserialise_psa_verify_hash_interruptible_operation_t(uint8_t return 1; } -size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value) +size_t psasim_serialise_mbedtls_svc_key_id_t_needs( + mbedtls_svc_key_id_t value) { return sizeof(value); } @@ -1589,18 +1628,32 @@ int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, void psa_sim_serialize_reset(void) { - memset(hash_operation_handles, 0, sizeof(hash_operation_handles)); - memset(hash_operations, 0, sizeof(hash_operations)); - memset(aead_operation_handles, 0, sizeof(aead_operation_handles)); - memset(aead_operations, 0, sizeof(aead_operations)); - memset(mac_operation_handles, 0, sizeof(mac_operation_handles)); - memset(mac_operations, 0, sizeof(mac_operations)); - memset(cipher_operation_handles, 0, sizeof(cipher_operation_handles)); - memset(cipher_operations, 0, sizeof(cipher_operations)); - memset(key_derivation_operation_handles, 0, sizeof(key_derivation_operation_handles)); - memset(key_derivation_operations, 0, sizeof(key_derivation_operations)); - memset(sign_hash_interruptible_operation_handles, 0, sizeof(sign_hash_interruptible_operation_handles)); - memset(sign_hash_interruptible_operations, 0, sizeof(sign_hash_interruptible_operations)); - memset(verify_hash_interruptible_operation_handles, 0, sizeof(verify_hash_interruptible_operation_handles)); - memset(verify_hash_interruptible_operations, 0, sizeof(verify_hash_interruptible_operations)); + memset(hash_operation_handles, 0, + sizeof(hash_operation_handles)); + memset(hash_operations, 0, + sizeof(hash_operations)); + memset(aead_operation_handles, 0, + sizeof(aead_operation_handles)); + memset(aead_operations, 0, + sizeof(aead_operations)); + memset(mac_operation_handles, 0, + sizeof(mac_operation_handles)); + memset(mac_operations, 0, + sizeof(mac_operations)); + memset(cipher_operation_handles, 0, + sizeof(cipher_operation_handles)); + memset(cipher_operations, 0, + sizeof(cipher_operations)); + memset(key_derivation_operation_handles, 0, + sizeof(key_derivation_operation_handles)); + memset(key_derivation_operations, 0, + sizeof(key_derivation_operations)); + memset(sign_hash_interruptible_operation_handles, 0, + sizeof(sign_hash_interruptible_operation_handles)); + memset(sign_hash_interruptible_operations, 0, + sizeof(sign_hash_interruptible_operations)); + memset(verify_hash_interruptible_operation_handles, 0, + sizeof(verify_hash_interruptible_operation_handles)); + memset(verify_hash_interruptible_operations, 0, + sizeof(verify_hash_interruptible_operations)); } diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 4bd7fe954e..f85faad606 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -107,7 +107,8 @@ int psasim_deserialise_begin(uint8_t **pos, size_t *remaining); * \c psasim_serialise_unsigned_int() to serialise * the given value. */ -size_t psasim_serialise_unsigned_int_needs(unsigned int value); +size_t psasim_serialise_unsigned_int_needs( + unsigned int value); /** Serialise an `unsigned int` into a buffer. * @@ -149,7 +150,8 @@ int psasim_deserialise_unsigned_int(uint8_t **pos, * \c psasim_serialise_int() to serialise * the given value. */ -size_t psasim_serialise_int_needs(int value); +size_t psasim_serialise_int_needs( + int value); /** Serialise an `int` into a buffer. * @@ -191,7 +193,8 @@ int psasim_deserialise_int(uint8_t **pos, * \c psasim_serialise_size_t() to serialise * the given value. */ -size_t psasim_serialise_size_t_needs(size_t value); +size_t psasim_serialise_size_t_needs( + size_t value); /** Serialise a `size_t` into a buffer. * @@ -233,7 +236,8 @@ int psasim_deserialise_size_t(uint8_t **pos, * \c psasim_serialise_uint16_t() to serialise * the given value. */ -size_t psasim_serialise_uint16_t_needs(uint16_t value); +size_t psasim_serialise_uint16_t_needs( + uint16_t value); /** Serialise an `uint16_t` into a buffer. * @@ -275,7 +279,8 @@ int psasim_deserialise_uint16_t(uint8_t **pos, * \c psasim_serialise_uint32_t() to serialise * the given value. */ -size_t psasim_serialise_uint32_t_needs(uint32_t value); +size_t psasim_serialise_uint32_t_needs( + uint32_t value); /** Serialise an `uint32_t` into a buffer. * @@ -317,7 +322,8 @@ int psasim_deserialise_uint32_t(uint8_t **pos, * \c psasim_serialise_uint64_t() to serialise * the given value. */ -size_t psasim_serialise_uint64_t_needs(uint64_t value); +size_t psasim_serialise_uint64_t_needs( + uint64_t value); /** Serialise an `uint64_t` into a buffer. * @@ -476,7 +482,8 @@ int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, size_t *re * \c psasim_serialise_psa_status_t() to serialise * the given value. */ -size_t psasim_serialise_psa_status_t_needs(psa_status_t value); +size_t psasim_serialise_psa_status_t_needs( + psa_status_t value); /** Serialise a `psa_status_t` into a buffer. * @@ -518,7 +525,8 @@ int psasim_deserialise_psa_status_t(uint8_t **pos, * \c psasim_serialise_psa_algorithm_t() to serialise * the given value. */ -size_t psasim_serialise_psa_algorithm_t_needs(psa_algorithm_t value); +size_t psasim_serialise_psa_algorithm_t_needs( + psa_algorithm_t value); /** Serialise a `psa_algorithm_t` into a buffer. * @@ -560,7 +568,8 @@ int psasim_deserialise_psa_algorithm_t(uint8_t **pos, * \c psasim_serialise_psa_key_derivation_step_t() to serialise * the given value. */ -size_t psasim_serialise_psa_key_derivation_step_t_needs(psa_key_derivation_step_t value); +size_t psasim_serialise_psa_key_derivation_step_t_needs( + psa_key_derivation_step_t value); /** Serialise a `psa_key_derivation_step_t` into a buffer. * @@ -602,7 +611,8 @@ int psasim_deserialise_psa_key_derivation_step_t(uint8_t **pos, * \c psasim_serialise_psa_hash_operation_t() to serialise * the given value. */ -size_t psasim_serialise_psa_hash_operation_t_needs(psa_hash_operation_t value); +size_t psasim_serialise_psa_hash_operation_t_needs( + psa_hash_operation_t value); /** Serialise a `psa_hash_operation_t` into a buffer. * @@ -644,7 +654,8 @@ int psasim_deserialise_psa_hash_operation_t(uint8_t **pos, * \c psasim_serialise_psa_hash_operation_t() to serialise * the given value. */ -size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *value); +size_t psasim_server_serialise_psa_hash_operation_t_needs( + psa_hash_operation_t *value); /** Serialise a `psa_hash_operation_t` into a buffer on the server side. * @@ -686,7 +697,8 @@ int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos, * \c psasim_serialise_psa_aead_operation_t() to serialise * the given value. */ -size_t psasim_serialise_psa_aead_operation_t_needs(psa_aead_operation_t value); +size_t psasim_serialise_psa_aead_operation_t_needs( + psa_aead_operation_t value); /** Serialise a `psa_aead_operation_t` into a buffer. * @@ -728,7 +740,8 @@ int psasim_deserialise_psa_aead_operation_t(uint8_t **pos, * \c psasim_serialise_psa_aead_operation_t() to serialise * the given value. */ -size_t psasim_server_serialise_psa_aead_operation_t_needs(psa_aead_operation_t *value); +size_t psasim_server_serialise_psa_aead_operation_t_needs( + psa_aead_operation_t *value); /** Serialise a `psa_aead_operation_t` into a buffer on the server side. * @@ -770,7 +783,8 @@ int psasim_server_deserialise_psa_aead_operation_t(uint8_t **pos, * \c psasim_serialise_psa_key_attributes_t() to serialise * the given value. */ -size_t psasim_serialise_psa_key_attributes_t_needs(psa_key_attributes_t value); +size_t psasim_serialise_psa_key_attributes_t_needs( + psa_key_attributes_t value); /** Serialise a `psa_key_attributes_t` into a buffer. * @@ -812,7 +826,8 @@ int psasim_deserialise_psa_key_attributes_t(uint8_t **pos, * \c psasim_serialise_psa_mac_operation_t() to serialise * the given value. */ -size_t psasim_serialise_psa_mac_operation_t_needs(psa_mac_operation_t value); +size_t psasim_serialise_psa_mac_operation_t_needs( + psa_mac_operation_t value); /** Serialise a `psa_mac_operation_t` into a buffer. * @@ -854,7 +869,8 @@ int psasim_deserialise_psa_mac_operation_t(uint8_t **pos, * \c psasim_serialise_psa_mac_operation_t() to serialise * the given value. */ -size_t psasim_server_serialise_psa_mac_operation_t_needs(psa_mac_operation_t *value); +size_t psasim_server_serialise_psa_mac_operation_t_needs( + psa_mac_operation_t *value); /** Serialise a `psa_mac_operation_t` into a buffer on the server side. * @@ -896,7 +912,8 @@ int psasim_server_deserialise_psa_mac_operation_t(uint8_t **pos, * \c psasim_serialise_psa_cipher_operation_t() to serialise * the given value. */ -size_t psasim_serialise_psa_cipher_operation_t_needs(psa_cipher_operation_t value); +size_t psasim_serialise_psa_cipher_operation_t_needs( + psa_cipher_operation_t value); /** Serialise a `psa_cipher_operation_t` into a buffer. * @@ -938,7 +955,8 @@ int psasim_deserialise_psa_cipher_operation_t(uint8_t **pos, * \c psasim_serialise_psa_cipher_operation_t() to serialise * the given value. */ -size_t psasim_server_serialise_psa_cipher_operation_t_needs(psa_cipher_operation_t *value); +size_t psasim_server_serialise_psa_cipher_operation_t_needs( + psa_cipher_operation_t *value); /** Serialise a `psa_cipher_operation_t` into a buffer on the server side. * @@ -980,7 +998,8 @@ int psasim_server_deserialise_psa_cipher_operation_t(uint8_t **pos, * \c psasim_serialise_psa_key_derivation_operation_t() to serialise * the given value. */ -size_t psasim_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t value); +size_t psasim_serialise_psa_key_derivation_operation_t_needs( + psa_key_derivation_operation_t value); /** Serialise a `psa_key_derivation_operation_t` into a buffer. * @@ -1022,7 +1041,8 @@ int psasim_deserialise_psa_key_derivation_operation_t(uint8_t **pos, * \c psasim_serialise_psa_key_derivation_operation_t() to serialise * the given value. */ -size_t psasim_server_serialise_psa_key_derivation_operation_t_needs(psa_key_derivation_operation_t *value); +size_t psasim_server_serialise_psa_key_derivation_operation_t_needs( + psa_key_derivation_operation_t *value); /** Serialise a `psa_key_derivation_operation_t` into a buffer on the server side. * @@ -1064,7 +1084,8 @@ int psasim_server_deserialise_psa_key_derivation_operation_t(uint8_t **pos, * \c psasim_serialise_psa_sign_hash_interruptible_operation_t() to serialise * the given value. */ -size_t psasim_serialise_psa_sign_hash_interruptible_operation_t_needs(psa_sign_hash_interruptible_operation_t value); +size_t psasim_serialise_psa_sign_hash_interruptible_operation_t_needs( + psa_sign_hash_interruptible_operation_t value); /** Serialise a `psa_sign_hash_interruptible_operation_t` into a buffer. * @@ -1106,7 +1127,8 @@ int psasim_deserialise_psa_sign_hash_interruptible_operation_t(uint8_t **pos, * \c psasim_serialise_psa_sign_hash_interruptible_operation_t() to serialise * the given value. */ -size_t psasim_server_serialise_psa_sign_hash_interruptible_operation_t_needs(psa_sign_hash_interruptible_operation_t *value); +size_t psasim_server_serialise_psa_sign_hash_interruptible_operation_t_needs( + psa_sign_hash_interruptible_operation_t *value); /** Serialise a `psa_sign_hash_interruptible_operation_t` into a buffer on the server side. * @@ -1148,7 +1170,8 @@ int psasim_server_deserialise_psa_sign_hash_interruptible_operation_t(uint8_t ** * \c psasim_serialise_psa_verify_hash_interruptible_operation_t() to serialise * the given value. */ -size_t psasim_serialise_psa_verify_hash_interruptible_operation_t_needs(psa_verify_hash_interruptible_operation_t value); +size_t psasim_serialise_psa_verify_hash_interruptible_operation_t_needs( + psa_verify_hash_interruptible_operation_t value); /** Serialise a `psa_verify_hash_interruptible_operation_t` into a buffer. * @@ -1190,7 +1213,8 @@ int psasim_deserialise_psa_verify_hash_interruptible_operation_t(uint8_t **pos, * \c psasim_serialise_psa_verify_hash_interruptible_operation_t() to serialise * the given value. */ -size_t psasim_server_serialise_psa_verify_hash_interruptible_operation_t_needs(psa_verify_hash_interruptible_operation_t *value); +size_t psasim_server_serialise_psa_verify_hash_interruptible_operation_t_needs( + psa_verify_hash_interruptible_operation_t *value); /** Serialise a `psa_verify_hash_interruptible_operation_t` into a buffer on the server side. * @@ -1232,7 +1256,8 @@ int psasim_server_deserialise_psa_verify_hash_interruptible_operation_t(uint8_t * \c psasim_serialise_mbedtls_svc_key_id_t() to serialise * the given value. */ -size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value); +size_t psasim_serialise_mbedtls_svc_key_id_t_needs( + mbedtls_svc_key_id_t value); /** Serialise a `mbedtls_svc_key_id_t` into a buffer. * diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index ed5dd9a25b..81808caffc 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -145,7 +145,8 @@ sub declare_needs * \\c psasim_serialise_$type_d() to serialise * the given value. */ -size_t psasim_${server}serialise_${type_d}_needs($type ${ptr}value); +size_t psasim_${server}serialise_${type_d}_needs( + $type ${ptr}value); EOF } @@ -451,7 +452,8 @@ sub define_needs return < Date: Fri, 14 Jun 2024 08:43:28 +0200 Subject: [PATCH 080/125] Adjust build systems Adjust build systems such as we can built Mbed TLS in the default and full configuration. Signed-off-by: Ronald Cron --- psasim/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/psasim/Makefile b/psasim/Makefile index 4b0c46e47c..02b639f2c4 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -8,7 +8,9 @@ LIBPSACLIENT := -Llibpsaclient/ -lmbedcrypto -lmbedx509 -lmbedtls LIBPSASERVER := -Llibpsaserver/ -lmbedcrypto MBEDTLS_ROOT_PATH = ../../.. -COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include +COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include \ + -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include \ + -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include GENERATED_H_FILES = include/psa_manifest/manifest.h \ include/psa_manifest/pid.h \ From 0185147d77ff659081de0c5244318272cd760d86 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 27 Jun 2024 18:14:43 +0200 Subject: [PATCH 081/125] psasim: minor fixes to the core - do not try to close a connection that was never started - fix data chunks length for psa_write (prevent memcpy-ing to large blocks of data) Signed-off-by: Valerio Setti --- psasim/src/psa_ff_server.c | 2 +- psasim/src/psa_sim_crypto_client.c | 7 ++++++- psasim/src/psa_sim_generate.pl | 7 ++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index 7f97b9bf0f..b0737ec840 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -474,7 +474,7 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, while (sofar < num_bytes) { size_t sending = (num_bytes - sofar); - if (sending >= MAX_FRAGMENT_SIZE) { + if (sending > (MAX_FRAGMENT_SIZE - (sizeof(size_t) * 2))) { sending = MAX_FRAGMENT_SIZE - (sizeof(size_t) * 2); } diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 28dff38d02..4200f6c04d 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -44,7 +44,7 @@ int psa_crypto_call(int function, invec.base = in_params; invec.len = in_params_len; - size_t max_receive = 8192; + size_t max_receive = 24576; uint8_t *receive = malloc(max_receive); if (receive == NULL) { fprintf(stderr, "FAILED to allocate %u bytes\n", (unsigned) max_receive); @@ -119,6 +119,11 @@ psa_status_t psa_crypto_init(void) void mbedtls_psa_crypto_free(void) { + /* Do not try to close a connection that was never started.*/ + if (handle == -1) { + return; + } + CLIENT_PRINT("Closing handle"); psa_close(handle); handle = -1; diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index ac238070c3..ac7b2419c7 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -349,7 +349,7 @@ sub client_calls_header invec.base = in_params; invec.len = in_params_len; - size_t max_receive = 8192; + size_t max_receive = 24576; uint8_t *receive = malloc(max_receive); if (receive == NULL) { fprintf(stderr, "FAILED to allocate %u bytes\n", (unsigned) max_receive); @@ -424,6 +424,11 @@ sub client_calls_header void mbedtls_psa_crypto_free(void) { + /* Do not try to close a connection that was never started.*/ + if (handle == -1) { + return; + } + CLIENT_PRINT("Closing handle"); psa_close(handle); handle = -1; From 4312abcc5ad7a5e765b47be908a67ca11c78d631 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Sat, 29 Jun 2024 16:10:21 +0100 Subject: [PATCH 082/125] psasim: invalidate operations on abort+finish Signed-off-by: Tom Cosgrove --- psasim/src/psa_sim_crypto_server.c | 90 +++++++++++++++--------------- psasim/src/psa_sim_generate.pl | 10 +++- psasim/src/psa_sim_serialise.c | 70 ++++++++++++++++++++--- psasim/src/psa_sim_serialise.h | 35 +++++++++--- psasim/src/psa_sim_serialise.pl | 56 +++++++++++++++---- 5 files changed, 190 insertions(+), 71 deletions(-) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 52597516cf..cab32c47c1 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -131,7 +131,7 @@ int psa_aead_abort_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -375,7 +375,7 @@ int psa_aead_decrypt_setup_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -619,7 +619,7 @@ int psa_aead_encrypt_setup_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -736,7 +736,7 @@ int psa_aead_finish_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -866,7 +866,7 @@ int psa_aead_generate_nonce_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -977,7 +977,7 @@ int psa_aead_set_lengths_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -1062,7 +1062,7 @@ int psa_aead_set_nonce_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -1172,7 +1172,7 @@ int psa_aead_update_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -1277,7 +1277,7 @@ int psa_aead_update_ad_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -1387,7 +1387,7 @@ int psa_aead_verify_wrapper( ok = psasim_server_serialise_psa_aead_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -1760,7 +1760,7 @@ int psa_cipher_abort_wrapper( ok = psasim_server_serialise_psa_cipher_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -1980,7 +1980,7 @@ int psa_cipher_decrypt_setup_wrapper( ok = psasim_server_serialise_psa_cipher_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -2200,7 +2200,7 @@ int psa_cipher_encrypt_setup_wrapper( ok = psasim_server_serialise_psa_cipher_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -2296,7 +2296,7 @@ int psa_cipher_finish_wrapper( ok = psasim_server_serialise_psa_cipher_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -2410,7 +2410,7 @@ int psa_cipher_generate_iv_wrapper( ok = psasim_server_serialise_psa_cipher_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -2513,7 +2513,7 @@ int psa_cipher_set_iv_wrapper( ok = psasim_server_serialise_psa_cipher_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -2623,7 +2623,7 @@ int psa_cipher_update_wrapper( ok = psasim_server_serialise_psa_cipher_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -3436,7 +3436,7 @@ int psa_hash_abort_wrapper( ok = psasim_server_serialise_psa_hash_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -3520,7 +3520,7 @@ int psa_hash_clone_wrapper( ok = psasim_server_serialise_psa_hash_operation_t( &rpos, &rremain, - target_operation); + target_operation, 0); if (!ok) { goto fail; } @@ -3827,7 +3827,7 @@ int psa_hash_finish_wrapper( ok = psasim_server_serialise_psa_hash_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -3929,7 +3929,7 @@ int psa_hash_setup_wrapper( ok = psasim_server_serialise_psa_hash_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -4014,7 +4014,7 @@ int psa_hash_update_wrapper( ok = psasim_server_serialise_psa_hash_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -4103,7 +4103,7 @@ int psa_hash_verify_wrapper( ok = psasim_server_serialise_psa_hash_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -4389,7 +4389,7 @@ int psa_key_derivation_abort_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -4567,7 +4567,7 @@ int psa_key_derivation_input_bytes_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -4664,7 +4664,7 @@ int psa_key_derivation_input_integer_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -4757,7 +4757,7 @@ int psa_key_derivation_input_key_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -4860,7 +4860,7 @@ int psa_key_derivation_key_agreement_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -4950,7 +4950,7 @@ int psa_key_derivation_output_bytes_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -5055,7 +5055,7 @@ int psa_key_derivation_output_key_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -5166,7 +5166,7 @@ int psa_key_derivation_output_key_ext_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -5261,7 +5261,7 @@ int psa_key_derivation_set_capacity_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -5345,7 +5345,7 @@ int psa_key_derivation_setup_wrapper( ok = psasim_server_serialise_psa_key_derivation_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -5420,7 +5420,7 @@ int psa_mac_abort_wrapper( ok = psasim_server_serialise_psa_mac_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -5643,7 +5643,7 @@ int psa_mac_sign_finish_wrapper( ok = psasim_server_serialise_psa_mac_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -5754,7 +5754,7 @@ int psa_mac_sign_setup_wrapper( ok = psasim_server_serialise_psa_mac_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -5839,7 +5839,7 @@ int psa_mac_update_wrapper( ok = psasim_server_serialise_psa_mac_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -6030,7 +6030,7 @@ int psa_mac_verify_finish_wrapper( ok = psasim_server_serialise_psa_mac_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -6127,7 +6127,7 @@ int psa_mac_verify_setup_wrapper( ok = psasim_server_serialise_psa_mac_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -6589,7 +6589,7 @@ int psa_sign_hash_abort_wrapper( ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -6685,7 +6685,7 @@ int psa_sign_hash_complete_wrapper( ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -6873,7 +6873,7 @@ int psa_sign_hash_start_wrapper( ok = psasim_server_serialise_psa_sign_hash_interruptible_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -7181,7 +7181,7 @@ int psa_verify_hash_abort_wrapper( ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t( &rpos, &rremain, - operation); + operation, 1); if (!ok) { goto fail; } @@ -7256,7 +7256,7 @@ int psa_verify_hash_complete_wrapper( ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } @@ -7436,7 +7436,7 @@ int psa_verify_hash_start_wrapper( ok = psasim_server_serialise_psa_verify_hash_interruptible_operation_t( &rpos, &rremain, - operation); + operation, 0); if (!ok) { goto fail; } diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index ac7b2419c7..dd2fe9e3c4 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -750,11 +750,19 @@ sub output_server_wrapper my $server_specific = ($argtype =~ /^psa_\w+_operation_t/) ? "server_" : ""; + my $completed = ""; # Only needed on server serialise calls + if (length($server_specific)) { + # On server serialisation, which is only for operation types, + # we need to mark the operation as completed (variously called + # terminated or inactive in psa/crypto.h) on certain calls. + $completed = ($name =~ /_(abort|finish|hash_verify)$/) ? ", 1" : ", 0"; + } + print $fh < Date: Mon, 1 Jul 2024 07:06:26 +0200 Subject: [PATCH 083/125] psasim: remove sleep on server side to make test as fast as possible Signed-off-by: Valerio Setti --- psasim/src/psa_ff_server.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index b0737ec840..b106092441 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -26,8 +26,6 @@ #define MAX_CLIENTS 128 #define MAX_MESSAGES 32 -#define SLEEP_US 1 - struct connection { uint32_t client; void *rhandle; @@ -104,9 +102,6 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout) uint32_t requested_version; ssize_t len; int idx; -#if !defined(PSASIM_USE_USLEEP) - const struct timespec ts_delay = { .tv_sec = 0, .tv_nsec = SLEEP_US * 1000 }; -#endif if (timeout == PSA_POLL) { INFO("psa_wait: Called in polling mode"); @@ -261,11 +256,6 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout) break; } else { /* There is no 'select' function in SysV to block on multiple queues, so busy-wait :( */ -#if defined(PSASIM_USE_USLEEP) - usleep(SLEEP_US); -#else /* PSASIM_USE_USLEEP */ - nanosleep(&ts_delay, NULL); -#endif /* PSASIM_USE_USLEEP */ } } while (timeout == PSA_BLOCK); From 1b39c5c8278c154e99365fd8f030bc7884a93789 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 27 Jun 2024 08:00:54 +0200 Subject: [PATCH 084/125] makefile: allow to build and link test suites against psasim Signed-off-by: Valerio Setti --- psasim/Makefile | 53 +++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/psasim/Makefile b/psasim/Makefile index 02b639f2c4..ec6691f422 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -1,11 +1,11 @@ CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L ifeq ($(DEBUG),1) -CFLAGS += -DDEBUG -O0 -g +override CFLAGS += -DDEBUG -O0 -g endif -LIBPSACLIENT := -Llibpsaclient/ -lmbedcrypto -lmbedx509 -lmbedtls -LIBPSASERVER := -Llibpsaserver/ -lmbedcrypto +CLIENT_LIBS := -Lclient_libs -lpsaclient -lmbedtls -lmbedx509 -lmbedcrypto +SERVER_LIBS := -Lserver_libs -lmbedcrypto MBEDTLS_ROOT_PATH = ../../.. COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include \ @@ -16,13 +16,14 @@ GENERATED_H_FILES = include/psa_manifest/manifest.h \ include/psa_manifest/pid.h \ include/psa_manifest/sid.h -PSA_CLIENT_COMMON_SRC = src/psa_ff_client.c \ - src/psa_sim_crypto_client.c \ - src/psa_sim_serialise.c +LIBPSACLIENT_SRC = src/psa_ff_client.c \ + src/psa_sim_crypto_client.c \ + src/psa_sim_serialise.c +LIBPSACLIENT_OBJS=$(LIBPSACLIENT_SRC:.c=.o) -PSA_CLIENT_BASE_SRC = $(PSA_CLIENT_COMMON_SRC) src/client.c +PSA_CLIENT_BASE_SRC = $(LIBPSACLIENT_SRC) src/client.c -PSA_CLIENT_FULL_SRC = $(PSA_CLIENT_COMMON_SRC) \ +PSA_CLIENT_FULL_SRC = $(LIBPSACLIENT_SRC) \ $(wildcard src/aut_*.c) PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c @@ -32,21 +33,28 @@ PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \ src/psa_sim_crypto_server.c \ src/psa_sim_serialise.c -.PHONY: all clean libpsaclient libpsaserver +.PHONY: all clean client_libs server_libs all: test/seedfile: dd if=/dev/urandom of=./test/seedfile bs=64 count=1 -test/psa_client_base: $(PSA_CLIENT_BASE_SRC) $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_BASE_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ +src/%.o: src/%.c $(GENERATED_H_FILES) + $(CC) $(COMMON_INCLUDE) $(CFLAGS) -c $< $(LDFLAGS) -o $@ -test/psa_client_full: $(PSA_CLIENT_FULL_SRC) $(GENERATED_H_FILES) - $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_FULL_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@ +client_libs/libpsaclient: $(LIBPSACLIENT_OBJS) + mkdir -p client_libs + $(AR) -src client_libs/libpsaclient.a $(LIBPSACLIENT_OBJS) -test/psa_partition: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) test/seedfile - $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_SERVER_SRC) $(LIBPSASERVER) $(LDFLAGS) -o $@ +test/psa_client_base: $(PSA_CLIENT_BASE_SRC) $(GENERATED_H_FILES) test/seedfile + $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_BASE_SRC) $(CLIENT_LIBS) $(LDFLAGS) -o $@ + +test/psa_client_full: $(PSA_CLIENT_FULL_SRC) $(GENERATED_H_FILES) test/seedfile + $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_FULL_SRC) $(CLIENT_LIBS) $(LDFLAGS) -o $@ + +test/psa_server: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) + $(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_SERVER_SRC) $(SERVER_LIBS) $(LDFLAGS) -o $@ $(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES): src/manifest.json src/server.c tools/psa_autogen.py src/manifest.json @@ -56,17 +64,18 @@ $(PARTITION_SERVER_BOOTSTRAP) $(GENERATED_H_FILES): src/manifest.json src/server # # Note: these rules assume that mbedtls_config.h is already configured by all.sh. # If not using all.sh then the user must do it manually. -libpsaclient libpsaserver: +client_libs: client_libs/libpsaclient +client_libs server_libs: $(MAKE) -C $(MBEDTLS_ROOT_PATH)/library CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" libmbedcrypto.a libmbedx509.a libmbedtls.a mkdir -p $@ cp $(MBEDTLS_ROOT_PATH)/library/libmbed*.a $@/ - $(MAKE) -C $(MBEDTLS_ROOT_PATH) clean -clean: - rm -f test/psa_client_base test/psa_client_full test/psa_partition +clean_server_intermediate_files: rm -f $(PARTITION_SERVER_BOOTSTRAP) - rm -rf libpsaclient libpsaserver rm -rf include/psa_manifest - rm -f test/psa_service_* test/psa_notify_* - rm -f test/*.log + +clean: clean_server_intermediate_files + rm -f test/psa_client_base test/psa_client_full test/psa_server + rm -rf client_libs server_libs + rm -f test/psa_service_* test/psa_notify_* test/*.log rm -f test/seedfile From ecce17cbd65d92135eeedac6619b4becfacbd97a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 27 Jun 2024 08:03:32 +0200 Subject: [PATCH 085/125] psasim: update bash scripts Signed-off-by: Valerio Setti --- psasim/test/kill_server.sh | 16 ++++++++++++++++ psasim/test/run_test.sh | 30 +++++++----------------------- psasim/test/start_server.sh | 19 +++++++++++++++++++ 3 files changed, 42 insertions(+), 23 deletions(-) create mode 100755 psasim/test/kill_server.sh create mode 100755 psasim/test/start_server.sh diff --git a/psasim/test/kill_server.sh b/psasim/test/kill_server.sh new file mode 100755 index 0000000000..7aba5a32ed --- /dev/null +++ b/psasim/test/kill_server.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +set -e + +pkill psa_server || true + +# Remove temporary files and logs +rm -f psa_notify_* +rm -f psa_service_* +rm -f psa_server.log + +# Remove all IPCs +ipcs -q | awk '{ printf " -q " $2 }' | xargs ipcrm > /dev/null 2>&1 || true diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh index 7c1011ead2..ac9c4c86ca 100755 --- a/psasim/test/run_test.sh +++ b/psasim/test/run_test.sh @@ -1,13 +1,13 @@ #!/bin/bash +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + # This is a simple bash script that tests psa_client/psa_server interaction. # This script is automatically executed when "make run" is launched by the # "psasim" root folder. The script can also be launched manually once # binary files are built (i.e. after "make test" is executed from the "psasim" # root folder). -# -# Copyright The Mbed TLS Contributors -# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later set -e @@ -16,26 +16,10 @@ cd "$(dirname "$0")" CLIENT_BIN=$1 shift -function clean_run() { - rm -f psa_notify_* - pkill psa_partition || true - pkill psa_client || true - ipcs | grep q | awk '{ printf " -q " $2 }' | xargs ipcrm > /dev/null 2>&1 || true -} - -# The server creates some local files when it starts up so we can wait for this -# event as signal that the server is ready so that we can start client(s). -function wait_for_server_startup() { - while [ ! -f ./psa_notify_* ]; do - sleep 0.1 - done -} - -clean_run - -./psa_partition & -wait_for_server_startup +ipcs | grep q | awk '{ printf " -q " $2 }' | xargs ipcrm > /dev/null 2>&1 || true + +./start_server.sh ./$CLIENT_BIN "$@" # Kill server once client exited -pkill psa_partition +pkill psa_server diff --git a/psasim/test/start_server.sh b/psasim/test/start_server.sh new file mode 100755 index 0000000000..fcc8a97e9c --- /dev/null +++ b/psasim/test/start_server.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +set -e + +# The server creates some local files when it starts up so we can wait for this +# event as signal that the server is ready so that we can start client(s). +function wait_for_server_startup() { + while [ $(find . -name "psa_notify_*" | wc -l) -eq 0 ]; do + sleep 0.1 + done +} + +$(dirname "$0")/kill_server.sh + +$(dirname "$0")/psa_server & +wait_for_server_startup From f1a13b90978cfcb60b744f6ae6140ef8b0dbed37 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Sat, 29 Jun 2024 15:10:21 +0100 Subject: [PATCH 086/125] psasim: add a bit of white-box testing to hash operations Signed-off-by: Tom Cosgrove --- psasim/src/aut_psa_hash.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/psasim/src/aut_psa_hash.c b/psasim/src/aut_psa_hash.c index 0446e7a76a..b429c0bc58 100644 --- a/psasim/src/aut_psa_hash.c +++ b/psasim/src/aut_psa_hash.c @@ -89,6 +89,43 @@ int psa_hash_main(void) mbedtls_printf("Multi-part hash operation successful!\n"); } + /* A bit of white-box testing: ensure that we can abort an operation more + * times than there are operation slots on the simulator server. + */ + for (int i = 0; i < 200; i++) { + /* This should be a no-op */ + status = psa_hash_abort(&hash_operation); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_abort failed\n"); + goto cleanup; + } + } + + /* Compute hash using multi-part operation using the same operation struct */ + status = psa_hash_setup(&hash_operation, HASH_ALG); + if (status == PSA_ERROR_NOT_SUPPORTED) { + mbedtls_printf("unknown hash algorithm supplied\n"); + goto cleanup; + } else if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_setup failed: %d\n", status); + goto cleanup; + } + + status = psa_hash_update(&hash_operation, sample_message, sample_message_length); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_update failed\n"); + goto cleanup; + } + + /* Don't use psa_hash_finish() when going to check against an expected result */ + status = psa_hash_verify(&hash_operation, expected_hash, expected_hash_len); + if (status != PSA_SUCCESS) { + mbedtls_printf("psa_hash_verify failed: %d\n", status); + goto cleanup; + } else { + mbedtls_printf("Second multi-part hash operation successful!\n"); + } + /* Clear local variables prior to one-shot hash demo */ memset(hash, 0, sizeof(hash)); hash_length = 0; From 0cc439fc384b3c819381d87069df5268d622431d Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 18 Jul 2024 15:21:20 +0200 Subject: [PATCH 087/125] Adapt psasim Signed-off-by: Ronald Cron --- psasim/Makefile | 2 +- psasim/include/util.h | 2 +- psasim/src/psa_ff_server.c | 6 +++--- psasim/test/kill_server.sh | 4 ++-- psasim/test/start_server.sh | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/psasim/Makefile b/psasim/Makefile index ec6691f422..c23017fa82 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -77,5 +77,5 @@ clean_server_intermediate_files: clean: clean_server_intermediate_files rm -f test/psa_client_base test/psa_client_full test/psa_server rm -rf client_libs server_libs - rm -f test/psa_service_* test/psa_notify_* test/*.log + rm -f test/*.log rm -f test/seedfile diff --git a/psasim/include/util.h b/psasim/include/util.h index 5eb8238c5c..bbff3ca9c5 100644 --- a/psasim/include/util.h +++ b/psasim/include/util.h @@ -28,4 +28,4 @@ #define PROJECT_ID 'M' #define PATHNAMESIZE 256 -#define TMP_FILE_BASE_PATH "./" +#define TMP_FILE_BASE_PATH "/tmp/" diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index b106092441..00c5272646 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -605,9 +605,9 @@ void __init_psasim(const char **array, key_t key; int qid; FILE *fp; - char doorbell_path[PATHNAMESIZE] = { 0 }; + char doorbell_file[PATHNAMESIZE] = { 0 }; char queue_path[PATHNAMESIZE]; - snprintf(doorbell_path, PATHNAMESIZE, TMP_FILE_BASE_PATH "psa_notify_%u", getpid()); + snprintf(doorbell_file, PATHNAMESIZE, "psa_notify_%u", getpid()); if (library_initialised > 0) { return; @@ -619,7 +619,7 @@ void __init_psasim(const char **array, FATAL("Unsupported value. Aborting."); } - array[3] = doorbell_path; + array[3] = doorbell_file; for (int i = 0; i < 32; i++) { if (strncmp(array[i], "", 1) != 0) { diff --git a/psasim/test/kill_server.sh b/psasim/test/kill_server.sh index 7aba5a32ed..0425282c13 100755 --- a/psasim/test/kill_server.sh +++ b/psasim/test/kill_server.sh @@ -8,8 +8,8 @@ set -e pkill psa_server || true # Remove temporary files and logs -rm -f psa_notify_* -rm -f psa_service_* +rm -f /tmp/psa_notify_* +rm -f /tmp/psa_service_* rm -f psa_server.log # Remove all IPCs diff --git a/psasim/test/start_server.sh b/psasim/test/start_server.sh index fcc8a97e9c..58ab8506bf 100755 --- a/psasim/test/start_server.sh +++ b/psasim/test/start_server.sh @@ -8,7 +8,7 @@ set -e # The server creates some local files when it starts up so we can wait for this # event as signal that the server is ready so that we can start client(s). function wait_for_server_startup() { - while [ $(find . -name "psa_notify_*" | wc -l) -eq 0 ]; do + while [ -z $(find /tmp -maxdepth 1 -name "psa_notify_*" -printf 1 -quit) ]; do sleep 0.1 done } From f35d900be0371ae662efaf8e294e0e5b0e835f41 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 22 Jul 2024 08:48:17 +0200 Subject: [PATCH 088/125] Revert "Adapt psasim" This reverts commit 0cc439fc384b3c819381d87069df5268d622431d. The usage of files /tmp/ could result in race conditions if several several are run on the same machine. Signed-off-by: Ronald Cron --- psasim/Makefile | 2 +- psasim/include/util.h | 2 +- psasim/src/psa_ff_server.c | 6 +++--- psasim/test/kill_server.sh | 4 ++-- psasim/test/start_server.sh | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/psasim/Makefile b/psasim/Makefile index c23017fa82..ec6691f422 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -77,5 +77,5 @@ clean_server_intermediate_files: clean: clean_server_intermediate_files rm -f test/psa_client_base test/psa_client_full test/psa_server rm -rf client_libs server_libs - rm -f test/*.log + rm -f test/psa_service_* test/psa_notify_* test/*.log rm -f test/seedfile diff --git a/psasim/include/util.h b/psasim/include/util.h index bbff3ca9c5..5eb8238c5c 100644 --- a/psasim/include/util.h +++ b/psasim/include/util.h @@ -28,4 +28,4 @@ #define PROJECT_ID 'M' #define PATHNAMESIZE 256 -#define TMP_FILE_BASE_PATH "/tmp/" +#define TMP_FILE_BASE_PATH "./" diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index 00c5272646..b106092441 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -605,9 +605,9 @@ void __init_psasim(const char **array, key_t key; int qid; FILE *fp; - char doorbell_file[PATHNAMESIZE] = { 0 }; + char doorbell_path[PATHNAMESIZE] = { 0 }; char queue_path[PATHNAMESIZE]; - snprintf(doorbell_file, PATHNAMESIZE, "psa_notify_%u", getpid()); + snprintf(doorbell_path, PATHNAMESIZE, TMP_FILE_BASE_PATH "psa_notify_%u", getpid()); if (library_initialised > 0) { return; @@ -619,7 +619,7 @@ void __init_psasim(const char **array, FATAL("Unsupported value. Aborting."); } - array[3] = doorbell_file; + array[3] = doorbell_path; for (int i = 0; i < 32; i++) { if (strncmp(array[i], "", 1) != 0) { diff --git a/psasim/test/kill_server.sh b/psasim/test/kill_server.sh index 0425282c13..7aba5a32ed 100755 --- a/psasim/test/kill_server.sh +++ b/psasim/test/kill_server.sh @@ -8,8 +8,8 @@ set -e pkill psa_server || true # Remove temporary files and logs -rm -f /tmp/psa_notify_* -rm -f /tmp/psa_service_* +rm -f psa_notify_* +rm -f psa_service_* rm -f psa_server.log # Remove all IPCs diff --git a/psasim/test/start_server.sh b/psasim/test/start_server.sh index 58ab8506bf..fcc8a97e9c 100755 --- a/psasim/test/start_server.sh +++ b/psasim/test/start_server.sh @@ -8,7 +8,7 @@ set -e # The server creates some local files when it starts up so we can wait for this # event as signal that the server is ready so that we can start client(s). function wait_for_server_startup() { - while [ -z $(find /tmp -maxdepth 1 -name "psa_notify_*" -printf 1 -quit) ]; do + while [ $(find . -name "psa_notify_*" | wc -l) -eq 0 ]; do sleep 0.1 done } From 733fcf6d202ae708eda583076b48bf823310a6a5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 22 Jul 2024 08:51:53 +0200 Subject: [PATCH 089/125] psasim: Fix doorbell file path Do not apply twice TMP_FILE_BASE_PATH Signed-off-by: Ronald Cron --- psasim/src/psa_ff_server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/psasim/src/psa_ff_server.c b/psasim/src/psa_ff_server.c index b106092441..00c5272646 100644 --- a/psasim/src/psa_ff_server.c +++ b/psasim/src/psa_ff_server.c @@ -605,9 +605,9 @@ void __init_psasim(const char **array, key_t key; int qid; FILE *fp; - char doorbell_path[PATHNAMESIZE] = { 0 }; + char doorbell_file[PATHNAMESIZE] = { 0 }; char queue_path[PATHNAMESIZE]; - snprintf(doorbell_path, PATHNAMESIZE, TMP_FILE_BASE_PATH "psa_notify_%u", getpid()); + snprintf(doorbell_file, PATHNAMESIZE, "psa_notify_%u", getpid()); if (library_initialised > 0) { return; @@ -619,7 +619,7 @@ void __init_psasim(const char **array, FATAL("Unsupported value. Aborting."); } - array[3] = doorbell_path; + array[3] = doorbell_file; for (int i = 0; i < 32; i++) { if (strncmp(array[i], "", 1) != 0) { From b465b5b6f9c4348bdb109b6e55aabceffc399f0b Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 22 Jul 2024 11:06:33 +0200 Subject: [PATCH 090/125] psasim: Fix IPCs removal Signed-off-by: Ronald Cron --- psasim/test/kill_server.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/psasim/test/kill_server.sh b/psasim/test/kill_server.sh index 7aba5a32ed..b6c4f6843e 100755 --- a/psasim/test/kill_server.sh +++ b/psasim/test/kill_server.sh @@ -13,4 +13,7 @@ rm -f psa_service_* rm -f psa_server.log # Remove all IPCs -ipcs -q | awk '{ printf " -q " $2 }' | xargs ipcrm > /dev/null 2>&1 || true +# Not just ipcrm -all=msg as it is not supported on macOS. +# Filter out header and empty lines, choosing to select based on keys being +# output in hex. +ipcs -q | fgrep 0x | awk '{ printf " -q " $2 }' | xargs ipcrm > /dev/null 2>&1 || true From 1170ada70e1b52015ce7d98cfc629f31cbc976a0 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 22 Jul 2024 11:51:02 +0200 Subject: [PATCH 091/125] psasim: Move file clean-up to all.sh Signed-off-by: Ronald Cron --- psasim/test/kill_server.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/psasim/test/kill_server.sh b/psasim/test/kill_server.sh index b6c4f6843e..e84fd39ea1 100755 --- a/psasim/test/kill_server.sh +++ b/psasim/test/kill_server.sh @@ -7,11 +7,6 @@ set -e pkill psa_server || true -# Remove temporary files and logs -rm -f psa_notify_* -rm -f psa_service_* -rm -f psa_server.log - # Remove all IPCs # Not just ipcrm -all=msg as it is not supported on macOS. # Filter out header and empty lines, choosing to select based on keys being From 5811e352db774467d1ae04bf52335b8b76a8715c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 22 Jul 2024 11:09:18 +0200 Subject: [PATCH 092/125] psasim: Rename kill_server.sh to kill_servers.sh Rename kill_server.sh to kill_servers.sh as it kills all started PSA servers. Signed-off-by: Ronald Cron --- psasim/test/{kill_server.sh => kill_servers.sh} | 0 psasim/test/start_server.sh | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename psasim/test/{kill_server.sh => kill_servers.sh} (100%) diff --git a/psasim/test/kill_server.sh b/psasim/test/kill_servers.sh similarity index 100% rename from psasim/test/kill_server.sh rename to psasim/test/kill_servers.sh diff --git a/psasim/test/start_server.sh b/psasim/test/start_server.sh index fcc8a97e9c..ed5d965b50 100755 --- a/psasim/test/start_server.sh +++ b/psasim/test/start_server.sh @@ -13,7 +13,7 @@ function wait_for_server_startup() { done } -$(dirname "$0")/kill_server.sh +$(dirname "$0")/kill_servers.sh $(dirname "$0")/psa_server & wait_for_server_startup From 0e62b0fbddca5713180eddcfe6dbf19afee6705b Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 22 Jul 2024 08:56:10 +0200 Subject: [PATCH 093/125] all.sh: psasim: Start server in tf-psa-crypto/tests Start a server in tf-psa-crypto/tests in addition to tests to be able to run test suites from tf-psa-crypto/tests. Signed-off-by: Ronald Cron --- psasim/test/start_server.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/psasim/test/start_server.sh b/psasim/test/start_server.sh index ed5d965b50..ef11439777 100755 --- a/psasim/test/start_server.sh +++ b/psasim/test/start_server.sh @@ -13,7 +13,5 @@ function wait_for_server_startup() { done } -$(dirname "$0")/kill_servers.sh - $(dirname "$0")/psa_server & wait_for_server_startup From de419d1ccb23c7afbef02b8f38ea6adca757c4dd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 31 Jul 2024 17:54:30 +0200 Subject: [PATCH 094/125] Write output files to the expected directory Signed-off-by: Gilles Peskine --- psasim/src/psa_sim_generate.pl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index dd2fe9e3c4..b4a177eeb7 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -10,11 +10,14 @@ # use strict; use Data::Dumper; +use File::Basename; use JSON qw(encode_json); my $debug = 0; # Globals (sorry!) +my $output_dir = dirname($0); + my %functions = get_functions(); my @functions = sort keys %functions; @@ -84,11 +87,11 @@ # We'll do psa_crypto_init() first put_crypto_init_first(\@functions); -write_function_codes("psa_functions_codes.h"); +write_function_codes("$output_dir/psa_functions_codes.h"); -write_client_calls("psa_sim_crypto_client.c"); +write_client_calls("$output_dir/psa_sim_crypto_client.c"); -write_server_implementations("psa_sim_crypto_server.c"); +write_server_implementations("$output_dir/psa_sim_crypto_server.c"); sub write_function_codes { From 1e8bc61e6e8843e64020d2570a78c90f8e59eee9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 31 Jul 2024 17:38:33 +0200 Subject: [PATCH 095/125] Parse the actual headers Parse the actual header instead of a copy that's going to get out of date very soon. No change to the generated output. Signed-off-by: Gilles Peskine --- psasim/src/psa_sim_generate.pl | 4415 +------------------------------- 1 file changed, 68 insertions(+), 4347 deletions(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index b4a177eeb7..07835ae9af 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -1078,14 +1078,21 @@ sub output_signature sub get_functions { + my $header_dir = 'tf-psa-crypto/include'; my $src = ""; - while () { - chomp; - s/\/\/.*//; - s/\s+^//; - s/\s+/ /g; - $_ .= "\n"; - $src .= $_; + for my $header_file ('psa/crypto.h', 'psa/crypto_extra.h') { + local *HEADER; + open HEADER, '<', "$header_dir/$header_file" + or die "$header_dir/$header_file: $!"; + while (
) { + chomp; + s/\/\/.*//; + s/\s+^//; + s/\s+/ /g; + $_ .= "\n"; + $src .= $_; + } + close HEADER; } $src =~ s/\/\*.*?\*\///gs; @@ -1096,15 +1103,48 @@ sub get_functions my %funcs = (); for (my $i = 0; $i <= $#src; $i++) { my $line = $src[$i]; - if ($line =~ /^(psa_status_t|uint32_t|void) (psa_\w*)\(/) { # begin function definition + if ($line =~ /^(static(?:\s+inline)?\s+)? + ((?:(?:enum|struct|union)\s+)?\w+\s*\**\s*)\s+ + ((?:mbedtls|psa)_\w*)\(/x) { + # begin function declaration #print "have one $line\n"; while ($line !~ /;/) { $line .= $src[$i + 1]; $i++; } + if ($line =~ /^static/) { + # IGNORE static inline functions: they're local. + next; + } $line =~ s/\s+/ /g; if ($line =~ /(\w+)\s+\b(\w+)\s*\(\s*(.*\S)\s*\)\s*[;{]/s) { my ($ret_type, $func, $args) = ($1, $2, $3); + + if ($func =~ /_init$/ and $func ne 'psa_crypto_init' and + $args eq 'void') { + # IGNORE constructors + next; + } + if ($func =~ /_pake_/ or + $func eq 'mbedtls_psa_external_get_random' or + $func eq 'mbedtls_psa_get_stats' or + $func eq 'mbedtls_psa_platform_get_builtin_key' or + $func eq 'psa_get_key_slot_number') { + # IGNORE functions using unsupported types + next; + } + if ($func eq 'mbedtls_psa_register_se_key' or + $func eq 'mbedtls_psa_inject_entropy') { + # IGNORE functions that are not supported, not used in + # the default build, and not supposed to be invoked + # by (unprivileged) clients anyway. + next; + } + if ($func eq 'mbedtls_psa_crypto_free') { + # IGNORE function that we redefine instead of wrapping + next; + } + my $copy = $line; $copy =~ s/{$//; my $f = { @@ -1199,8 +1239,22 @@ sub get_functions die("FAILED"); } push(@rebuild, $line); - } elsif ($line =~ /^static psa_\w+_t (psa_\w*)\(/) { # begin function definition - # IGNORE static functions + } elsif ($line =~ /^#/i) { + # IGNORE directive + while ($line =~ /\\$/) { + $i++; + $line = $src[$i]; + } + } elsif ($line =~ /^(?:typedef +)?(enum|struct|union)[^;]*$/) { + # IGNORE compound type definition + while ($line !~ /^\}/) { + $i++; + $line = $src[$i]; + } + } elsif ($line =~ /^typedef /i) { + # IGNORE type definition + } elsif ($line =~ / = .*;$/) { + # IGNORE assignment in inline function definition } else { if ($line =~ /psa_/) { print "NOT PARSED: $line\n"; @@ -1228,4345 +1282,12 @@ sub put_crypto_init_first last; } } + if (!defined $idx) { + die "psa_crypto_init not found" + } - if (defined($idx) && $idx != 0) { # Do nothing if already first + if ($idx != 0) { # Do nothing if already first splice(@$functions, $idx, 1); unshift(@$functions, $want_first); } } - -__END__ -/** - * \brief Library initialization. - * - * Applications must call this function before calling any other - * function in this module. - * - * Applications may call this function more than once. Once a call - * succeeds, subsequent calls are guaranteed to succeed. - * - * If the application calls other functions before calling psa_crypto_init(), - * the behavior is undefined. Implementations are encouraged to either perform - * the operation as if the library had been initialized or to return - * #PSA_ERROR_BAD_STATE or some other applicable error. In particular, - * implementations should not return a success status if the lack of - * initialization may have security implications, for example due to improper - * seeding of the random number generator. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - */ -psa_status_t psa_crypto_init(void); - -/** Calculate the hash (digest) of a message. - * - * \note To verify the hash of a message against an - * expected value, use psa_hash_compare() instead. - * - * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_HASH(\p alg) is true). - * \param[in] input Buffer containing the message to hash. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] hash Buffer where the hash is to be written. - * \param hash_size Size of the \p hash buffer in bytes. - * \param[out] hash_length On success, the number of bytes - * that make up the hash value. This is always - * #PSA_HASH_LENGTH(\p alg). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a hash algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p hash_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -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); - -/* XXX We put this next one in place to check we ignore static functions - * when we eventually read all this from a real header file - */ - -/** Return an initial value for a hash operation object. - */ -static psa_hash_operation_t psa_hash_operation_init(void); - -/* XXX Back to normal function declarations */ - -/** Set up a multipart hash operation. - * - * The sequence of operations to calculate a hash (message digest) - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_hash_operation_t, e.g. #PSA_HASH_OPERATION_INIT. - * -# Call psa_hash_setup() to specify the algorithm. - * -# Call psa_hash_update() zero, one or more times, passing a fragment - * of the message each time. The hash that is calculated is the hash - * of the concatenation of these messages in order. - * -# To calculate the hash, call psa_hash_finish(). - * To compare the hash with an expected value, call psa_hash_verify(). - * - * If an error occurs at any step after a call to psa_hash_setup(), the - * operation will need to be reset by a call to psa_hash_abort(). The - * application may call psa_hash_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_hash_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_hash_finish() or psa_hash_verify(). - * - A call to psa_hash_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_hash_operation_t and not yet in use. - * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_HASH(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not a supported hash algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p alg is not a hash algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_setup(psa_hash_operation_t *operation, - psa_algorithm_t alg); - -/** Add a message fragment to a multipart hash operation. - * - * The application must call psa_hash_setup() before calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_hash_abort(). - * - * \param[in,out] operation Active hash operation. - * \param[in] input Buffer containing the message fragment to hash. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_update(psa_hash_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Finish the calculation of the hash of a message. - * - * The application must call psa_hash_setup() before calling this function. - * This function calculates the hash of the message formed by concatenating - * the inputs passed to preceding calls to psa_hash_update(). - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_hash_abort(). - * - * \warning Applications should not call this function if they expect - * a specific value for the hash. Call psa_hash_verify() instead. - * Beware that comparing integrity or authenticity data such as - * hash values with a function such as \c memcmp is risky - * because the time taken by the comparison may leak information - * about the hashed data which could allow an attacker to guess - * a valid hash and thereby bypass security controls. - * - * \param[in,out] operation Active hash operation. - * \param[out] hash Buffer where the hash is to be written. - * \param hash_size Size of the \p hash buffer in bytes. - * \param[out] hash_length On success, the number of bytes - * that make up the hash value. This is always - * #PSA_HASH_LENGTH(\c alg) where \c alg is the - * hash algorithm that is calculated. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p hash buffer is too small. You can determine a - * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg) - * where \c alg is the hash algorithm that is calculated. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_finish(psa_hash_operation_t *operation, - uint8_t *hash, - size_t hash_size, - size_t *hash_length); - -/** Finish the calculation of the hash of a message and compare it with - * an expected value. - * - * The application must call psa_hash_setup() before calling this function. - * This function calculates the hash of the message formed by concatenating - * the inputs passed to preceding calls to psa_hash_update(). It then - * compares the calculated hash with the expected hash passed as a - * parameter to this function. - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_hash_abort(). - * - * \note Implementations shall make the best effort to ensure that the - * comparison between the actual hash and the expected hash is performed - * in constant time. - * - * \param[in,out] operation Active hash operation. - * \param[in] hash Buffer containing the expected hash value. - * \param hash_length Size of the \p hash buffer in bytes. - * - * \retval #PSA_SUCCESS - * The expected hash is identical to the actual hash of the message. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The hash of the message was calculated successfully, but it - * differs from the expected hash. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_verify(psa_hash_operation_t *operation, - const uint8_t *hash, - size_t hash_length); - -/** Abort a hash operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * psa_hash_setup() again. - * - * You may call this function any time after the operation object has - * been initialized by one of the methods described in #psa_hash_operation_t. - * - * In particular, calling psa_hash_abort() after the operation has been - * terminated by a call to psa_hash_abort(), psa_hash_finish() or - * psa_hash_verify() is safe and has no effect. - * - * \param[in,out] operation Initialized hash operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_abort(psa_hash_operation_t *operation); - -/** Clone a hash operation. - * - * This function copies the state of an ongoing hash operation to - * a new operation object. In other words, this function is equivalent - * to calling psa_hash_setup() on \p target_operation with the same - * algorithm that \p source_operation was set up for, then - * psa_hash_update() on \p target_operation with the same input that - * that was passed to \p source_operation. After this function returns, the - * two objects are independent, i.e. subsequent calls involving one of - * the objects do not affect the other object. - * - * \param[in] source_operation The active hash operation to clone. - * \param[in,out] target_operation The operation object to set up. - * It must be initialized but not active. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The \p source_operation state is not valid (it must be active), or - * the \p target_operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, - psa_hash_operation_t *target_operation); - -/** Calculate the hash (digest) of a message and compare it with a - * reference value. - * - * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_HASH(\p alg) is true). - * \param[in] input Buffer containing the message to hash. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] hash Buffer containing the expected hash value. - * \param hash_length Size of the \p hash buffer in bytes. - * - * \retval #PSA_SUCCESS - * The expected hash is identical to the actual hash of the input. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The hash of the message was calculated successfully, but it - * differs from the expected hash. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a hash algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p input_length or \p hash_length do not match the hash size for \p alg - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_hash_compare(psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *hash, - size_t hash_length); - -/** Process an authenticated encryption operation. - * - * \param key Identifier of the key to use for the - * operation. It must allow the usage - * #PSA_KEY_USAGE_ENCRYPT. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * \param[in] nonce Nonce or IV to use. - * \param nonce_length Size of the \p nonce buffer in bytes. - * \param[in] additional_data Additional data that will be authenticated - * but not encrypted. - * \param additional_data_length Size of \p additional_data in bytes. - * \param[in] plaintext Data that will be authenticated and - * encrypted. - * \param plaintext_length Size of \p plaintext in bytes. - * \param[out] ciphertext Output buffer for the authenticated and - * encrypted data. The additional data is not - * part of this output. For algorithms where the - * encrypted data and the authentication tag - * are defined as separate outputs, the - * authentication tag is appended to the - * encrypted data. - * \param ciphertext_size Size of the \p ciphertext buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, - * \p alg, \p plaintext_length) where - * \c key_type is the type of \p key. - * - #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p - * plaintext_length) evaluates to the maximum - * ciphertext size of any supported AEAD - * encryption. - * \param[out] ciphertext_length On success, the size of the output - * in the \p ciphertext buffer. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p ciphertext_size is too small. - * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, \p alg, - * \p plaintext_length) or - * #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length) can be used to - * determine the required buffer size. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *nonce, - size_t nonce_length, - const uint8_t *additional_data, - size_t additional_data_length, - const uint8_t *plaintext, - size_t plaintext_length, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length); - -/** Process an authenticated decryption operation. - * - * \param key Identifier of the key to use for the - * operation. It must allow the usage - * #PSA_KEY_USAGE_DECRYPT. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * \param[in] nonce Nonce or IV to use. - * \param nonce_length Size of the \p nonce buffer in bytes. - * \param[in] additional_data Additional data that has been authenticated - * but not encrypted. - * \param additional_data_length Size of \p additional_data in bytes. - * \param[in] ciphertext Data that has been authenticated and - * encrypted. For algorithms where the - * encrypted data and the authentication tag - * are defined as separate inputs, the buffer - * must contain the encrypted data followed - * by the authentication tag. - * \param ciphertext_length Size of \p ciphertext in bytes. - * \param[out] plaintext Output buffer for the decrypted data. - * \param plaintext_size Size of the \p plaintext buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, - * \p alg, \p ciphertext_length) where - * \c key_type is the type of \p key. - * - #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p - * ciphertext_length) evaluates to the maximum - * plaintext size of any supported AEAD - * decryption. - * \param[out] plaintext_length On success, the size of the output - * in the \p plaintext buffer. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The ciphertext is not authentic. - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p plaintext_size is too small. - * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, \p alg, - * \p ciphertext_length) or - * #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length) can be used - * to determine the required buffer size. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *nonce, - size_t nonce_length, - const uint8_t *additional_data, - size_t additional_data_length, - const uint8_t *ciphertext, - size_t ciphertext_length, - uint8_t *plaintext, - size_t plaintext_size, - size_t *plaintext_length); - -/** The type of the state data structure for multipart AEAD operations. - * - * Before calling any function on an AEAD operation object, the application - * must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_aead_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_aead_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_AEAD_OPERATION_INIT, - * for example: - * \code - * psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_aead_operation_init() - * to the structure, for example: - * \code - * psa_aead_operation_t operation; - * operation = psa_aead_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_aead_operation_s psa_aead_operation_t; - -/** \def PSA_AEAD_OPERATION_INIT - * - * This macro returns a suitable initializer for an AEAD operation object of - * type #psa_aead_operation_t. - */ - -/** Return an initial value for an AEAD operation object. - */ -static psa_aead_operation_t psa_aead_operation_init(void); - -/** Set the key for a multipart authenticated encryption operation. - * - * The sequence of operations to encrypt a message with authentication - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_aead_operation_t, e.g. - * #PSA_AEAD_OPERATION_INIT. - * -# Call psa_aead_encrypt_setup() to specify the algorithm and key. - * -# If needed, call psa_aead_set_lengths() to specify the length of the - * inputs to the subsequent calls to psa_aead_update_ad() and - * psa_aead_update(). See the documentation of psa_aead_set_lengths() - * for details. - * -# Call either psa_aead_generate_nonce() or psa_aead_set_nonce() to - * generate or set the nonce. You should use - * psa_aead_generate_nonce() unless the protocol you are implementing - * requires a specific nonce value. - * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment - * of the non-encrypted additional authenticated data each time. - * -# Call psa_aead_update() zero, one or more times, passing a fragment - * of the message to encrypt each time. - * -# Call psa_aead_finish(). - * - * If an error occurs at any step after a call to psa_aead_encrypt_setup(), - * the operation will need to be reset by a call to psa_aead_abort(). The - * application may call psa_aead_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_aead_encrypt_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_aead_finish(). - * - A call to psa_aead_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_aead_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_ENCRYPT. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Set the key for a multipart authenticated decryption operation. - * - * The sequence of operations to decrypt a message with authentication - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_aead_operation_t, e.g. - * #PSA_AEAD_OPERATION_INIT. - * -# Call psa_aead_decrypt_setup() to specify the algorithm and key. - * -# If needed, call psa_aead_set_lengths() to specify the length of the - * inputs to the subsequent calls to psa_aead_update_ad() and - * psa_aead_update(). See the documentation of psa_aead_set_lengths() - * for details. - * -# Call psa_aead_set_nonce() with the nonce for the decryption. - * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment - * of the non-encrypted additional authenticated data each time. - * -# Call psa_aead_update() zero, one or more times, passing a fragment - * of the ciphertext to decrypt each time. - * -# Call psa_aead_verify(). - * - * If an error occurs at any step after a call to psa_aead_decrypt_setup(), - * the operation will need to be reset by a call to psa_aead_abort(). The - * application may call psa_aead_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_aead_decrypt_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_aead_verify(). - * - A call to psa_aead_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_aead_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_DECRYPT. - * \param alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or the - * library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Generate a random nonce for an authenticated encryption operation. - * - * This function generates a random nonce for the authenticated encryption - * operation with an appropriate size for the chosen algorithm, key type - * and key size. - * - * The application must call psa_aead_encrypt_setup() before - * calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param[out] nonce Buffer where the generated nonce is to be - * written. - * \param nonce_size Size of the \p nonce buffer in bytes. - * \param[out] nonce_length On success, the number of bytes of the - * generated nonce. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p nonce buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active aead encrypt - * operation, with no nonce set), or the library has not been - * previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, - uint8_t *nonce, - size_t nonce_size, - size_t *nonce_length); - -/** Set the nonce for an authenticated encryption or decryption operation. - * - * This function sets the nonce for the authenticated - * encryption or decryption operation. - * - * The application must call psa_aead_encrypt_setup() or - * psa_aead_decrypt_setup() before calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \note When encrypting, applications should use psa_aead_generate_nonce() - * instead of this function, unless implementing a protocol that requires - * a non-random IV. - * - * \param[in,out] operation Active AEAD operation. - * \param[in] nonce Buffer containing the nonce to use. - * \param nonce_length Size of the nonce in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size of \p nonce is not acceptable for the chosen algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, with no nonce - * set), or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, - const uint8_t *nonce, - size_t nonce_length); - -/** Declare the lengths of the message and additional data for AEAD. - * - * The application must call this function before calling - * psa_aead_update_ad() or psa_aead_update() if the algorithm for - * the operation requires it. If the algorithm does not require it, - * calling this function is optional, but if this function is called - * then the implementation must enforce the lengths. - * - * You may call this function before or after setting the nonce with - * psa_aead_set_nonce() or psa_aead_generate_nonce(). - * - * - For #PSA_ALG_CCM, calling this function is required. - * - For the other AEAD algorithms defined in this specification, calling - * this function is not required. - * - For vendor-defined algorithm, refer to the vendor documentation. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param ad_length Size of the non-encrypted additional - * authenticated data in bytes. - * \param plaintext_length Size of the plaintext to encrypt in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * At least one of the lengths is not acceptable for the chosen - * algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, and - * psa_aead_update_ad() and psa_aead_update() must not have been - * called yet), or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, - size_t ad_length, - size_t plaintext_length); - -/** Pass additional data to an active AEAD operation. - * - * Additional data is authenticated, but not encrypted. - * - * You may call this function multiple times to pass successive fragments - * of the additional data. You may not call this function after passing - * data to encrypt or decrypt with psa_aead_update(). - * - * Before calling this function, you must: - * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). - * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, - * there is no guarantee that the input is valid. Therefore, until - * you have called psa_aead_verify() and it has returned #PSA_SUCCESS, - * treat the input as untrusted and prepare to undo any action that - * depends on the input if psa_aead_verify() returns an error status. - * - * \param[in,out] operation Active AEAD operation. - * \param[in] input Buffer containing the fragment of - * additional data. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total input length overflows the additional data length that - * was previously specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, have a nonce - * set, have lengths set if required by the algorithm, and - * psa_aead_update() must not have been called yet), or the library - * has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Encrypt or decrypt a message fragment in an active AEAD operation. - * - * Before calling this function, you must: - * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). - * The choice of setup function determines whether this function - * encrypts or decrypts its input. - * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). - * 3. Call psa_aead_update_ad() to pass all the additional data. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, - * there is no guarantee that the input is valid. Therefore, until - * you have called psa_aead_verify() and it has returned #PSA_SUCCESS: - * - Do not use the output in any way other than storing it in a - * confidential location. If you take any action that depends - * on the tentative decrypted data, this action will need to be - * undone if the input turns out not to be valid. Furthermore, - * if an adversary can observe that this action took place - * (for example through timing), they may be able to use this - * fact as an oracle to decrypt any message encrypted with the - * same key. - * - In particular, do not copy the output anywhere but to a - * memory or storage space that you have exclusive access to. - * - * This function does not require the input to be aligned to any - * particular block boundary. If the implementation can only process - * a whole block at a time, it must consume all the input provided, but - * it may delay the end of the corresponding output until a subsequent - * call to psa_aead_update(), psa_aead_finish() or psa_aead_verify() - * provides sufficient input. The amount of data that can be delayed - * in this way is bounded by #PSA_AEAD_UPDATE_OUTPUT_SIZE. - * - * \param[in,out] operation Active AEAD operation. - * \param[in] input Buffer containing the message fragment to - * encrypt or decrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * \param output_size Size of the \p output buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, - * \c alg, \p input_length) where - * \c key_type is the type of key and \c alg is - * the algorithm that were used to set up the - * operation. - * - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p - * input_length) evaluates to the maximum - * output size of any supported AEAD - * algorithm. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or - * #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to - * determine the required buffer size. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total length of input to psa_aead_update_ad() so far is - * less than the additional data length that was previously - * specified with psa_aead_set_lengths(), or - * the total input length overflows the plaintext length that - * was previously specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, have a nonce - * set, and have lengths set if required by the algorithm), or the - * library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_update(psa_aead_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Finish encrypting a message in an AEAD operation. - * - * The operation must have been set up with psa_aead_encrypt_setup(). - * - * This function finishes the authentication of the additional data - * formed by concatenating the inputs passed to preceding calls to - * psa_aead_update_ad() with the plaintext formed by concatenating the - * inputs passed to preceding calls to psa_aead_update(). - * - * This function has two output buffers: - * - \p ciphertext contains trailing ciphertext that was buffered from - * preceding calls to psa_aead_update(). - * - \p tag contains the authentication tag. - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \param[in,out] operation Active AEAD operation. - * \param[out] ciphertext Buffer where the last part of the ciphertext - * is to be written. - * \param ciphertext_size Size of the \p ciphertext buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, - * \c alg) where \c key_type is the type of key - * and \c alg is the algorithm that were used to - * set up the operation. - * - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to - * the maximum output size of any supported AEAD - * algorithm. - * \param[out] ciphertext_length On success, the number of bytes of - * returned ciphertext. - * \param[out] tag Buffer where the authentication tag is - * to be written. - * \param tag_size Size of the \p tag buffer in bytes. - * This must be appropriate for the selected - * algorithm and key: - * - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c - * key_type, \c key_bits, \c alg) where - * \c key_type and \c key_bits are the type and - * bit-size of the key, and \c alg is the - * algorithm that were used in the call to - * psa_aead_encrypt_setup(). - * - #PSA_AEAD_TAG_MAX_SIZE evaluates to the - * maximum tag size of any supported AEAD - * algorithm. - * \param[out] tag_length On success, the number of bytes - * that make up the returned tag. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p ciphertext or \p tag buffer is too small. - * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, \c alg) or - * #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE can be used to determine the - * required \p ciphertext buffer size. #PSA_AEAD_TAG_LENGTH(\c key_type, - * \c key_bits, \c alg) or #PSA_AEAD_TAG_MAX_SIZE can be used to - * determine the required \p tag buffer size. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total length of input to psa_aead_update_ad() so far is - * less than the additional data length that was previously - * specified with psa_aead_set_lengths(), or - * the total length of input to psa_aead_update() so far is - * less than the plaintext length that was previously - * specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active encryption - * operation with a nonce set), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_finish(psa_aead_operation_t *operation, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length, - uint8_t *tag, - size_t tag_size, - size_t *tag_length); - -/** Finish authenticating and decrypting a message in an AEAD operation. - * - * The operation must have been set up with psa_aead_decrypt_setup(). - * - * This function finishes the authenticated decryption of the message - * components: - * - * - The additional data consisting of the concatenation of the inputs - * passed to preceding calls to psa_aead_update_ad(). - * - The ciphertext consisting of the concatenation of the inputs passed to - * preceding calls to psa_aead_update(). - * - The tag passed to this function call. - * - * If the authentication tag is correct, this function outputs any remaining - * plaintext and reports success. If the authentication tag is not correct, - * this function returns #PSA_ERROR_INVALID_SIGNATURE. - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_aead_abort(). - * - * \note Implementations shall make the best effort to ensure that the - * comparison between the actual tag and the expected tag is performed - * in constant time. - * - * \param[in,out] operation Active AEAD operation. - * \param[out] plaintext Buffer where the last part of the plaintext - * is to be written. This is the remaining data - * from previous calls to psa_aead_update() - * that could not be processed until the end - * of the input. - * \param plaintext_size Size of the \p plaintext buffer in bytes. - * This must be appropriate for the selected algorithm and key: - * - A sufficient output size is - * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, - * \c alg) where \c key_type is the type of key - * and \c alg is the algorithm that were used to - * set up the operation. - * - #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE evaluates to - * the maximum output size of any supported AEAD - * algorithm. - * \param[out] plaintext_length On success, the number of bytes of - * returned plaintext. - * \param[in] tag Buffer containing the authentication tag. - * \param tag_length Size of the \p tag buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculations were successful, but the authentication tag is - * not correct. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p plaintext buffer is too small. - * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, \c alg) or - * #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE can be used to determine the - * required buffer size. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total length of input to psa_aead_update_ad() so far is - * less than the additional data length that was previously - * specified with psa_aead_set_lengths(), or - * the total length of input to psa_aead_update() so far is - * less than the plaintext length that was previously - * specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active decryption - * operation with a nonce set), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_verify(psa_aead_operation_t *operation, - uint8_t *plaintext, - size_t plaintext_size, - size_t *plaintext_length, - const uint8_t *tag, - size_t tag_length); - -/** Abort an AEAD operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * psa_aead_encrypt_setup() or psa_aead_decrypt_setup() again. - * - * You may call this function any time after the operation object has - * been initialized as described in #psa_aead_operation_t. - * - * In particular, calling psa_aead_abort() after the operation has been - * terminated by a call to psa_aead_abort(), psa_aead_finish() or - * psa_aead_verify() is safe and has no effect. - * - * \param[in,out] operation Initialized AEAD operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_aead_abort(psa_aead_operation_t *operation); - -/** - * \brief Import a key in binary format. - * - * This function supports any output from psa_export_key(). Refer to the - * documentation of psa_export_public_key() for the format of public keys - * and to the documentation of psa_export_key() for the format for - * other key types. - * - * The key data determines the key size. The attributes may optionally - * specify a key size; in this case it must match the size determined - * from the key data. A key size of 0 in \p attributes indicates that - * the key size is solely determined by the key data. - * - * Implementations must reject an attempt to import a key of size 0. - * - * This specification supports a single format for each key type. - * Implementations may support other formats as long as the standard - * format is supported. Implementations that support other formats - * should ensure that the formats are clearly unambiguous so as to - * minimize the risk that an invalid input is accidentally interpreted - * according to a different format. - * - * \param[in] attributes The attributes for the new key. - * The key size is always determined from the - * \p data buffer. - * If the key size in \p attributes is nonzero, - * it must be equal to the size from \p data. - * \param[out] key On success, an identifier to the newly created key. - * For persistent keys, this is the key identifier - * defined in \p attributes. - * \c 0 on failure. - * \param[in] data Buffer containing the key data. The content of this - * buffer is interpreted according to the type declared - * in \p attributes. - * All implementations must support at least the format - * described in the documentation - * of psa_export_key() or psa_export_public_key() for - * the chosen type. Implementations may allow other - * formats, but should be conservative: implementations - * should err on the side of rejecting content if it - * may be erroneous (e.g. wrong type or truncated data). - * \param data_length Size of the \p data buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The key type or key size is not supported, either by the - * implementation in general or in this particular persistent location. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key attributes, as a whole, are invalid, or - * the key data is not correctly formatted, or - * the size in \p attributes is nonzero and does not match the size - * of the key data. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_import_key(const psa_key_attributes_t *attributes, - const uint8_t *data, - size_t data_length, - mbedtls_svc_key_id_t *key); - -/** Retrieve the attributes of a key. - * - * This function first resets the attribute structure as with - * psa_reset_key_attributes(). It then copies the attributes of - * the given key into the given attribute structure. - * - * \note This function may allocate memory or other resources. - * Once you have called this function on an attribute structure, - * you must call psa_reset_key_attributes() to free these resources. - * - * \param[in] key Identifier of the key to query. - * \param[in,out] attributes On success, the attributes of the key. - * On failure, equivalent to a - * freshly-initialized structure. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, - psa_key_attributes_t *attributes); - -/** - * \brief Destroy a key. - * - * This function destroys a key from both volatile - * memory and, if applicable, non-volatile storage. Implementations shall - * make a best effort to ensure that the key material cannot be recovered. - * - * This function also erases any metadata such as policies and frees - * resources associated with the key. - * - * If a key is currently in use in a multipart operation, then destroying the - * key will cause the multipart operation to fail. - * - * \warning We can only guarantee that the the key material will - * eventually be wiped from memory. With threading enabled - * and during concurrent execution, copies of the key material may - * still exist until all threads have finished using the key. - * - * \param key Identifier of the key to erase. If this is \c 0, do nothing and - * return #PSA_SUCCESS. - * - * \retval #PSA_SUCCESS - * \p key was a valid identifier and the key material that it - * referred to has been erased. Alternatively, \p key is \c 0. - * \retval #PSA_ERROR_NOT_PERMITTED - * The key cannot be erased because it is - * read-only, either due to a policy or due to physical restrictions. - * \retval #PSA_ERROR_INVALID_HANDLE - * \p key is not a valid identifier nor \c 0. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * There was a failure in communication with the cryptoprocessor. - * The key material may still be present in the cryptoprocessor. - * \retval #PSA_ERROR_DATA_INVALID - * This error is typically a result of either storage corruption on a - * cleartext storage backend, or an attempt to read data that was - * written by an incompatible version of the library. - * \retval #PSA_ERROR_STORAGE_FAILURE - * The storage is corrupted. Implementations shall make a best effort - * to erase key material even in this stage, however applications - * should be aware that it may be impossible to guarantee that the - * key material is not recoverable in such cases. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * An unexpected condition which is not a storage corruption or - * a communication failure occurred. The cryptoprocessor may have - * been compromised. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); - -/** - * \brief Generate random bytes. - * - * \warning This function **can** fail! Callers MUST check the return status - * and MUST NOT use the content of the output buffer if the return - * status is not #PSA_SUCCESS. - * - * \note To generate a key, use psa_generate_key() instead. - * - * \param[out] output Output buffer for the generated data. - * \param output_size Number of bytes to generate and output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_generate_random(uint8_t *output, - size_t output_size); - -/** Calculate the MAC (message authentication code) of a message. - * - * \note To verify the MAC of a message against an - * expected value, use psa_mac_verify() instead. - * Beware that comparing integrity or authenticity data such as - * MAC values with a function such as \c memcmp is risky - * because the time taken by the comparison may leak information - * about the MAC value which could allow an attacker to guess - * a valid MAC and thereby bypass security controls. - * - * \param key Identifier of the key to use for the operation. It - * must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. - * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * \param[in] input Buffer containing the input message. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] mac Buffer where the MAC value is to be written. - * \param mac_size Size of the \p mac buffer in bytes. - * \param[out] mac_length On success, the number of bytes - * that make up the MAC value. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p mac_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The key could not be retrieved from storage. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *mac, - size_t mac_size, - size_t *mac_length); - -/** Calculate the MAC of a message and compare it with a reference value. - * - * \param key Identifier of the key to use for the operation. It - * must allow the usage PSA_KEY_USAGE_VERIFY_MESSAGE. - * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * \param[in] input Buffer containing the input message. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] mac Buffer containing the expected MAC value. - * \param mac_length Size of the \p mac buffer in bytes. - * - * \retval #PSA_SUCCESS - * The expected MAC is identical to the actual MAC of the input. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The MAC of the message was calculated successfully, but it - * differs from the expected value. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The key could not be retrieved from storage. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *mac, - size_t mac_length); - -/** The type of the state data structure for multipart MAC operations. - * - * Before calling any function on a MAC operation object, the application must - * initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_mac_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_mac_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_MAC_OPERATION_INIT, - * for example: - * \code - * psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_mac_operation_init() - * to the structure, for example: - * \code - * psa_mac_operation_t operation; - * operation = psa_mac_operation_init(); - * \endcode - * - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_mac_operation_s psa_mac_operation_t; - -/** \def PSA_MAC_OPERATION_INIT - * - * This macro returns a suitable initializer for a MAC operation object of type - * #psa_mac_operation_t. - */ - -/** Return an initial value for a MAC operation object. - */ -static psa_mac_operation_t psa_mac_operation_init(void); - -/** Set up a multipart MAC calculation operation. - * - * This function sets up the calculation of the MAC - * (message authentication code) of a byte string. - * To verify the MAC of a message against an - * expected value, use psa_mac_verify_setup() instead. - * - * The sequence of operations to calculate a MAC is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. - * -# Call psa_mac_sign_setup() to specify the algorithm and key. - * -# Call psa_mac_update() zero, one or more times, passing a fragment - * of the message each time. The MAC that is calculated is the MAC - * of the concatenation of these messages in order. - * -# At the end of the message, call psa_mac_sign_finish() to finish - * calculating the MAC value and retrieve it. - * - * If an error occurs at any step after a call to psa_mac_sign_setup(), the - * operation will need to be reset by a call to psa_mac_abort(). The - * application may call psa_mac_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_mac_sign_setup(), the application must - * eventually terminate the operation through one of the following methods: - * - A successful call to psa_mac_sign_finish(). - * - A call to psa_mac_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_mac_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. It - * must remain valid until the operation terminates. - * It must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. - * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The key could not be retrieved from storage. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Set up a multipart MAC verification operation. - * - * This function sets up the verification of the MAC - * (message authentication code) of a byte string against an expected value. - * - * The sequence of operations to verify a MAC is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. - * -# Call psa_mac_verify_setup() to specify the algorithm and key. - * -# Call psa_mac_update() zero, one or more times, passing a fragment - * of the message each time. The MAC that is calculated is the MAC - * of the concatenation of these messages in order. - * -# At the end of the message, call psa_mac_verify_finish() to finish - * calculating the actual MAC of the message and verify it against - * the expected value. - * - * If an error occurs at any step after a call to psa_mac_verify_setup(), the - * operation will need to be reset by a call to psa_mac_abort(). The - * application may call psa_mac_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_mac_verify_setup(), the application must - * eventually terminate the operation through one of the following methods: - * - A successful call to psa_mac_verify_finish(). - * - A call to psa_mac_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_mac_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. It - * must remain valid until the operation terminates. - * It must allow the usage - * PSA_KEY_USAGE_VERIFY_MESSAGE. - * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value - * such that #PSA_ALG_IS_MAC(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c key is not compatible with \c alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \c alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE - * The key could not be retrieved from storage. - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Add a message fragment to a multipart MAC operation. - * - * The application must call psa_mac_sign_setup() or psa_mac_verify_setup() - * before calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_mac_abort(). - * - * \param[in,out] operation Active MAC operation. - * \param[in] input Buffer containing the message fragment to add to - * the MAC calculation. - * \param input_length Size of the \p input buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_update(psa_mac_operation_t *operation, - const uint8_t *input, - size_t input_length); - -/** Finish the calculation of the MAC of a message. - * - * The application must call psa_mac_sign_setup() before calling this function. - * This function calculates the MAC of the message formed by concatenating - * the inputs passed to preceding calls to psa_mac_update(). - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_mac_abort(). - * - * \warning Applications should not call this function if they expect - * a specific value for the MAC. Call psa_mac_verify_finish() instead. - * Beware that comparing integrity or authenticity data such as - * MAC values with a function such as \c memcmp is risky - * because the time taken by the comparison may leak information - * about the MAC value which could allow an attacker to guess - * a valid MAC and thereby bypass security controls. - * - * \param[in,out] operation Active MAC operation. - * \param[out] mac Buffer where the MAC value is to be written. - * \param mac_size Size of the \p mac buffer in bytes. - * \param[out] mac_length On success, the number of bytes - * that make up the MAC value. This is always - * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg) - * where \c key_type and \c key_bits are the type and - * bit-size respectively of the key and \c alg is the - * MAC algorithm that is calculated. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p mac buffer is too small. You can determine a - * sufficient buffer size by calling PSA_MAC_LENGTH(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active mac sign - * operation), or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, - uint8_t *mac, - size_t mac_size, - size_t *mac_length); - -/** Finish the calculation of the MAC of a message and compare it with - * an expected value. - * - * The application must call psa_mac_verify_setup() before calling this function. - * This function calculates the MAC of the message formed by concatenating - * the inputs passed to preceding calls to psa_mac_update(). It then - * compares the calculated MAC with the expected MAC passed as a - * parameter to this function. - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_mac_abort(). - * - * \note Implementations shall make the best effort to ensure that the - * comparison between the actual MAC and the expected MAC is performed - * in constant time. - * - * \param[in,out] operation Active MAC operation. - * \param[in] mac Buffer containing the expected MAC value. - * \param mac_length Size of the \p mac buffer in bytes. - * - * \retval #PSA_SUCCESS - * The expected MAC is identical to the actual MAC of the message. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The MAC of the message was calculated successfully, but it - * differs from the expected MAC. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active mac verify - * operation), or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, - const uint8_t *mac, - size_t mac_length); - -/** Abort a MAC operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * psa_mac_sign_setup() or psa_mac_verify_setup() again. - * - * You may call this function any time after the operation object has - * been initialized by one of the methods described in #psa_mac_operation_t. - * - * In particular, calling psa_mac_abort() after the operation has been - * terminated by a call to psa_mac_abort(), psa_mac_sign_finish() or - * psa_mac_verify_finish() is safe and has no effect. - * - * \param[in,out] operation Initialized MAC operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_mac_abort(psa_mac_operation_t *operation); - -/** Encrypt a message using a symmetric cipher. - * - * This function encrypts a message with a random IV (initialization - * vector). Use the multipart operation interface with a - * #psa_cipher_operation_t object to provide other forms of IV. - * - * \param key Identifier of the key to use for the operation. - * It must allow the usage #PSA_KEY_USAGE_ENCRYPT. - * \param alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param[in] input Buffer containing the message to encrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * The output contains the IV followed by - * the ciphertext proper. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Decrypt a message using a symmetric cipher. - * - * This function decrypts a message encrypted with a symmetric cipher. - * - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_DECRYPT. - * \param alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * \param[in] input Buffer containing the message to decrypt. - * This consists of the IV followed by the - * ciphertext proper. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the plaintext is to be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** The type of the state data structure for multipart cipher operations. - * - * Before calling any function on a cipher operation object, the application - * must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_cipher_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_cipher_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_CIPHER_OPERATION_INIT, - * for example: - * \code - * psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_cipher_operation_init() - * to the structure, for example: - * \code - * psa_cipher_operation_t operation; - * operation = psa_cipher_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. */ -typedef struct psa_cipher_operation_s psa_cipher_operation_t; - -/** \def PSA_CIPHER_OPERATION_INIT - * - * This macro returns a suitable initializer for a cipher operation object of - * type #psa_cipher_operation_t. - */ - -/** Return an initial value for a cipher operation object. - */ -static psa_cipher_operation_t psa_cipher_operation_init(void); - -/** Set the key for a multipart symmetric encryption operation. - * - * The sequence of operations to encrypt a message with a symmetric cipher - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_cipher_operation_t, e.g. - * #PSA_CIPHER_OPERATION_INIT. - * -# Call psa_cipher_encrypt_setup() to specify the algorithm and key. - * -# Call either psa_cipher_generate_iv() or psa_cipher_set_iv() to - * generate or set the IV (initialization vector). You should use - * psa_cipher_generate_iv() unless the protocol you are implementing - * requires a specific IV value. - * -# Call psa_cipher_update() zero, one or more times, passing a fragment - * of the message each time. - * -# Call psa_cipher_finish(). - * - * If an error occurs at any step after a call to psa_cipher_encrypt_setup(), - * the operation will need to be reset by a call to psa_cipher_abort(). The - * application may call psa_cipher_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_cipher_encrypt_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_cipher_finish(). - * - A call to psa_cipher_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_cipher_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_ENCRYPT. - * \param alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Set the key for a multipart symmetric decryption operation. - * - * The sequence of operations to decrypt a message with a symmetric cipher - * is as follows: - * -# Allocate an operation object which will be passed to all the functions - * listed here. - * -# Initialize the operation object with one of the methods described in the - * documentation for #psa_cipher_operation_t, e.g. - * #PSA_CIPHER_OPERATION_INIT. - * -# Call psa_cipher_decrypt_setup() to specify the algorithm and key. - * -# Call psa_cipher_set_iv() with the IV (initialization vector) for the - * decryption. If the IV is prepended to the ciphertext, you can call - * psa_cipher_update() on a buffer containing the IV followed by the - * beginning of the message. - * -# Call psa_cipher_update() zero, one or more times, passing a fragment - * of the message each time. - * -# Call psa_cipher_finish(). - * - * If an error occurs at any step after a call to psa_cipher_decrypt_setup(), - * the operation will need to be reset by a call to psa_cipher_abort(). The - * application may call psa_cipher_abort() at any time after the operation - * has been initialized. - * - * After a successful call to psa_cipher_decrypt_setup(), the application must - * eventually terminate the operation. The following events terminate an - * operation: - * - A successful call to psa_cipher_finish(). - * - A call to psa_cipher_abort(). - * - * \param[in,out] operation The operation object to set up. It must have - * been initialized as per the documentation for - * #psa_cipher_operation_t and not yet in use. - * \param key Identifier of the key to use for the operation. - * It must remain valid until the operation - * terminates. It must allow the usage - * #PSA_KEY_USAGE_DECRYPT. - * \param alg The cipher algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_CIPHER(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not compatible with \p alg. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg); - -/** Generate an IV for a symmetric encryption operation. - * - * This function generates a random IV (initialization vector), nonce - * or initial counter value for the encryption operation as appropriate - * for the chosen algorithm, key type and key size. - * - * The application must call psa_cipher_encrypt_setup() before - * calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_cipher_abort(). - * - * \param[in,out] operation Active cipher operation. - * \param[out] iv Buffer where the generated IV is to be written. - * \param iv_size Size of the \p iv buffer in bytes. - * \param[out] iv_length On success, the number of bytes of the - * generated IV. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p iv buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, with no IV set), - * or the library has not been previously initialized - * by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, - uint8_t *iv, - size_t iv_size, - size_t *iv_length); - -/** Set the IV for a symmetric encryption or decryption operation. - * - * This function sets the IV (initialization vector), nonce - * or initial counter value for the encryption or decryption operation. - * - * The application must call psa_cipher_encrypt_setup() before - * calling this function. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_cipher_abort(). - * - * \note When encrypting, applications should use psa_cipher_generate_iv() - * instead of this function, unless implementing a protocol that requires - * a non-random IV. - * - * \param[in,out] operation Active cipher operation. - * \param[in] iv Buffer containing the IV to use. - * \param iv_length Size of the IV in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size of \p iv is not acceptable for the chosen algorithm, - * or the chosen algorithm does not use an IV. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be an active cipher - * encrypt operation, with no IV set), or the library has not been - * previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, - const uint8_t *iv, - size_t iv_length); - -/** Encrypt or decrypt a message fragment in an active cipher operation. - * - * Before calling this function, you must: - * 1. Call either psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup(). - * The choice of setup function determines whether this function - * encrypts or decrypts its input. - * 2. If the algorithm requires an IV, call psa_cipher_generate_iv() - * (recommended when encrypting) or psa_cipher_set_iv(). - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_cipher_abort(). - * - * \param[in,out] operation Active cipher operation. - * \param[in] input Buffer containing the message fragment to - * encrypt or decrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[out] output Buffer where the output is to be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, with an IV set - * if required for the algorithm), or the library has not been - * previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Finish encrypting or decrypting a message in a cipher operation. - * - * The application must call psa_cipher_encrypt_setup() or - * psa_cipher_decrypt_setup() before calling this function. The choice - * of setup function determines whether this function encrypts or - * decrypts its input. - * - * This function finishes the encryption or decryption of the message - * formed by concatenating the inputs passed to preceding calls to - * psa_cipher_update(). - * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_cipher_abort(). - * - * \param[in,out] operation Active cipher operation. - * \param[out] output Buffer where the output is to be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The total input size passed to this operation is not valid for - * this particular algorithm. For example, the algorithm is a based - * on block cipher and requires a whole number of blocks, but the - * total input size is not a multiple of the block size. - * \retval #PSA_ERROR_INVALID_PADDING - * This is a decryption operation for an algorithm that includes - * padding, and the ciphertext does not contain valid padding. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active, with an IV set - * if required for the algorithm), or the library has not been - * previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Abort a cipher operation. - * - * Aborting an operation frees all associated resources except for the - * \p operation structure itself. Once aborted, the operation object - * can be reused for another operation by calling - * psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup() again. - * - * You may call this function any time after the operation object has - * been initialized as described in #psa_cipher_operation_t. - * - * In particular, calling psa_cipher_abort() after the operation has been - * terminated by a call to psa_cipher_abort() or psa_cipher_finish() - * is safe and has no effect. - * - * \param[in,out] operation Initialized cipher operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); - -/** \defgroup key_derivation Key derivation and pseudorandom generation - * @{ - */ - -/** The type of the state data structure for key derivation operations. - * - * Before calling any function on a key derivation operation object, the - * application must initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * \code - * psa_key_derivation_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * \endcode - * - Initialize the structure to logical zero values, for example: - * \code - * psa_key_derivation_operation_t operation = {0}; - * \endcode - * - Initialize the structure to the initializer #PSA_KEY_DERIVATION_OPERATION_INIT, - * for example: - * \code - * psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; - * \endcode - * - Assign the result of the function psa_key_derivation_operation_init() - * to the structure, for example: - * \code - * psa_key_derivation_operation_t operation; - * operation = psa_key_derivation_operation_init(); - * \endcode - * - * This is an implementation-defined \c struct. Applications should not - * make any assumptions about the content of this structure. - * Implementation details can change in future versions without notice. - */ -typedef struct psa_key_derivation_s psa_key_derivation_operation_t; - -/** \def PSA_KEY_DERIVATION_OPERATION_INIT - * - * This macro returns a suitable initializer for a key derivation operation - * object of type #psa_key_derivation_operation_t. - */ - -/** Return an initial value for a key derivation operation object. - */ -static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); - -/** Set up a key derivation operation. - * - * A key derivation algorithm takes some inputs and uses them to generate - * a byte stream in a deterministic way. - * This byte stream can be used to produce keys and other - * cryptographic material. - * - * To derive a key: - * -# Start with an initialized object of type #psa_key_derivation_operation_t. - * -# Call psa_key_derivation_setup() to select the algorithm. - * -# Provide the inputs for the key derivation by calling - * psa_key_derivation_input_bytes() or psa_key_derivation_input_key() - * as appropriate. Which inputs are needed, in what order, and whether - * they may be keys and if so of what type depends on the algorithm. - * -# Optionally set the operation's maximum capacity with - * psa_key_derivation_set_capacity(). You may do this before, in the middle - * of or after providing inputs. For some algorithms, this step is mandatory - * because the output depends on the maximum capacity. - * -# To derive a key, call psa_key_derivation_output_key() or - * psa_key_derivation_output_key_ext(). - * To derive a byte string for a different purpose, call - * psa_key_derivation_output_bytes(). - * Successive calls to these functions use successive output bytes - * calculated by the key derivation algorithm. - * -# Clean up the key derivation operation object with - * psa_key_derivation_abort(). - * - * If this function returns an error, the key derivation operation object is - * not changed. - * - * If an error occurs at any step after a call to psa_key_derivation_setup(), - * the operation will need to be reset by a call to psa_key_derivation_abort(). - * - * Implementations must reject an attempt to derive a key of size 0. - * - * \param[in,out] operation The key derivation operation object - * to set up. It must - * have been initialized but not set up yet. - * \param alg The key derivation algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c alg is not a key derivation algorithm. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \c alg is not supported or is not a key derivation algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be inactive), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_setup( - psa_key_derivation_operation_t *operation, - psa_algorithm_t alg); - -/** Retrieve the current capacity of a key derivation operation. - * - * The capacity of a key derivation is the maximum number of bytes that it can - * return. When you get *N* bytes of output from a key derivation operation, - * this reduces its capacity by *N*. - * - * \param[in] operation The operation to query. - * \param[out] capacity On success, the capacity of the operation. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_get_capacity( - const psa_key_derivation_operation_t *operation, - size_t *capacity); - -/** Set the maximum capacity of a key derivation operation. - * - * The capacity of a key derivation operation is the maximum number of bytes - * that the key derivation operation can return from this point onwards. - * - * \param[in,out] operation The key derivation operation object to modify. - * \param capacity The new capacity of the operation. - * It must be less or equal to the operation's - * current capacity. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p capacity is larger than the operation's current capacity. - * In this case, the operation object remains valid and its capacity - * remains unchanged. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active), or the - * library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_set_capacity( - psa_key_derivation_operation_t *operation, - size_t capacity); - -/** Use the maximum possible capacity for a key derivation operation. - * - * Use this value as the capacity argument when setting up a key derivation - * to indicate that the operation should have the maximum possible capacity. - * The value of the maximum possible capacity depends on the key derivation - * algorithm. - */ -#define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY ((size_t) (-1)) - -/** Provide an input for key derivation or key agreement. - * - * Which inputs are required and in what order depends on the algorithm. - * Refer to the documentation of each key derivation or key agreement - * algorithm for information. - * - * This function passes direct inputs, which is usually correct for - * non-secret inputs. To pass a secret input, which should be in a key - * object, call psa_key_derivation_input_key() instead of this function. - * Refer to the documentation of individual step types - * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) - * for more information. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to use. - * It must have been set up with - * psa_key_derivation_setup() and must not - * have produced any output yet. - * \param step Which step the input data is for. - * \param[in] data Input data to use. - * \param data_length Size of the \p data buffer in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c step is not compatible with the operation's algorithm, or - * \c step does not allow direct inputs. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid for this input \p step, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_input_bytes( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - const uint8_t *data, - size_t data_length); - -/** Provide a numeric input for key derivation or key agreement. - * - * Which inputs are required and in what order depends on the algorithm. - * However, when an algorithm requires a particular order, numeric inputs - * usually come first as they tend to be configuration parameters. - * Refer to the documentation of each key derivation or key agreement - * algorithm for information. - * - * This function is used for inputs which are fixed-size non-negative - * integers. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to use. - * It must have been set up with - * psa_key_derivation_setup() and must not - * have produced any output yet. - * \param step Which step the input data is for. - * \param[in] value The value of the numeric input. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c step is not compatible with the operation's algorithm, or - * \c step does not allow numeric inputs. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid for this input \p step, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_input_integer( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - uint64_t value); - -/** Provide an input for key derivation in the form of a key. - * - * Which inputs are required and in what order depends on the algorithm. - * Refer to the documentation of each key derivation or key agreement - * algorithm for information. - * - * This function obtains input from a key object, which is usually correct for - * secret inputs or for non-secret personalization strings kept in the key - * store. To pass a non-secret parameter which is not in the key store, - * call psa_key_derivation_input_bytes() instead of this function. - * Refer to the documentation of individual step types - * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) - * for more information. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to use. - * It must have been set up with - * psa_key_derivation_setup() and must not - * have produced any output yet. - * \param step Which step the input data is for. - * \param key Identifier of the key. It must have an - * appropriate type for step and must allow the - * usage #PSA_KEY_USAGE_DERIVE or - * #PSA_KEY_USAGE_VERIFY_DERIVATION (see note) - * and the algorithm used by the operation. - * - * \note Once all inputs steps are completed, the operations will allow: - * - psa_key_derivation_output_bytes() if each input was either a direct input - * or a key with #PSA_KEY_USAGE_DERIVE set; - * - psa_key_derivation_output_key() or psa_key_derivation_output_key_ext() - * if the input for step - * #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD - * was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was - * either a direct input or a key with #PSA_KEY_USAGE_DERIVE set; - * - psa_key_derivation_verify_bytes() if each input was either a direct input - * or a key with #PSA_KEY_USAGE_VERIFY_DERIVATION set; - * - psa_key_derivation_verify_key() under the same conditions as - * psa_key_derivation_verify_bytes(). - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key allows neither #PSA_KEY_USAGE_DERIVE nor - * #PSA_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this - * algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c step is not compatible with the operation's algorithm, or - * \c step does not allow key inputs of the given type - * or does not allow key inputs at all. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid for this input \p step, or - * the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_input_key( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - mbedtls_svc_key_id_t key); - -/** Perform a key agreement and use the shared secret as input to a key - * derivation. - * - * A key agreement algorithm takes two inputs: a private key \p private_key - * a public key \p peer_key. - * The result of this function is passed as input to a key derivation. - * The output of this key derivation can be extracted by reading from the - * resulting operation to produce keys and other cryptographic material. - * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to use. - * It must have been set up with - * psa_key_derivation_setup() with a - * key agreement and derivation algorithm - * \c alg (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_KEY_AGREEMENT(\c alg) is true - * and #PSA_ALG_IS_RAW_KEY_AGREEMENT(\c alg) - * is false). - * The operation must be ready for an - * input of the type given by \p step. - * \param step Which step the input data is for. - * \param private_key Identifier of the private key to use. It must - * allow the usage #PSA_KEY_USAGE_DERIVE. - * \param[in] peer_key Public key of the peer. The peer key must be in the - * same format that psa_import_key() accepts for the - * public key type corresponding to the type of - * private_key. That is, this function performs the - * equivalent of - * #psa_import_key(..., - * `peer_key`, `peer_key_length`) where - * with key attributes indicating the public key - * type corresponding to the type of `private_key`. - * For example, for EC keys, this means that peer_key - * is interpreted as a point on the curve that the - * private key is on. The standard formats for public - * keys are documented in the documentation of - * psa_export_public_key(). - * \param peer_key_length Size of \p peer_key in bytes. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c private_key is not compatible with \c alg, - * or \p peer_key is not valid for \c alg or not compatible with - * \c private_key, or \c step does not allow an input resulting - * from a key agreement. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \c alg is not supported or is not a key derivation algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid for this key agreement \p step, - * or the library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_key_agreement( - psa_key_derivation_operation_t *operation, - psa_key_derivation_step_t step, - mbedtls_svc_key_id_t private_key, - const uint8_t *peer_key, - size_t peer_key_length); - -/** Read some data from a key derivation operation. - * - * This function calculates output bytes from a key derivation algorithm and - * return those bytes. - * If you view the key derivation's output as a stream of bytes, this - * function destructively reads the requested number of bytes from the - * stream. - * The operation's capacity decreases by the number of bytes read. - * - * If this function returns an error status other than - * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to read from. - * \param[out] output Buffer where the output will be written. - * \param output_length Number of bytes to output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * One of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_DERIVE. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * The operation's capacity was less than - * \p output_length bytes. Note that in this case, - * no output is written to the output buffer. - * The operation's capacity is set to 0, thus - * subsequent calls to this function will not - * succeed, even with a smaller output buffer. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_output_bytes( - psa_key_derivation_operation_t *operation, - uint8_t *output, - size_t output_length); - -/** Derive a key from an ongoing key derivation operation. - * - * This function calculates output bytes from a key derivation algorithm - * and uses those bytes to generate a key deterministically. - * The key's location, usage policy, type and size are taken from - * \p attributes. - * - * If you view the key derivation's output as a stream of bytes, this - * function destructively reads as many bytes as required from the - * stream. - * The operation's capacity decreases by the number of bytes read. - * - * If this function returns an error status other than - * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error - * state and must be aborted by calling psa_key_derivation_abort(). - * - * How much output is produced and consumed from the operation, and how - * the key is derived, depends on the key type and on the key size - * (denoted \c bits below): - * - * - For key types for which the key is an arbitrary sequence of bytes - * of a given size, this function is functionally equivalent to - * calling #psa_key_derivation_output_bytes - * and passing the resulting output to #psa_import_key. - * However, this function has a security benefit: - * if the implementation provides an isolation boundary then - * the key material is not exposed outside the isolation boundary. - * As a consequence, for these key types, this function always consumes - * exactly (\c bits / 8) bytes from the operation. - * The following key types defined in this specification follow this scheme: - * - * - #PSA_KEY_TYPE_AES; - * - #PSA_KEY_TYPE_ARIA; - * - #PSA_KEY_TYPE_CAMELLIA; - * - #PSA_KEY_TYPE_DERIVE; - * - #PSA_KEY_TYPE_HMAC; - * - #PSA_KEY_TYPE_PASSWORD_HASH. - * - * - For ECC keys on a Montgomery elliptic curve - * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a - * Montgomery curve), this function always draws a byte string whose - * length is determined by the curve, and sets the mandatory bits - * accordingly. That is: - * - * - Curve25519 (#PSA_ECC_FAMILY_MONTGOMERY, 255 bits): draw a 32-byte - * string and process it as specified in RFC 7748 §5. - * - Curve448 (#PSA_ECC_FAMILY_MONTGOMERY, 448 bits): draw a 56-byte - * string and process it as specified in RFC 7748 §5. - * - * - For key types for which the key is represented by a single sequence of - * \c bits bits with constraints as to which bit sequences are acceptable, - * this function draws a byte string of length (\c bits / 8) bytes rounded - * up to the nearest whole number of bytes. If the resulting byte string - * is acceptable, it becomes the key, otherwise the drawn bytes are discarded. - * This process is repeated until an acceptable byte string is drawn. - * The byte string drawn from the operation is interpreted as specified - * for the output produced by psa_export_key(). - * The following key types defined in this specification follow this scheme: - * - * - #PSA_KEY_TYPE_DES. - * Force-set the parity bits, but discard forbidden weak keys. - * For 2-key and 3-key triple-DES, the three keys are generated - * successively (for example, for 3-key triple-DES, - * if the first 8 bytes specify a weak key and the next 8 bytes do not, - * discard the first 8 bytes, use the next 8 bytes as the first key, - * and continue reading output from the operation to derive the other - * two keys). - * - Finite-field Diffie-Hellman keys (#PSA_KEY_TYPE_DH_KEY_PAIR(\c group) - * where \c group designates any Diffie-Hellman group) and - * ECC keys on a Weierstrass elliptic curve - * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a - * Weierstrass curve). - * For these key types, interpret the byte string as integer - * in big-endian order. Discard it if it is not in the range - * [0, *N* - 2] where *N* is the boundary of the private key domain - * (the prime *p* for Diffie-Hellman, the subprime *q* for DSA, - * or the order of the curve's base point for ECC). - * Add 1 to the resulting integer and use this as the private key *x*. - * This method allows compliance to NIST standards, specifically - * the methods titled "key-pair generation by testing candidates" - * in NIST SP 800-56A §5.6.1.1.4 for Diffie-Hellman, - * in FIPS 186-4 §B.1.2 for DSA, and - * in NIST SP 800-56A §5.6.1.2.2 or - * FIPS 186-4 §B.4.2 for elliptic curve keys. - * - * - For other key types, including #PSA_KEY_TYPE_RSA_KEY_PAIR, - * the way in which the operation output is consumed is - * implementation-defined. - * - * In all cases, the data that is read is discarded from the operation. - * The operation's capacity is decreased by the number of bytes read. - * - * For algorithms that take an input step #PSA_KEY_DERIVATION_INPUT_SECRET, - * the input to that step must be provided with psa_key_derivation_input_key(). - * Future versions of this specification may include additional restrictions - * on the derived key based on the attributes and strength of the secret key. - * - * \note This function is equivalent to calling - * psa_key_derivation_output_key_ext() - * with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT - * and `params_data_length == 0` (i.e. `params->data` is empty). - * - * \param[in] attributes The attributes for the new key. - * If the key type to be created is - * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in - * the policy must be the same as in the current - * operation. - * \param[in,out] operation The key derivation operation object to read from. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * There was not enough data to create the desired key. - * Note that in this case, no output is written to the output buffer. - * The operation's capacity is set to 0, thus subsequent calls to - * this function will not succeed, even with a smaller output buffer. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The key type or key size is not supported, either by the - * implementation in general or in this particular location. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The provided key attributes are not valid for the operation. - * \retval #PSA_ERROR_NOT_PERMITTED - * The #PSA_KEY_DERIVATION_INPUT_SECRET or - * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a - * key; or one of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_DERIVE. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_output_key( - const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - mbedtls_svc_key_id_t *key); - -/** Derive a key from an ongoing key derivation operation with custom - * production parameters. - * - * See the description of psa_key_derivation_out_key() for the operation of - * this function with the default production parameters. - * Mbed TLS currently does not currently support any non-default production - * parameters. - * - * \note This function is experimental and may change in future minor - * versions of Mbed TLS. - * - * \param[in] attributes The attributes for the new key. - * If the key type to be created is - * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in - * the policy must be the same as in the current - * operation. - * \param[in,out] operation The key derivation operation object to read from. - * \param[in] params Customization parameters for the key derivation. - * When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT - * with \p params_data_length = 0, - * this function is equivalent to - * psa_key_derivation_output_key(). - * Mbed TLS currently only supports the default - * production parameters, i.e. - * #PSA_KEY_PRODUCTION_PARAMETERS_INIT, - * for all key types. - * \param params_data_length - * Length of `params->data` in bytes. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * There was not enough data to create the desired key. - * Note that in this case, no output is written to the output buffer. - * The operation's capacity is set to 0, thus subsequent calls to - * this function will not succeed, even with a smaller output buffer. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The key type or key size is not supported, either by the - * implementation in general or in this particular location. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The provided key attributes are not valid for the operation. - * \retval #PSA_ERROR_NOT_PERMITTED - * The #PSA_KEY_DERIVATION_INPUT_SECRET or - * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a - * key; or one of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_DERIVE. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_output_key_ext( - const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - const psa_key_production_parameters_t *params, - size_t params_data_length, - mbedtls_svc_key_id_t *key); - -/** Compare output data from a key derivation operation to an expected value. - * - * This function calculates output bytes from a key derivation algorithm and - * compares those bytes to an expected value in constant time. - * If you view the key derivation's output as a stream of bytes, this - * function destructively reads the expected number of bytes from the - * stream before comparing them. - * The operation's capacity decreases by the number of bytes read. - * - * This is functionally equivalent to the following code: - * \code - * psa_key_derivation_output_bytes(operation, tmp, output_length); - * if (memcmp(output, tmp, output_length) != 0) - * return PSA_ERROR_INVALID_SIGNATURE; - * \endcode - * except (1) it works even if the key's policy does not allow outputting the - * bytes, and (2) the comparison will be done in constant time. - * - * If this function returns an error status other than - * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE, - * the operation enters an error state and must be aborted by calling - * psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to read from. - * \param[in] expected_output Buffer containing the expected derivation output. - * \param output_length Length of the expected output; this is also the - * number of bytes that will be read. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The output was read successfully, but it differs from the expected - * output. - * \retval #PSA_ERROR_NOT_PERMITTED - * One of the inputs was a key whose policy didn't allow - * #PSA_KEY_USAGE_VERIFY_DERIVATION. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * The operation's capacity was less than - * \p output_length bytes. Note that in this case, - * the operation's capacity is set to 0, thus - * subsequent calls to this function will not - * succeed, even with a smaller expected output. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_verify_bytes( - psa_key_derivation_operation_t *operation, - const uint8_t *expected_output, - size_t output_length); - -/** Compare output data from a key derivation operation to an expected value - * stored in a key object. - * - * This function calculates output bytes from a key derivation algorithm and - * compares those bytes to an expected value, provided as key of type - * #PSA_KEY_TYPE_PASSWORD_HASH. - * If you view the key derivation's output as a stream of bytes, this - * function destructively reads the number of bytes corresponding to the - * length of the expected value from the stream before comparing them. - * The operation's capacity decreases by the number of bytes read. - * - * This is functionally equivalent to exporting the key and calling - * psa_key_derivation_verify_bytes() on the result, except that it - * works even if the key cannot be exported. - * - * If this function returns an error status other than - * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE, - * the operation enters an error state and must be aborted by calling - * psa_key_derivation_abort(). - * - * \param[in,out] operation The key derivation operation object to read from. - * \param[in] expected A key of type #PSA_KEY_TYPE_PASSWORD_HASH - * containing the expected output. Its policy must - * include the #PSA_KEY_USAGE_VERIFY_DERIVATION flag - * and the permitted algorithm must match the - * operation. The value of this key was likely - * computed by a previous call to - * psa_key_derivation_output_key() or - * psa_key_derivation_output_key_ext(). - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The output was read successfully, but if differs from the expected - * output. - * \retval #PSA_ERROR_INVALID_HANDLE - * The key passed as the expected value does not exist. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key passed as the expected value has an invalid type. - * \retval #PSA_ERROR_NOT_PERMITTED - * The key passed as the expected value does not allow this usage or - * this algorithm; or one of the inputs was a key whose policy didn't - * allow #PSA_KEY_USAGE_VERIFY_DERIVATION. - * \retval #PSA_ERROR_INSUFFICIENT_DATA - * The operation's capacity was less than - * the length of the expected value. In this case, - * the operation's capacity is set to 0, thus - * subsequent calls to this function will not - * succeed, even with a smaller expected output. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The operation state is not valid (it must be active and completed - * all required input steps), or the library has not been previously - * initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_verify_key( - psa_key_derivation_operation_t *operation, - psa_key_id_t expected); - -/** Abort a key derivation operation. - * - * Aborting an operation frees all associated resources except for the \c - * operation structure itself. Once aborted, the operation object can be reused - * for another operation by calling psa_key_derivation_setup() again. - * - * This function may be called at any time after the operation - * object has been initialized as described in #psa_key_derivation_operation_t. - * - * In particular, it is valid to call psa_key_derivation_abort() twice, or to - * call psa_key_derivation_abort() on an operation that has not been set up. - * - * \param[in,out] operation The operation to abort. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation_abort( - psa_key_derivation_operation_t *operation); - -/** Perform a key agreement and return the raw shared secret. - * - * \warning The raw result of a key agreement algorithm such as finite-field - * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should - * not be used directly as key material. It should instead be passed as - * input to a key derivation algorithm. To chain a key agreement with - * a key derivation, use psa_key_derivation_key_agreement() and other - * functions from the key derivation interface. - * - * \param alg The key agreement algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_RAW_KEY_AGREEMENT(\p alg) - * is true). - * \param private_key Identifier of the private key to use. It must - * allow the usage #PSA_KEY_USAGE_DERIVE. - * \param[in] peer_key Public key of the peer. It must be - * in the same format that psa_import_key() - * accepts. The standard formats for public - * keys are documented in the documentation - * of psa_export_public_key(). - * \param peer_key_length Size of \p peer_key in bytes. - * \param[out] output Buffer where the decrypted message is to - * be written. - * \param output_size Size of the \c output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p alg is not a key agreement algorithm, or - * \p private_key is not compatible with \p alg, - * or \p peer_key is not valid for \p alg or not compatible with - * \p private_key. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \p output_size is too small - * \retval #PSA_ERROR_NOT_SUPPORTED - * \p alg is not a supported key agreement algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, - mbedtls_svc_key_id_t private_key, - const uint8_t *peer_key, - size_t peer_key_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** - * \brief Generate a key or key pair. - * - * The key is generated randomly. - * Its location, usage policy, type and size are taken from \p attributes. - * - * Implementations must reject an attempt to generate a key of size 0. - * - * The following type-specific considerations apply: - * - For RSA keys (#PSA_KEY_TYPE_RSA_KEY_PAIR), - * the public exponent is 65537. - * The modulus is a product of two probabilistic primes - * between 2^{n-1} and 2^n where n is the bit size specified in the - * attributes. - * - * \note This function is equivalent to calling psa_generate_key_ext() - * with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT - * and `params_data_length == 0` (i.e. `params->data` is empty). - * - * \param[in] attributes The attributes for the new key. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *key); - -/** - * \brief Generate a key or key pair using custom production parameters. - * - * See the description of psa_generate_key() for the operation of this - * function with the default production parameters. In addition, this function - * supports the following production customizations, described in more detail - * in the documentation of ::psa_key_production_parameters_t: - * - * - RSA keys: generation with a custom public exponent. - * - * \note This function is experimental and may change in future minor - * versions of Mbed TLS. - * - * \param[in] attributes The attributes for the new key. - * \param[in] params Customization parameters for the key generation. - * When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT - * with \p params_data_length = 0, - * this function is equivalent to - * psa_generate_key(). - * \param params_data_length - * Length of `params->data` in bytes. - * \param[out] key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS - * Success. - * If the key is persistent, the key material and the key's metadata - * have been saved to persistent storage. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, - const psa_key_production_parameters_t *params, - size_t params_data_length, - mbedtls_svc_key_id_t *key); - -/** - * \brief Sign a message with a private key. For hash-and-sign algorithms, - * this includes the hashing step. - * - * \note To perform a multi-part hash-and-sign signature algorithm, first use - * a multi-part hash operation and then pass the resulting hash to - * psa_sign_hash(). PSA_ALG_GET_HASH(\p alg) can be used to determine the - * hash algorithm to use. - * - * \param[in] key Identifier of the key to use for the operation. - * It must be an asymmetric key pair. The key must - * allow the usage #PSA_KEY_USAGE_SIGN_MESSAGE. - * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) - * is true), that is compatible with the type of - * \p key. - * \param[in] input The input message to sign. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[out] signature Buffer where the signature is to be written. - * \param[in] signature_size Size of the \p signature buffer in bytes. This - * must be appropriate for the selected - * algorithm and key: - * - The required signature size is - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and - * bit-size respectively of key. - * - #PSA_SIGNATURE_MAX_SIZE evaluates to the - * maximum signature size of any supported - * signature algorithm. - * \param[out] signature_length On success, the number of bytes that make up - * the returned signature value. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, - * or it does not permit the requested algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length); - -/** \brief Verify the signature of a message with a public key, using - * a hash-and-sign verification algorithm. - * - * \note To perform a multi-part hash-and-sign signature verification - * algorithm, first use a multi-part hash operation to hash the message - * and then pass the resulting hash to psa_verify_hash(). - * PSA_ALG_GET_HASH(\p alg) can be used to determine the hash algorithm - * to use. - * - * \param[in] key Identifier of the key to use for the operation. - * It must be a public key or an asymmetric key - * pair. The key must allow the usage - * #PSA_KEY_USAGE_VERIFY_MESSAGE. - * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) - * is true), that is compatible with the type of - * \p key. - * \param[in] input The message whose signature is to be verified. - * \param[in] input_length Size of the \p input buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param[in] signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, - * or it does not permit the requested algorithm. - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed signature - * is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *signature, - size_t signature_length); - -/** - * \brief Sign a hash or short message with a private key. - * - * Note that to perform a hash-and-sign signature algorithm, you must - * first calculate the hash by calling psa_hash_setup(), psa_hash_update() - * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). - * Then pass the resulting hash as the \p hash - * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) - * to determine the hash algorithm to use. - * - * \param key Identifier of the key to use for the operation. - * It must be an asymmetric key pair. The key must - * allow the usage #PSA_KEY_USAGE_SIGN_HASH. - * \param alg A signature algorithm (PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) - * is true), that is compatible with - * the type of \p key. - * \param[in] hash The hash or message to sign. - * \param hash_length Size of the \p hash buffer in bytes. - * \param[out] signature Buffer where the signature is to be written. - * \param signature_size Size of the \p signature buffer in bytes. - * \param[out] signature_length On success, the number of bytes - * that make up the returned signature value. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - uint8_t *signature, - size_t signature_size, - size_t *signature_length); - -/** - * \brief Verify the signature of a hash or short message using a public key. - * - * Note that to perform a hash-and-sign signature algorithm, you must - * first calculate the hash by calling psa_hash_setup(), psa_hash_update() - * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). - * Then pass the resulting hash as the \p hash - * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) - * to determine the hash algorithm to use. - * - * \param key Identifier of the key to use for the operation. It - * must be a public key or an asymmetric key pair. The - * key must allow the usage - * #PSA_KEY_USAGE_VERIFY_HASH. - * \param alg A signature algorithm (PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) - * is true), that is compatible with - * the type of \p key. - * \param[in] hash The hash or message whose signature is to be - * verified. - * \param hash_length Size of the \p hash buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The signature is valid. - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *hash, - size_t hash_length, - const uint8_t *signature, - size_t signature_length); - -/** - * \brief Encrypt a short message with a public key. - * - * \param key Identifier of the key to use for the operation. - * It must be a public key or an asymmetric key - * pair. It must allow the usage - * #PSA_KEY_USAGE_ENCRYPT. - * \param alg An asymmetric encryption algorithm that is - * compatible with the type of \p key. - * \param[in] input The message to encrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] salt A salt or label, if supported by the - * encryption algorithm. - * If the algorithm does not support a - * salt, pass \c NULL. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass \c NULL. - * - * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param salt_length Size of the \p salt buffer in bytes. - * If \p salt is \c NULL, pass 0. - * \param[out] output Buffer where the encrypted message is to - * be written. - * \param output_size Size of the \p output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *salt, - size_t salt_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** - * \brief Decrypt a short message with a private key. - * - * \param key Identifier of the key to use for the operation. - * It must be an asymmetric key pair. It must - * allow the usage #PSA_KEY_USAGE_DECRYPT. - * \param alg An asymmetric encryption algorithm that is - * compatible with the type of \p key. - * \param[in] input The message to decrypt. - * \param input_length Size of the \p input buffer in bytes. - * \param[in] salt A salt or label, if supported by the - * encryption algorithm. - * If the algorithm does not support a - * salt, pass \c NULL. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass \c NULL. - * - * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param salt_length Size of the \p salt buffer in bytes. - * If \p salt is \c NULL, pass 0. - * \param[out] output Buffer where the decrypted message is to - * be written. - * \param output_size Size of the \c output buffer in bytes. - * \param[out] output_length On success, the number of bytes - * that make up the returned output. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p output buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_INVALID_PADDING \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - const uint8_t *salt, - size_t salt_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -/** Remove non-essential copies of key material from memory. - * - * If the key identifier designates a volatile key, this functions does not do - * anything and returns successfully. - * - * If the key identifier designates a persistent key, then this function will - * free all resources associated with the key in volatile memory. The key - * data in persistent storage is not affected and the key can still be used. - * - * \param key Identifier of the key to purge. - * - * \retval #PSA_SUCCESS - * The key material will have been removed from memory if it is not - * currently required. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p key is not a valid key identifier. - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); - -/** - * \brief Export a key in binary format. - * - * The output of this function can be passed to psa_import_key() to - * create an equivalent object. - * - * If the implementation of psa_import_key() supports other formats - * beyond the format specified here, the output from psa_export_key() - * must use the representation specified here, not the original - * representation. - * - * For standard key types, the output format is as follows: - * - * - For symmetric keys (including MAC keys), the format is the - * raw bytes of the key. - * - For DES, the key data consists of 8 bytes. The parity bits must be - * correct. - * - For Triple-DES, the format is the concatenation of the - * two or three DES keys. - * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEY_PAIR), the format - * is the non-encrypted DER encoding of the representation defined by - * PKCS\#1 (RFC 8017) as `RSAPrivateKey`, version 0. - * ``` - * RSAPrivateKey ::= SEQUENCE { - * version INTEGER, -- must be 0 - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER, -- (inverse of q) mod p - * } - * ``` - * - For elliptic curve key pairs (key types for which - * #PSA_KEY_TYPE_IS_ECC_KEY_PAIR is true), the format is - * a representation of the private value as a `ceiling(m/8)`-byte string - * where `m` is the bit size associated with the curve, i.e. the bit size - * of the order of the curve's coordinate field. This byte string is - * in little-endian order for Montgomery curves (curve types - * `PSA_ECC_FAMILY_CURVEXXX`), and in big-endian order for Weierstrass - * curves (curve types `PSA_ECC_FAMILY_SECTXXX`, `PSA_ECC_FAMILY_SECPXXX` - * and `PSA_ECC_FAMILY_BRAINPOOL_PXXX`). - * For Weierstrass curves, this is the content of the `privateKey` field of - * the `ECPrivateKey` format defined by RFC 5915. For Montgomery curves, - * the format is defined by RFC 7748, and output is masked according to §5. - * For twisted Edwards curves, the private key is as defined by RFC 8032 - * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). - * - For Diffie-Hellman key exchange key pairs (key types for which - * #PSA_KEY_TYPE_IS_DH_KEY_PAIR is true), the - * format is the representation of the private key `x` as a big-endian byte - * string. The length of the byte string is the private key size in bytes - * (leading zeroes are not stripped). - * - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is - * true), the format is the same as for psa_export_public_key(). - * - * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set. - * - * \param key Identifier of the key to export. It must allow the - * usage #PSA_KEY_USAGE_EXPORT, unless it is a public - * key. - * \param[out] data Buffer where the key data is to be written. - * \param data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes - * that make up the key data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_EXPORT flag. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p data buffer is too small. You can determine a - * sufficient buffer size by calling - * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits) - * where \c type is the key type - * and \c bits is the key size in bits. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_export_key(mbedtls_svc_key_id_t key, - uint8_t *data, - size_t data_size, - size_t *data_length); - -/** - * \brief Export a public key or the public part of a key pair in binary format. - * - * The output of this function can be passed to psa_import_key() to - * create an object that is equivalent to the public key. - * - * This specification supports a single format for each key type. - * Implementations may support other formats as long as the standard - * format is supported. Implementations that support other formats - * should ensure that the formats are clearly unambiguous so as to - * minimize the risk that an invalid input is accidentally interpreted - * according to a different format. - * - * For standard key types, the output format is as follows: - * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of - * the representation defined by RFC 3279 §2.3.1 as `RSAPublicKey`. - * ``` - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER } -- e - * ``` - * - For elliptic curve keys on a twisted Edwards curve (key types for which - * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true and #PSA_KEY_TYPE_ECC_GET_FAMILY - * returns #PSA_ECC_FAMILY_TWISTED_EDWARDS), the public key is as defined - * by RFC 8032 - * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). - * - For other elliptic curve public keys (key types for which - * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed - * representation defined by SEC1 §2.3.3 as the content of an ECPoint. - * Let `m` be the bit size associated with the curve, i.e. the bit size of - * `q` for a curve over `F_q`. The representation consists of: - * - The byte 0x04; - * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; - * - `y_P` as a `ceiling(m/8)`-byte string, big-endian. - * - For Diffie-Hellman key exchange public keys (key types for which - * #PSA_KEY_TYPE_IS_DH_PUBLIC_KEY is true), - * the format is the representation of the public key `y = g^x mod p` as a - * big-endian byte string. The length of the byte string is the length of the - * base prime `p` in bytes. - * - * Exporting a public key object or the public part of a key pair is - * always permitted, regardless of the key's usage flags. - * - * \param key Identifier of the key to export. - * \param[out] data Buffer where the key data is to be written. - * \param data_size Size of the \p data buffer in bytes. - * \param[out] data_length On success, the number of bytes - * that make up the key data. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key is neither a public key nor a key pair. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p data buffer is too small. You can determine a - * sufficient buffer size by calling - * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits) - * where \c type is the key type - * and \c bits is the key size in bits. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, - uint8_t *data, - size_t data_size, - size_t *data_length); - -/** - * \brief Set the maximum number of ops allowed to be - * executed by an interruptible function in a - * single call. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note The time taken to execute a single op is - * implementation specific and depends on - * software, hardware, the algorithm, key type and - * curve chosen. Even within a single operation, - * successive ops can take differing amounts of - * time. The only guarantee is that lower values - * for \p max_ops means functions will block for a - * lesser maximum amount of time. The functions - * \c psa_sign_interruptible_get_num_ops() and - * \c psa_verify_interruptible_get_num_ops() are - * provided to help with tuning this value. - * - * \note This value defaults to - * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, which - * means the whole operation will be done in one - * go, regardless of the number of ops required. - * - * \note If more ops are needed to complete a - * computation, #PSA_OPERATION_INCOMPLETE will be - * returned by the function performing the - * computation. It is then the caller's - * responsibility to either call again with the - * same operation context until it returns 0 or an - * error code; or to call the relevant abort - * function if the answer is no longer required. - * - * \note The interpretation of \p max_ops is also - * implementation defined. On a hard real time - * system, this can indicate a hard deadline, as a - * real-time system needs a guarantee of not - * spending more than X time, however care must be - * taken in such an implementation to avoid the - * situation whereby calls just return, not being - * able to do any actual work within the allotted - * time. On a non-real-time system, the - * implementation can be more relaxed, but again - * whether this number should be interpreted as as - * hard or soft limit or even whether a less than - * or equals as regards to ops executed in a - * single call is implementation defined. - * - * \note For keys in local storage when no accelerator - * driver applies, please see also the - * documentation for \c mbedtls_ecp_set_max_ops(), - * which is the internal implementation in these - * cases. - * - * \warning With implementations that interpret this number - * as a hard limit, setting this number too small - * may result in an infinite loop, whereby each - * call results in immediate return with no ops - * done (as there is not enough time to execute - * any), and thus no result will ever be achieved. - * - * \note This only applies to functions whose - * documentation mentions they may return - * #PSA_OPERATION_INCOMPLETE. - * - * \param max_ops The maximum number of ops to be executed in a - * single call. This can be a number from 0 to - * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0 - * is the least amount of work done per call. - */ -void psa_interruptible_set_max_ops(uint32_t max_ops); - -/** - * \brief Get the maximum number of ops allowed to be - * executed by an interruptible function in a - * single call. This will return the last - * value set by - * \c psa_interruptible_set_max_ops() or - * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED if - * that function has never been called. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \return Maximum number of ops allowed to be - * executed by an interruptible function in a - * single call. - */ -uint32_t psa_interruptible_get_max_ops(void); - -/** - * \brief Get the number of ops that a hash signing - * operation has taken so far. If the operation - * has completed, then this will represent the - * number of ops required for the entire - * operation. After initialization or calling - * \c psa_sign_hash_interruptible_abort() on - * the operation, a value of 0 will be returned. - * - * \note This interface is guaranteed re-entrant and - * thus may be called from driver code. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * This is a helper provided to help you tune the - * value passed to \c - * psa_interruptible_set_max_ops(). - * - * \param operation The \c psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \return Number of ops that the operation has taken so - * far. - */ -uint32_t psa_sign_hash_get_num_ops( - const psa_sign_hash_interruptible_operation_t *operation); - -/** - * \brief Get the number of ops that a hash verification - * operation has taken so far. If the operation - * has completed, then this will represent the - * number of ops required for the entire - * operation. After initialization or calling \c - * psa_verify_hash_interruptible_abort() on the - * operation, a value of 0 will be returned. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * This is a helper provided to help you tune the - * value passed to \c - * psa_interruptible_set_max_ops(). - * - * \param operation The \c - * psa_verify_hash_interruptible_operation_t to - * use. This must be initialized first. - * - * \return Number of ops that the operation has taken so - * far. - */ -uint32_t psa_verify_hash_get_num_ops( - const psa_verify_hash_interruptible_operation_t *operation); - -/** - * \brief Start signing a hash or short message with a - * private key, in an interruptible manner. - * - * \see \c psa_sign_hash_complete() - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function combined with \c - * psa_sign_hash_complete() is equivalent to - * \c psa_sign_hash() but - * \c psa_sign_hash_complete() can return early and - * resume according to the limit set with \c - * psa_interruptible_set_max_ops() to reduce the - * maximum time spent in a function call. - * - * \note Users should call \c psa_sign_hash_complete() - * repeatedly on the same context after a - * successful call to this function until \c - * psa_sign_hash_complete() either returns 0 or an - * error. \c psa_sign_hash_complete() will return - * #PSA_OPERATION_INCOMPLETE if there is more work - * to do. Alternatively users can call - * \c psa_sign_hash_abort() at any point if they no - * longer want the result. - * - * \note If this function returns an error status, the - * operation enters an error state and must be - * aborted by calling \c psa_sign_hash_abort(). - * - * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \param key Identifier of the key to use for the operation. - * It must be an asymmetric key pair. The key must - * allow the usage #PSA_KEY_USAGE_SIGN_HASH. - * \param alg A signature algorithm (\c PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) - * is true), that is compatible with - * the type of \p key. - * \param[in] hash The hash or message to sign. - * \param hash_length Size of the \p hash buffer in bytes. - * - * \retval #PSA_SUCCESS - * The operation started successfully - call \c psa_sign_hash_complete() - * with the same context to complete the operation - * - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_SIGN_HASH flag, or it does - * not permit the requested algorithm. - * \retval #PSA_ERROR_BAD_STATE - * An operation has previously been started on this context, and is - * still in progress. - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_sign_hash_start( - psa_sign_hash_interruptible_operation_t *operation, - mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length); - -/** - * \brief Continue and eventually complete the action of - * signing a hash or short message with a private - * key, in an interruptible manner. - * - * \see \c psa_sign_hash_start() - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function combined with \c - * psa_sign_hash_start() is equivalent to - * \c psa_sign_hash() but this function can return - * early and resume according to the limit set with - * \c psa_interruptible_set_max_ops() to reduce the - * maximum time spent in a function call. - * - * \note Users should call this function on the same - * operation object repeatedly until it either - * returns 0 or an error. This function will return - * #PSA_OPERATION_INCOMPLETE if there is more work - * to do. Alternatively users can call - * \c psa_sign_hash_abort() at any point if they no - * longer want the result. - * - * \note When this function returns successfully, the - * operation becomes inactive. If this function - * returns an error status, the operation enters an - * error state and must be aborted by calling - * \c psa_sign_hash_abort(). - * - * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t - * to use. This must be initialized first, and have - * had \c psa_sign_hash_start() called with it - * first. - * - * \param[out] signature Buffer where the signature is to be written. - * \param signature_size Size of the \p signature buffer in bytes. This - * must be appropriate for the selected - * algorithm and key: - * - The required signature size is - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c - * key_bits, \c alg) where \c key_type and \c - * key_bits are the type and bit-size - * respectively of key. - * - #PSA_SIGNATURE_MAX_SIZE evaluates to the - * maximum signature size of any supported - * signature algorithm. - * \param[out] signature_length On success, the number of bytes that make up - * the returned signature value. - * - * \retval #PSA_SUCCESS - * Operation completed successfully - * - * \retval #PSA_OPERATION_INCOMPLETE - * Operation was interrupted due to the setting of \c - * psa_interruptible_set_max_ops(). There is still work to be done. - * Call this function again with the same operation object. - * - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of the \p signature buffer is too small. You can - * determine a sufficient buffer size by calling - * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \c alg) - * where \c key_type and \c key_bits are the type and bit-size - * respectively of \c key. - * - * \retval #PSA_ERROR_BAD_STATE - * An operation was not previously started on this context via - * \c psa_sign_hash_start(). - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has either not been previously initialized by - * psa_crypto_init() or you did not previously call - * psa_sign_hash_start() with this operation object. It is - * implementation-dependent whether a failure to initialize results in - * this error code. - */ -psa_status_t psa_sign_hash_complete( - psa_sign_hash_interruptible_operation_t *operation, - uint8_t *signature, size_t signature_size, - size_t *signature_length); - -/** - * \brief Abort a sign hash operation. - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function is the only function that clears - * the number of ops completed as part of the - * operation. Please ensure you copy this value via - * \c psa_sign_hash_get_num_ops() if required - * before calling. - * - * \note Aborting an operation frees all associated - * resources except for the \p operation structure - * itself. Once aborted, the operation object can - * be reused for another operation by calling \c - * psa_sign_hash_start() again. - * - * \note You may call this function any time after the - * operation object has been initialized. In - * particular, calling \c psa_sign_hash_abort() - * after the operation has already been terminated - * by a call to \c psa_sign_hash_abort() or - * psa_sign_hash_complete() is safe. - * - * \param[in,out] operation Initialized sign hash operation. - * - * \retval #PSA_SUCCESS - * The operation was aborted successfully. - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_sign_hash_abort( - psa_sign_hash_interruptible_operation_t *operation); - -/** - * \brief Start reading and verifying a hash or short - * message, in an interruptible manner. - * - * \see \c psa_verify_hash_complete() - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function combined with \c - * psa_verify_hash_complete() is equivalent to - * \c psa_verify_hash() but \c - * psa_verify_hash_complete() can return early and - * resume according to the limit set with \c - * psa_interruptible_set_max_ops() to reduce the - * maximum time spent in a function. - * - * \note Users should call \c psa_verify_hash_complete() - * repeatedly on the same operation object after a - * successful call to this function until \c - * psa_verify_hash_complete() either returns 0 or - * an error. \c psa_verify_hash_complete() will - * return #PSA_OPERATION_INCOMPLETE if there is - * more work to do. Alternatively users can call - * \c psa_verify_hash_abort() at any point if they - * no longer want the result. - * - * \note If this function returns an error status, the - * operation enters an error state and must be - * aborted by calling \c psa_verify_hash_abort(). - * - * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t - * to use. This must be initialized first. - * - * \param key Identifier of the key to use for the operation. - * The key must allow the usage - * #PSA_KEY_USAGE_VERIFY_HASH. - * \param alg A signature algorithm (\c PSA_ALG_XXX - * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) - * is true), that is compatible with - * the type of \p key. - * \param[in] hash The hash whose signature is to be verified. - * \param hash_length Size of the \p hash buffer in bytes. - * \param[in] signature Buffer containing the signature to verify. - * \param signature_length Size of the \p signature buffer in bytes. - * - * \retval #PSA_SUCCESS - * The operation started successfully - please call \c - * psa_verify_hash_complete() with the same context to complete the - * operation. - * - * \retval #PSA_ERROR_BAD_STATE - * Another operation has already been started on this context, and is - * still in progress. - * - * \retval #PSA_ERROR_NOT_PERMITTED - * The key does not have the #PSA_KEY_USAGE_VERIFY_HASH flag, or it does - * not permit the requested algorithm. - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_verify_hash_start( - psa_verify_hash_interruptible_operation_t *operation, - mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash, size_t hash_length, - const uint8_t *signature, size_t signature_length); - -/** - * \brief Continue and eventually complete the action of - * reading and verifying a hash or short message - * signed with a private key, in an interruptible - * manner. - * - * \see \c psa_verify_hash_start() - * - * \warning This is a beta API, and thus subject to change - * at any point. It is not bound by the usual - * interface stability promises. - * - * \note This function combined with \c - * psa_verify_hash_start() is equivalent to - * \c psa_verify_hash() but this function can - * return early and resume according to the limit - * set with \c psa_interruptible_set_max_ops() to - * reduce the maximum time spent in a function - * call. - * - * \note Users should call this function on the same - * operation object repeatedly until it either - * returns 0 or an error. This function will return - * #PSA_OPERATION_INCOMPLETE if there is more work - * to do. Alternatively users can call - * \c psa_verify_hash_abort() at any point if they - * no longer want the result. - * - * \note When this function returns successfully, the - * operation becomes inactive. If this function - * returns an error status, the operation enters an - * error state and must be aborted by calling - * \c psa_verify_hash_abort(). - * - * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t - * to use. This must be initialized first, and have - * had \c psa_verify_hash_start() called with it - * first. - * - * \retval #PSA_SUCCESS - * Operation completed successfully, and the passed signature is valid. - * - * \retval #PSA_OPERATION_INCOMPLETE - * Operation was interrupted due to the setting of \c - * psa_interruptible_set_max_ops(). There is still work to be done. - * Call this function again with the same operation object. - * - * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription - * \retval #PSA_ERROR_INVALID_SIGNATURE - * The calculation was performed successfully, but the passed - * signature is not a valid signature. - * \retval #PSA_ERROR_BAD_STATE - * An operation was not previously started on this context via - * \c psa_verify_hash_start(). - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has either not been previously initialized by - * psa_crypto_init() or you did not previously call - * psa_verify_hash_start() on this object. It is - * implementation-dependent whether a failure to initialize results in - * this error code. - */ -psa_status_t psa_verify_hash_complete( - psa_verify_hash_interruptible_operation_t *operation); - -/** - * \brief Abort a verify hash operation. - * - * \warning This is a beta API, and thus subject to change at - * any point. It is not bound by the usual interface - * stability promises. - * - * \note This function is the only function that clears the - * number of ops completed as part of the operation. - * Please ensure you copy this value via - * \c psa_verify_hash_get_num_ops() if required - * before calling. - * - * \note Aborting an operation frees all associated - * resources except for the operation structure - * itself. Once aborted, the operation object can be - * reused for another operation by calling \c - * psa_verify_hash_start() again. - * - * \note You may call this function any time after the - * operation object has been initialized. - * In particular, calling \c psa_verify_hash_abort() - * after the operation has already been terminated by - * a call to \c psa_verify_hash_abort() or - * psa_verify_hash_complete() is safe. - * - * \param[in,out] operation Initialized verify hash operation. - * - * \retval #PSA_SUCCESS - * The operation was aborted successfully. - * - * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_verify_hash_abort( - psa_verify_hash_interruptible_operation_t *operation); - -/** Make a copy of a key. - * - * Copy key material from one location to another. - * - * This function is primarily useful to copy a key from one location - * to another, since it populates a key using the material from - * another key which may have a different lifetime. - * - * This function may be used to share a key with a different party, - * subject to implementation-defined restrictions on key sharing. - * - * The policy on the source key must have the usage flag - * #PSA_KEY_USAGE_COPY set. - * This flag is sufficient to permit the copy if the key has the lifetime - * #PSA_KEY_LIFETIME_VOLATILE or #PSA_KEY_LIFETIME_PERSISTENT. - * Some secure elements do not provide a way to copy a key without - * making it extractable from the secure element. If a key is located - * in such a secure element, then the key must have both usage flags - * #PSA_KEY_USAGE_COPY and #PSA_KEY_USAGE_EXPORT in order to make - * a copy of the key outside the secure element. - * - * The resulting key may only be used in a way that conforms to - * both the policy of the original key and the policy specified in - * the \p attributes parameter: - * - The usage flags on the resulting key are the bitwise-and of the - * usage flags on the source policy and the usage flags in \p attributes. - * - If both allow the same algorithm or wildcard-based - * algorithm policy, the resulting key has the same algorithm policy. - * - If either of the policies allows an algorithm and the other policy - * allows a wildcard-based algorithm policy that includes this algorithm, - * the resulting key allows the same algorithm. - * - If the policies do not allow any algorithm in common, this function - * fails with the status #PSA_ERROR_INVALID_ARGUMENT. - * - * The effect of this function on implementation-defined attributes is - * implementation-defined. - * - * \param source_key The key to copy. It must allow the usage - * #PSA_KEY_USAGE_COPY. If a private or secret key is - * being copied outside of a secure element it must - * also allow #PSA_KEY_USAGE_EXPORT. - * \param[in] attributes The attributes for the new key. - * They are used as follows: - * - The key type and size may be 0. If either is - * nonzero, it must match the corresponding - * attribute of the source key. - * - The key location (the lifetime and, for - * persistent keys, the key identifier) is - * used directly. - * - The policy constraints (usage flags and - * algorithm policy) are combined from - * the source key and \p attributes so that - * both sets of restrictions apply, as - * described in the documentation of this function. - * \param[out] target_key On success, an identifier for the newly created - * key. For persistent keys, this is the key - * identifier defined in \p attributes. - * \c 0 on failure. - * - * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INVALID_HANDLE - * \p source_key is invalid. - * \retval #PSA_ERROR_ALREADY_EXISTS - * This is an attempt to create a persistent key, and there is - * already a persistent key with the given identifier. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The lifetime or identifier in \p attributes are invalid, or - * the policy constraints on the source and specified in - * \p attributes are incompatible, or - * \p attributes specifies a key type or key size - * which does not match the attributes of the source key. - * \retval #PSA_ERROR_NOT_PERMITTED - * The source key does not have the #PSA_KEY_USAGE_COPY usage flag, or - * the source key is not exportable and its lifetime does not - * allow copying it to the target's lifetime. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription - * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription - * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription - * \retval #PSA_ERROR_DATA_INVALID \emptydescription - * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription - * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, - const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *target_key); - -/** Reset a key attribute structure to a freshly initialized state. - * - * You must initialize the attribute structure as described in the - * documentation of the type #psa_key_attributes_t before calling this - * function. Once the structure has been initialized, you may call this - * function at any time. - * - * This function frees any auxiliary resources that the structure - * may contain. - * - * \param[in,out] attributes The attribute structure to reset. - */ -void psa_reset_key_attributes(psa_key_attributes_t *attributes); From 1b495c6d1020a11d335856516adbacd4e76f3083 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 1 Aug 2024 16:40:49 +0200 Subject: [PATCH 096/125] Enhance existing skip mechanism instead of duplicating it Signed-off-by: Gilles Peskine --- psasim/src/psa_sim_generate.pl | 51 ++++++++++++---------------------- 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 07835ae9af..e32195ecbe 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -22,14 +22,25 @@ my @functions = sort keys %functions; # We don't want these functions (e.g. because they are not implemented, etc) -my @skip_functions = qw( - psa_key_derivation_verify_bytes - psa_key_derivation_verify_key +my @skip_functions = ( + 'mbedtls_psa_crypto_free', # redefined rather than wrapped + 'mbedtls_psa_external_get_random', # not in the default config, uses unsupported type + 'mbedtls_psa_get_stats', # uses unsupported type + 'mbedtls_psa_inject_entropy', # not in the default config, generally not for client use anyway + 'mbedtls_psa_platform_get_builtin_key', # not in the default config, uses unsupported type + 'mbedtls_psa_register_se_key', # not in the default config, generally not for client use anyway + 'psa_get_key_slot_number', # not in the default config, uses unsupported type + 'psa_key_derivation_verify_bytes', # not implemented yet + 'psa_key_derivation_verify_key', # not implemented yet ); -# Remove @skip_functions from @functions -my %skip_functions = map { $_ => 1 } @skip_functions; -@functions = grep(!exists($skip_functions{$_}), @functions); +my $skip_functions_re = '\A(' . join('|', @skip_functions). ')\Z'; +@functions = grep(!/$skip_functions_re + |_pake_ # Skip everything PAKE + |_init\Z # constructors + /x, @functions); +# Restore psa_crypto_init() and put it first. +unshift @functions, 'psa_crypto_init'; # get_functions(), called above, returns a data structure for each function # that we need to create client and server stubs for. In this example Perl script, @@ -84,9 +95,6 @@ # It's possible that a production version might not need both type and ctypename; # that was done for convenience and future-proofing during development. -# We'll do psa_crypto_init() first -put_crypto_init_first(\@functions); - write_function_codes("$output_dir/psa_functions_codes.h"); write_client_calls("$output_dir/psa_sim_crypto_client.c"); @@ -1120,31 +1128,6 @@ sub get_functions if ($line =~ /(\w+)\s+\b(\w+)\s*\(\s*(.*\S)\s*\)\s*[;{]/s) { my ($ret_type, $func, $args) = ($1, $2, $3); - if ($func =~ /_init$/ and $func ne 'psa_crypto_init' and - $args eq 'void') { - # IGNORE constructors - next; - } - if ($func =~ /_pake_/ or - $func eq 'mbedtls_psa_external_get_random' or - $func eq 'mbedtls_psa_get_stats' or - $func eq 'mbedtls_psa_platform_get_builtin_key' or - $func eq 'psa_get_key_slot_number') { - # IGNORE functions using unsupported types - next; - } - if ($func eq 'mbedtls_psa_register_se_key' or - $func eq 'mbedtls_psa_inject_entropy') { - # IGNORE functions that are not supported, not used in - # the default build, and not supposed to be invoked - # by (unprivileged) clients anyway. - next; - } - if ($func eq 'mbedtls_psa_crypto_free') { - # IGNORE function that we redefine instead of wrapping - next; - } - my $copy = $line; $copy =~ s/{$//; my $f = { From 889f31ae41b8564525c54dc787aa3fc0862efcec Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 2 Aug 2024 12:42:01 +0200 Subject: [PATCH 097/125] Remove cruft and update documentation Signed-off-by: Gilles Peskine --- psasim/src/psa_sim_generate.pl | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index e32195ecbe..bc63975e83 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -3,7 +3,8 @@ # This is a proof-of-concept script to show that the client and server wrappers # can be created by a script. It is not hooked into the build, so is run # manually and the output files are what are to be reviewed. In due course -# this will be replaced by a Python script. +# this will be replaced by a Python script based on the +# code_wrapper.psa_wrapper module. # # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later @@ -43,10 +44,8 @@ unshift @functions, 'psa_crypto_init'; # get_functions(), called above, returns a data structure for each function -# that we need to create client and server stubs for. In this example Perl script, -# the function declarations we want are in the data section (after __END__ at -# the bottom of this file), but a production Python version should process -# psa_crypto.h. +# that we need to create client and server stubs for. The functions are +# listed from PSA header files. # # In this script, the data for psa_crypto_init() looks like: # @@ -1251,26 +1250,3 @@ sub get_functions return %funcs; } - -sub put_crypto_init_first -{ - my ($functions) = @_; - - my $want_first = "psa_crypto_init"; - - my $idx = undef; - for my $i (0 .. $#$functions) { - if ($functions->[$i] eq $want_first) { - $idx = $i; - last; - } - } - if (!defined $idx) { - die "psa_crypto_init not found" - } - - if ($idx != 0) { # Do nothing if already first - splice(@$functions, $idx, 1); - unshift(@$functions, $want_first); - } -} From b4698a730a526f1652531a9d5571929ae27f2229 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 31 Jul 2024 22:10:13 +0200 Subject: [PATCH 098/125] Migrate psasim wrappers to psa_custom_key_parameters_t Signed-off-by: Gilles Peskine --- psasim/src/psa_sim_generate.pl | 48 ---------- psasim/src/psa_sim_serialise.pl | 161 +------------------------------- 2 files changed, 1 insertion(+), 208 deletions(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index bc63975e83..e0e9b19f0d 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -564,13 +564,6 @@ sub output_server_wrapper print $fh < UINT32_MAX / 2) { /* arbitrary limit */ - return 0; /* too big to serialise */ - } - - /* We use 32-bit lengths, which should be enough for any reasonable usage :) */ - /* (the UINT32_MAX / 2 above is an even more conservative check to avoid overflow here) */ - uint32_t len = (uint32_t) (sizeof(data_length) + sizeof(*params) + data_length); - if (*remaining < SER_TAG_SIZE + sizeof(uint32_t) + len) { - return 0; - } - - char tag[SER_TAG_SIZE] = "PKPP"; - - memcpy(*pos, tag, sizeof(tag)); - memcpy(*pos + sizeof(tag), &len, sizeof(len)); - *pos += sizeof(tag) + sizeof(len); - *remaining -= sizeof(tag) + sizeof(len); - - memcpy(*pos, &data_length, sizeof(data_length)); - memcpy(*pos + sizeof(data_length), params, sizeof(*params) + data_length); - *pos += sizeof(data_length) + sizeof(*params) + data_length; - *remaining -= sizeof(data_length) + sizeof(*params) + data_length; - - return 1; -} - -int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, - size_t *remaining, - psa_key_production_parameters_t **params, - size_t *data_length) -{ - if (*remaining < SER_TAG_SIZE + sizeof(uint32_t)) { - return 0; /* can't even be an empty serialisation */ - } - - char tag[SER_TAG_SIZE] = "PKPP"; /* expected */ - uint32_t len; - - memcpy(&len, *pos + sizeof(tag), sizeof(len)); - - if (memcmp(*pos, tag, sizeof(tag)) != 0) { - return 0; /* wrong tag */ - } - - *pos += sizeof(tag) + sizeof(len); - *remaining -= sizeof(tag) + sizeof(len); - - if (*remaining < sizeof(*data_length)) { - return 0; /* missing data_length */ - } - memcpy(data_length, *pos, sizeof(*data_length)); - - if ((size_t) len != (sizeof(data_length) + sizeof(**params) + *data_length)) { - return 0; /* wrong length */ - } - - if (*remaining < sizeof(*data_length) + sizeof(**params) + *data_length) { - return 0; /* not enough data provided */ - } - - *pos += sizeof(data_length); - *remaining -= sizeof(data_length); - - psa_key_production_parameters_t *out = malloc(sizeof(**params) + *data_length); - if (out == NULL) { - return 0; /* allocation failure */ - } - - memcpy(out, *pos, sizeof(*out) + *data_length); - *pos += sizeof(*out) + *data_length; - *remaining -= sizeof(*out) + *data_length; - - *params = out; - - return 1; -} -EOF -} sub c_header { From 6cc552fd2e33b2932ef75e8067f4fe8d7a3d68f6 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 31 Jul 2024 17:03:59 +0200 Subject: [PATCH 099/125] Update generated PSA wrappers Signed-off-by: Gilles Peskine --- psasim/src/psa_functions_codes.h | 4 +- psasim/src/psa_sim_crypto_client.c | 44 +++++++++----- psasim/src/psa_sim_crypto_server.c | 66 +++++++++++++-------- psasim/src/psa_sim_serialise.c | 92 ++++++------------------------ psasim/src/psa_sim_serialise.h | 49 +++++++--------- 5 files changed, 112 insertions(+), 143 deletions(-) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index bc1b84442a..1301ff2d63 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -40,7 +40,7 @@ enum { PSA_EXPORT_KEY, PSA_EXPORT_PUBLIC_KEY, PSA_GENERATE_KEY, - PSA_GENERATE_KEY_EXT, + PSA_GENERATE_KEY_CUSTOM, PSA_GENERATE_RANDOM, PSA_GET_KEY_ATTRIBUTES, PSA_HASH_ABORT, @@ -62,7 +62,7 @@ enum { PSA_KEY_DERIVATION_KEY_AGREEMENT, PSA_KEY_DERIVATION_OUTPUT_BYTES, PSA_KEY_DERIVATION_OUTPUT_KEY, - PSA_KEY_DERIVATION_OUTPUT_KEY_EXT, + PSA_KEY_DERIVATION_OUTPUT_KEY_CUSTOM, PSA_KEY_DERIVATION_SET_CAPACITY, PSA_KEY_DERIVATION_SETUP, PSA_MAC_ABORT, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 4200f6c04d..d4d9d60884 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -2803,9 +2803,10 @@ psa_status_t psa_generate_key( } -psa_status_t psa_generate_key_ext( +psa_status_t psa_generate_key_custom( const psa_key_attributes_t *attributes, - const psa_key_production_parameters_t *params, size_t params_data_length, + const psa_custom_key_parameters_t *custom, + const uint8_t *custom_data, size_t custom_data_length, mbedtls_svc_key_id_t *key ) { @@ -2817,7 +2818,8 @@ psa_status_t psa_generate_key_ext( size_t needed = psasim_serialise_begin_needs() + psasim_serialise_psa_key_attributes_t_needs(*attributes) + - psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) + + psasim_serialise_psa_custom_key_parameters_t_needs(*custom) + + psasim_serialise_buffer_needs(custom_data, custom_data_length) + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); @@ -2839,9 +2841,15 @@ psa_status_t psa_generate_key_ext( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_production_parameters_t( + ok = psasim_serialise_psa_custom_key_parameters_t( &pos, &remaining, - params, params_data_length); + *custom); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer( + &pos, &remaining, + custom_data, custom_data_length); if (!ok) { goto fail; } @@ -2852,10 +2860,10 @@ psa_status_t psa_generate_key_ext( goto fail; } - ok = psa_crypto_call(PSA_GENERATE_KEY_EXT, + ok = psa_crypto_call(PSA_GENERATE_KEY_CUSTOM, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_GENERATE_KEY_EXT server call failed\n"); + printf("PSA_GENERATE_KEY_CUSTOM server call failed\n"); goto fail; } @@ -4572,10 +4580,11 @@ psa_status_t psa_key_derivation_output_key( } -psa_status_t psa_key_derivation_output_key_ext( +psa_status_t psa_key_derivation_output_key_custom( const psa_key_attributes_t *attributes, psa_key_derivation_operation_t *operation, - const psa_key_production_parameters_t *params, size_t params_data_length, + const psa_custom_key_parameters_t *custom, + const uint8_t *custom_data, size_t custom_data_length, mbedtls_svc_key_id_t *key ) { @@ -4588,7 +4597,8 @@ psa_status_t psa_key_derivation_output_key_ext( psasim_serialise_begin_needs() + psasim_serialise_psa_key_attributes_t_needs(*attributes) + psasim_serialise_psa_key_derivation_operation_t_needs(*operation) + - psasim_serialise_psa_key_production_parameters_t_needs(params, params_data_length) + + psasim_serialise_psa_custom_key_parameters_t_needs(*custom) + + psasim_serialise_buffer_needs(custom_data, custom_data_length) + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); @@ -4616,9 +4626,15 @@ psa_status_t psa_key_derivation_output_key_ext( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_production_parameters_t( + ok = psasim_serialise_psa_custom_key_parameters_t( + &pos, &remaining, + *custom); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer( &pos, &remaining, - params, params_data_length); + custom_data, custom_data_length); if (!ok) { goto fail; } @@ -4629,10 +4645,10 @@ psa_status_t psa_key_derivation_output_key_ext( goto fail; } - ok = psa_crypto_call(PSA_KEY_DERIVATION_OUTPUT_KEY_EXT, + ok = psa_crypto_call(PSA_KEY_DERIVATION_OUTPUT_KEY_CUSTOM, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_KEY_DERIVATION_OUTPUT_KEY_EXT server call failed\n"); + printf("PSA_KEY_DERIVATION_OUTPUT_KEY_CUSTOM server call failed\n"); goto fail; } diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index cab32c47c1..b2ed070c8a 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -3116,14 +3116,15 @@ int psa_generate_key_wrapper( } // Returns 1 for success, 0 for failure -int psa_generate_key_ext_wrapper( +int psa_generate_key_custom_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_key_attributes_t attributes; - psa_key_production_parameters_t *params = NULL; - size_t params_data_length; + psa_custom_key_parameters_t custom; + uint8_t *custom_data = NULL; + size_t custom_data_length; mbedtls_svc_key_id_t key; uint8_t *pos = in_params; @@ -3143,9 +3144,16 @@ int psa_generate_key_ext_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_production_parameters_t( + ok = psasim_deserialise_psa_custom_key_parameters_t( &pos, &remaining, - ¶ms, ¶ms_data_length); + &custom); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer( + &pos, &remaining, + &custom_data, &custom_data_length); if (!ok) { goto fail; } @@ -3159,9 +3167,10 @@ int psa_generate_key_ext_wrapper( // Now we call the actual target function - status = psa_generate_key_ext( + status = psa_generate_key_custom( &attributes, - params, params_data_length, + &custom, + custom_data, custom_data_length, &key ); @@ -3201,14 +3210,14 @@ int psa_generate_key_ext_wrapper( *out_params = result; *out_params_len = result_size; - free(params); + free(custom_data); return 1; // success fail: free(result); - free(params); + free(custom_data); return 0; // This shouldn't happen! } @@ -5079,15 +5088,16 @@ int psa_key_derivation_output_key_wrapper( } // Returns 1 for success, 0 for failure -int psa_key_derivation_output_key_ext_wrapper( +int psa_key_derivation_output_key_custom_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_key_attributes_t attributes; psa_key_derivation_operation_t *operation; - psa_key_production_parameters_t *params = NULL; - size_t params_data_length; + psa_custom_key_parameters_t custom; + uint8_t *custom_data = NULL; + size_t custom_data_length; mbedtls_svc_key_id_t key; uint8_t *pos = in_params; @@ -5114,9 +5124,16 @@ int psa_key_derivation_output_key_ext_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_production_parameters_t( + ok = psasim_deserialise_psa_custom_key_parameters_t( + &pos, &remaining, + &custom); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer( &pos, &remaining, - ¶ms, ¶ms_data_length); + &custom_data, &custom_data_length); if (!ok) { goto fail; } @@ -5130,10 +5147,11 @@ int psa_key_derivation_output_key_ext_wrapper( // Now we call the actual target function - status = psa_key_derivation_output_key_ext( + status = psa_key_derivation_output_key_custom( &attributes, operation, - params, params_data_length, + &custom, + custom_data, custom_data_length, &key ); @@ -5181,14 +5199,14 @@ int psa_key_derivation_output_key_ext_wrapper( *out_params = result; *out_params_len = result_size; - free(params); + free(custom_data); return 1; // success fail: free(result); - free(params); + free(custom_data); return 0; // This shouldn't happen! } @@ -7712,9 +7730,9 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_generate_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; - case PSA_GENERATE_KEY_EXT: - ok = psa_generate_key_ext_wrapper(in_params, in_params_len, - &out_params, &out_params_len); + case PSA_GENERATE_KEY_CUSTOM: + ok = psa_generate_key_custom_wrapper(in_params, in_params_len, + &out_params, &out_params_len); break; case PSA_GENERATE_RANDOM: ok = psa_generate_random_wrapper(in_params, in_params_len, @@ -7800,9 +7818,9 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_key_derivation_output_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; - case PSA_KEY_DERIVATION_OUTPUT_KEY_EXT: - ok = psa_key_derivation_output_key_ext_wrapper(in_params, in_params_len, - &out_params, &out_params_len); + case PSA_KEY_DERIVATION_OUTPUT_KEY_CUSTOM: + ok = psa_key_derivation_output_key_custom_wrapper(in_params, in_params_len, + &out_params, &out_params_len); break; case PSA_KEY_DERIVATION_SET_CAPACITY: ok = psa_key_derivation_set_capacity_wrapper(in_params, in_params_len, diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 92ecdd20f2..e5c7225c84 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -735,96 +735,38 @@ int psasim_deserialise_return_buffer(uint8_t **pos, return 1; } -#define SER_TAG_SIZE 4 - -size_t psasim_serialise_psa_key_production_parameters_t_needs( - const psa_key_production_parameters_t *params, - size_t data_length) +size_t psasim_serialise_psa_custom_key_parameters_t_needs( + psa_custom_key_parameters_t value) { - /* We will serialise with 4-byte tag = "PKPP" + 4-byte overall length at the beginning, - * followed by size_t data_length, then the actual data from the structure. - */ - return SER_TAG_SIZE + sizeof(uint32_t) + sizeof(data_length) + sizeof(*params) + data_length; + return sizeof(value); } -int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos, - size_t *remaining, - const psa_key_production_parameters_t *params, - size_t data_length) +int psasim_serialise_psa_custom_key_parameters_t(uint8_t **pos, + size_t *remaining, + psa_custom_key_parameters_t value) { - if (data_length > UINT32_MAX / 2) { /* arbitrary limit */ - return 0; /* too big to serialise */ - } - - /* We use 32-bit lengths, which should be enough for any reasonable usage :) */ - /* (the UINT32_MAX / 2 above is an even more conservative check to avoid overflow here) */ - uint32_t len = (uint32_t) (sizeof(data_length) + sizeof(*params) + data_length); - if (*remaining < SER_TAG_SIZE + sizeof(uint32_t) + len) { + if (*remaining < sizeof(value)) { return 0; } - char tag[SER_TAG_SIZE] = "PKPP"; - - memcpy(*pos, tag, sizeof(tag)); - memcpy(*pos + sizeof(tag), &len, sizeof(len)); - *pos += sizeof(tag) + sizeof(len); - *remaining -= sizeof(tag) + sizeof(len); - - memcpy(*pos, &data_length, sizeof(data_length)); - memcpy(*pos + sizeof(data_length), params, sizeof(*params) + data_length); - *pos += sizeof(data_length) + sizeof(*params) + data_length; - *remaining -= sizeof(data_length) + sizeof(*params) + data_length; + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); return 1; } -int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, - size_t *remaining, - psa_key_production_parameters_t **params, - size_t *data_length) +int psasim_deserialise_psa_custom_key_parameters_t(uint8_t **pos, + size_t *remaining, + psa_custom_key_parameters_t *value) { - if (*remaining < SER_TAG_SIZE + sizeof(uint32_t)) { - return 0; /* can't even be an empty serialisation */ - } - - char tag[SER_TAG_SIZE] = "PKPP"; /* expected */ - uint32_t len; - - memcpy(&len, *pos + sizeof(tag), sizeof(len)); - - if (memcmp(*pos, tag, sizeof(tag)) != 0) { - return 0; /* wrong tag */ - } - - *pos += sizeof(tag) + sizeof(len); - *remaining -= sizeof(tag) + sizeof(len); - - if (*remaining < sizeof(*data_length)) { - return 0; /* missing data_length */ - } - memcpy(data_length, *pos, sizeof(*data_length)); - - if ((size_t) len != (sizeof(data_length) + sizeof(**params) + *data_length)) { - return 0; /* wrong length */ - } - - if (*remaining < sizeof(*data_length) + sizeof(**params) + *data_length) { - return 0; /* not enough data provided */ - } - - *pos += sizeof(data_length); - *remaining -= sizeof(data_length); - - psa_key_production_parameters_t *out = malloc(sizeof(**params) + *data_length); - if (out == NULL) { - return 0; /* allocation failure */ + if (*remaining < sizeof(*value)) { + return 0; } - memcpy(out, *pos, sizeof(*out) + *data_length); - *pos += sizeof(*out) + *data_length; - *remaining -= sizeof(*out) + *data_length; + memcpy(value, *pos, sizeof(*value)); - *params = out; + *pos += sizeof(*value); + *remaining -= sizeof(*value); return 1; } diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index f60e371c30..523ce8028b 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -421,55 +421,48 @@ int psasim_deserialise_buffer(uint8_t **pos, size_t *remaining, int psasim_deserialise_return_buffer(uint8_t **pos, size_t *remaining, uint8_t *buffer, size_t buffer_length); -/** Return how much space is needed by \c psasim_serialise_psa_key_production_parameters_t() - * to serialise a psa_key_production_parameters_t (a structure with a flexible array member). +/** Return how much buffer space is needed by \c psasim_serialise_psa_custom_key_parameters_t() + * to serialise a `psa_custom_key_parameters_t`. * - * \param params Pointer to the struct to be serialised + * \param value The value that will be serialised into the buffer * (needed in case some serialisations are value- * dependent). - * \param data_length Number of bytes in the data[] of the struct to be serialised. * - * \return The number of bytes needed in the serialisation buffer by - * \c psasim_serialise_psa_key_production_parameters_t() to serialise - * the specified structure. + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_custom_key_parameters_t() to serialise + * the given value. */ -size_t psasim_serialise_psa_key_production_parameters_t_needs( - const psa_key_production_parameters_t *params, - size_t buffer_size); +size_t psasim_serialise_psa_custom_key_parameters_t_needs( + psa_custom_key_parameters_t value); -/** Serialise a psa_key_production_parameters_t. +/** Serialise a `psa_custom_key_parameters_t` into a buffer. * * \param pos[in,out] Pointer to a `uint8_t *` holding current position * in the buffer. * \param remaining[in,out] Pointer to a `size_t` holding number of bytes * remaining in the buffer. - * \param params Pointer to the structure to be serialised. - * \param data_length Number of bytes in the data[] of the struct to be serialised. + * \param value The value to serialise into the buffer. * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos, - size_t *remaining, - const psa_key_production_parameters_t *params, - size_t data_length); +int psasim_serialise_psa_custom_key_parameters_t(uint8_t **pos, + size_t *remaining, + psa_custom_key_parameters_t value); -/** Deserialise a psa_key_production_parameters_t. +/** Deserialise a `psa_custom_key_parameters_t` from a buffer. * * \param pos[in,out] Pointer to a `uint8_t *` holding current position - * in the serialisation buffer. + * in the buffer. * \param remaining[in,out] Pointer to a `size_t` holding number of bytes - * remaining in the serialisation buffer. - * \param params Pointer to a `psa_key_production_parameters_t *` to - * receive the address of a newly-allocated structure, - * which the caller must `free()`. - * \param data_length Pointer to a `size_t` to receive the number of - * bytes in the data[] member of the structure deserialised. + * remaining in the buffer. + * \param value Pointer to a `psa_custom_key_parameters_t` to receive the value + * deserialised from the buffer. * * \return \c 1 on success ("okay"), \c 0 on error. */ -int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, size_t *remaining, - psa_key_production_parameters_t **params, - size_t *buffer_length); +int psasim_deserialise_psa_custom_key_parameters_t(uint8_t **pos, + size_t *remaining, + psa_custom_key_parameters_t *value); /** Return how much buffer space is needed by \c psasim_serialise_psa_status_t() * to serialise a `psa_status_t`. From 8c613fe701b7ee04dd4ff348f786a98b0e725397 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 5 Aug 2024 15:57:43 +0200 Subject: [PATCH 100/125] psasim: small fixes to all.sh and test bash scripts Signed-off-by: Valerio Setti --- psasim/test/kill_servers.sh | 3 +++ psasim/test/run_test.sh | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/psasim/test/kill_servers.sh b/psasim/test/kill_servers.sh index e84fd39ea1..d72263791f 100755 --- a/psasim/test/kill_servers.sh +++ b/psasim/test/kill_servers.sh @@ -7,6 +7,9 @@ set -e pkill psa_server || true +# Remove temporary files +rm -f psa_notify_* + # Remove all IPCs # Not just ipcrm -all=msg as it is not supported on macOS. # Filter out header and empty lines, choosing to select based on keys being diff --git a/psasim/test/run_test.sh b/psasim/test/run_test.sh index ac9c4c86ca..f54e352532 100755 --- a/psasim/test/run_test.sh +++ b/psasim/test/run_test.sh @@ -16,10 +16,9 @@ cd "$(dirname "$0")" CLIENT_BIN=$1 shift -ipcs | grep q | awk '{ printf " -q " $2 }' | xargs ipcrm > /dev/null 2>&1 || true +./kill_servers.sh ./start_server.sh ./$CLIENT_BIN "$@" -# Kill server once client exited -pkill psa_server +./kill_servers.sh From e90999117a2ea6f3e3d807ab00724f15c629d34a Mon Sep 17 00:00:00 2001 From: Harry Ramsey Date: Mon, 7 Oct 2024 11:27:39 +0100 Subject: [PATCH 101/125] Fix failing psasim tests This commit fixes failing psasim tests by ensuring that MBEDTLS_VERSION_C is defined before attempting to access version information. Signed-off-by: Harry Ramsey --- psasim/src/server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/psasim/src/server.c b/psasim/src/server.c index 10ab5a287f..44939f1c2a 100644 --- a/psasim/src/server.c +++ b/psasim/src/server.c @@ -52,12 +52,14 @@ int psa_server_main(int argc, char *argv[]) psa_msg_t msg = { -1 }; const int magic_num = 66; int client_disconnected = 0; - char mbedtls_version[18]; extern psa_status_t psa_crypto_call(psa_msg_t msg); extern psa_status_t psa_crypto_close(void); +#if defined(MBEDTLS_VERSION_C) + char mbedtls_version[18]; mbedtls_version_get_string_full(mbedtls_version); SERVER_PRINT("%s", mbedtls_version); +#endif parse_input_args(argc, argv); SERVER_PRINT("Starting"); From cbf407fa31897f1747af8ec822b7bb1b762a9d86 Mon Sep 17 00:00:00 2001 From: Harry Ramsey Date: Mon, 21 Oct 2024 12:26:59 +0100 Subject: [PATCH 102/125] Fix linking error for mbedtls_test_hook_error_add This commit fixes a linking error with psa_sim_crypto_server.c where mbedtls_test_hook_error_add was undefined. Signed-off-by: Harry Ramsey --- psasim/src/psa_sim_crypto_server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index b2ed070c8a..2daacd8498 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -21,6 +21,10 @@ #error "Error: MBEDTLS_PSA_CRYPTO_C must be enabled on server build" #endif +#if defined(MBEDTLS_TEST_HOOKS) +void (*mbedtls_test_hook_error_add)(int, int, const char *, int); +#endif + // Returns 1 for success, 0 for failure int psa_crypto_init_wrapper( uint8_t *in_params, size_t in_params_len, From 34261822443d182ffcd6989c37beab49d1f75b5d Mon Sep 17 00:00:00 2001 From: Harry Ramsey Date: Mon, 21 Oct 2024 18:38:15 +0100 Subject: [PATCH 103/125] Fix formatting issue This commit fixes a formatting issue where whitespace was added at the end of lines. Signed-off-by: Harry Ramsey --- psasim/src/psa_sim_crypto_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 2daacd8498..a88fc51cce 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -21,8 +21,8 @@ #error "Error: MBEDTLS_PSA_CRYPTO_C must be enabled on server build" #endif -#if defined(MBEDTLS_TEST_HOOKS) -void (*mbedtls_test_hook_error_add)(int, int, const char *, int); +#if defined(MBEDTLS_TEST_HOOKS) +void (*mbedtls_test_hook_error_add)(int, int, const char *, int); #endif // Returns 1 for success, 0 for failure From 578ce8d57182f7709cf8ce845ad93d29d7aac45f Mon Sep 17 00:00:00 2001 From: Waleed Elmelegy Date: Tue, 6 Aug 2024 10:55:09 +0100 Subject: [PATCH 104/125] Add PSA interuptable key agreement APIs Signed-off-by: Waleed Elmelegy --- psasim/src/psa_sim_serialise.c | 36 +++++++++++++++++++++++++++ psasim/src/psa_sim_serialise.h | 43 +++++++++++++++++++++++++++++++++ psasim/src/psa_sim_serialise.pl | 3 ++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index e5c7225c84..44d87d60f1 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -1624,6 +1624,42 @@ int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, return 1; } +size_t psasim_serialise_psa_key_agreement_iop_t_needs( + psa_key_agreement_iop_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_key_agreement_iop_t(uint8_t **pos, + size_t *remaining, + psa_key_agreement_iop_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_key_agreement_iop_t(uint8_t **pos, + size_t *remaining, + psa_key_agreement_iop_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + void psa_sim_serialize_reset(void) { memset(hash_operation_handles, 0, diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 523ce8028b..02f6bcbe32 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -1301,3 +1301,46 @@ int psasim_serialise_mbedtls_svc_key_id_t(uint8_t **pos, int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, size_t *remaining, mbedtls_svc_key_id_t *value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_key_agreement_iop_t() + * to serialise a `psa_key_agreement_iop_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_key_agreement_iop_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_key_agreement_iop_t_needs( + psa_key_agreement_iop_t value); + +/** Serialise a `psa_key_agreement_iop_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_key_agreement_iop_t(uint8_t **pos, + size_t *remaining, + psa_key_agreement_iop_t value); + +/** Deserialise a `psa_key_agreement_iop_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_key_agreement_iop_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_key_agreement_iop_t(uint8_t **pos, + size_t *remaining, + psa_key_agreement_iop_t *value); diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 31c93aeb20..054841ea3a 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -48,7 +48,8 @@ psa_key_derivation_operation_t psa_sign_hash_interruptible_operation_t psa_verify_hash_interruptible_operation_t - mbedtls_svc_key_id_t); + mbedtls_svc_key_id_t + psa_key_agreement_iop_t); grep(s/-/ /g, @types); From c64ae58a4f75e35118dac669024940251905304f Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 15 Nov 2024 14:05:03 +0000 Subject: [PATCH 105/125] Add required code to psa_sim_generate.pl Non generated code was unfortnuately added to psa_sim_crypto_server.c, fix that by adding it to the generation scripts. Signed-off-by: Paul Elliott --- psasim/src/psa_sim_generate.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index e0e9b19f0d..fbceddf8d2 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -302,6 +302,10 @@ sub server_implementations_header #if !defined(MBEDTLS_PSA_CRYPTO_C) #error "Error: MBEDTLS_PSA_CRYPTO_C must be enabled on server build" #endif + +#if defined(MBEDTLS_TEST_HOOKS) +void (*mbedtls_test_hook_error_add)(int, int, const char *, int); +#endif EOF } From a3f92e00c7c7e5421721d2bcf88e9cd5eb72f23e Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 14 Nov 2024 12:29:44 +0000 Subject: [PATCH 106/125] Regenerate PSA Sim headers Signed-off-by: Paul Elliott --- psasim/src/psa_functions_codes.h | 9 + psasim/src/psa_sim_crypto_client.c | 1144 ++++++++++++++++++----- psasim/src/psa_sim_crypto_server.c | 1360 ++++++++++++++++++++++------ psasim/src/psa_sim_serialise.c | 36 + psasim/src/psa_sim_serialise.h | 43 + psasim/src/psa_sim_serialise.pl | 3 +- 6 files changed, 2126 insertions(+), 469 deletions(-) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 1301ff2d63..4be53c5973 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -41,6 +41,10 @@ enum { PSA_EXPORT_PUBLIC_KEY, PSA_GENERATE_KEY, PSA_GENERATE_KEY_CUSTOM, + PSA_GENERATE_KEY_IOP_ABORT, + PSA_GENERATE_KEY_IOP_COMPLETE, + PSA_GENERATE_KEY_IOP_GET_NUM_OPS, + PSA_GENERATE_KEY_IOP_SETUP, PSA_GENERATE_RANDOM, PSA_GET_KEY_ATTRIBUTES, PSA_HASH_ABORT, @@ -54,6 +58,11 @@ enum { PSA_IMPORT_KEY, PSA_INTERRUPTIBLE_GET_MAX_OPS, PSA_INTERRUPTIBLE_SET_MAX_OPS, + PSA_KEY_AGREEMENT, + PSA_KEY_AGREEMENT_IOP_ABORT, + PSA_KEY_AGREEMENT_IOP_COMPLETE, + PSA_KEY_AGREEMENT_IOP_GET_NUM_OPS, + PSA_KEY_AGREEMENT_IOP_SETUP, PSA_KEY_DERIVATION_ABORT, PSA_KEY_DERIVATION_GET_CAPACITY, PSA_KEY_DERIVATION_INPUT_BYTES, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index d4d9d60884..f6efd620cf 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -2897,8 +2897,8 @@ psa_status_t psa_generate_key_custom( } -psa_status_t psa_generate_random( - uint8_t *output, size_t output_size +psa_status_t psa_generate_key_iop_abort( + psa_generate_key_iop_t *operation ) { uint8_t *ser_params = NULL; @@ -2908,7 +2908,7 @@ psa_status_t psa_generate_random( size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_buffer_needs(output, output_size); + psasim_serialise_psa_generate_key_iop_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2923,17 +2923,17 @@ psa_status_t psa_generate_random( if (!ok) { goto fail; } - ok = psasim_serialise_buffer( + ok = psasim_serialise_psa_generate_key_iop_t( &pos, &remaining, - output, output_size); + *operation); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_GENERATE_RANDOM, + ok = psa_crypto_call(PSA_GENERATE_KEY_IOP_ABORT, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_GENERATE_RANDOM server call failed\n"); + printf("PSA_GENERATE_KEY_IOP_ABORT server call failed\n"); goto fail; } @@ -2952,9 +2952,9 @@ psa_status_t psa_generate_random( goto fail; } - ok = psasim_deserialise_return_buffer( + ok = psasim_deserialise_psa_generate_key_iop_t( &rpos, &rremain, - output, output_size); + operation); if (!ok) { goto fail; } @@ -2967,9 +2967,9 @@ psa_status_t psa_generate_random( } -psa_status_t psa_get_key_attributes( - mbedtls_svc_key_id_t key, - psa_key_attributes_t *attributes +psa_status_t psa_generate_key_iop_complete( + psa_generate_key_iop_t *operation, + mbedtls_svc_key_id_t *key ) { uint8_t *ser_params = NULL; @@ -2979,8 +2979,8 @@ psa_status_t psa_get_key_attributes( size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_mbedtls_svc_key_id_t_needs(key) + - psasim_serialise_psa_key_attributes_t_needs(*attributes); + psasim_serialise_psa_generate_key_iop_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -2995,23 +2995,23 @@ psa_status_t psa_get_key_attributes( if (!ok) { goto fail; } - ok = psasim_serialise_mbedtls_svc_key_id_t( + ok = psasim_serialise_psa_generate_key_iop_t( &pos, &remaining, - key); + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t( + ok = psasim_serialise_mbedtls_svc_key_id_t( &pos, &remaining, - *attributes); + *key); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_GET_KEY_ATTRIBUTES, + ok = psa_crypto_call(PSA_GENERATE_KEY_IOP_COMPLETE, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_GET_KEY_ATTRIBUTES server call failed\n"); + printf("PSA_GENERATE_KEY_IOP_COMPLETE server call failed\n"); goto fail; } @@ -3030,9 +3030,16 @@ psa_status_t psa_get_key_attributes( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t( + ok = psasim_deserialise_psa_generate_key_iop_t( &rpos, &rremain, - attributes); + operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -3045,22 +3052,22 @@ psa_status_t psa_get_key_attributes( } -psa_status_t psa_hash_abort( - psa_hash_operation_t *operation +uint32_t psa_generate_key_iop_get_num_ops( + psa_generate_key_iop_t *operation ) { uint8_t *ser_params = NULL; uint8_t *ser_result = NULL; size_t result_length; - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + uint32_t value = 0; size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation); + psasim_serialise_psa_generate_key_iop_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { - status = PSA_ERROR_INSUFFICIENT_MEMORY; + value = 0; goto fail; } @@ -3071,17 +3078,17 @@ psa_status_t psa_hash_abort( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t( + ok = psasim_serialise_psa_generate_key_iop_t( &pos, &remaining, *operation); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_HASH_ABORT, + ok = psa_crypto_call(PSA_GENERATE_KEY_IOP_GET_NUM_OPS, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_HASH_ABORT server call failed\n"); + printf("PSA_GENERATE_KEY_IOP_GET_NUM_OPS server call failed\n"); goto fail; } @@ -3093,14 +3100,14 @@ psa_status_t psa_hash_abort( goto fail; } - ok = psasim_deserialise_psa_status_t( + ok = psasim_deserialise_uint32_t( &rpos, &rremain, - &status); + &value); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_hash_operation_t( + ok = psasim_deserialise_psa_generate_key_iop_t( &rpos, &rremain, operation); if (!ok) { @@ -3111,13 +3118,13 @@ psa_status_t psa_hash_abort( free(ser_params); free(ser_result); - return status; + return value; } -psa_status_t psa_hash_clone( - const psa_hash_operation_t *source_operation, - psa_hash_operation_t *target_operation +psa_status_t psa_generate_key_iop_setup( + psa_generate_key_iop_t *operation, + const psa_key_attributes_t *attributes ) { uint8_t *ser_params = NULL; @@ -3127,8 +3134,8 @@ psa_status_t psa_hash_clone( size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*source_operation) + - psasim_serialise_psa_hash_operation_t_needs(*target_operation); + psasim_serialise_psa_generate_key_iop_t_needs(*operation) + + psasim_serialise_psa_key_attributes_t_needs(*attributes); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3143,23 +3150,23 @@ psa_status_t psa_hash_clone( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t( + ok = psasim_serialise_psa_generate_key_iop_t( &pos, &remaining, - *source_operation); + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t( + ok = psasim_serialise_psa_key_attributes_t( &pos, &remaining, - *target_operation); + *attributes); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_HASH_CLONE, + ok = psa_crypto_call(PSA_GENERATE_KEY_IOP_SETUP, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_HASH_CLONE server call failed\n"); + printf("PSA_GENERATE_KEY_IOP_SETUP server call failed\n"); goto fail; } @@ -3178,9 +3185,9 @@ psa_status_t psa_hash_clone( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t( + ok = psasim_deserialise_psa_generate_key_iop_t( &rpos, &rremain, - target_operation); + operation); if (!ok) { goto fail; } @@ -3193,10 +3200,8 @@ psa_status_t psa_hash_clone( } -psa_status_t psa_hash_compare( - psa_algorithm_t alg, - const uint8_t *input, size_t input_length, - const uint8_t *hash, size_t hash_length +psa_status_t psa_generate_random( + uint8_t *output, size_t output_size ) { uint8_t *ser_params = NULL; @@ -3206,9 +3211,7 @@ psa_status_t psa_hash_compare( 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_length); + psasim_serialise_buffer_needs(output, output_size); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3223,29 +3226,17 @@ psa_status_t psa_hash_compare( 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_length); + output, output_size); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_HASH_COMPARE, + ok = psa_crypto_call(PSA_GENERATE_RANDOM, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_HASH_COMPARE server call failed\n"); + printf("PSA_GENERATE_RANDOM server call failed\n"); goto fail; } @@ -3264,6 +3255,13 @@ psa_status_t psa_hash_compare( goto fail; } + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + output, output_size); + if (!ok) { + goto fail; + } + fail: free(ser_params); free(ser_result); @@ -3272,11 +3270,9 @@ psa_status_t psa_hash_compare( } -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 +psa_status_t psa_get_key_attributes( + mbedtls_svc_key_id_t key, + psa_key_attributes_t *attributes ) { uint8_t *ser_params = NULL; @@ -3286,10 +3282,8 @@ psa_status_t psa_hash_compute( 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); + psasim_serialise_mbedtls_svc_key_id_t_needs(key) + + psasim_serialise_psa_key_attributes_t_needs(*attributes); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3304,35 +3298,23 @@ psa_status_t psa_hash_compute( 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( + ok = psasim_serialise_mbedtls_svc_key_id_t( &pos, &remaining, - hash, hash_size); + key); if (!ok) { goto fail; } - ok = psasim_serialise_size_t( + ok = psasim_serialise_psa_key_attributes_t( &pos, &remaining, - *hash_length); + *attributes); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_HASH_COMPUTE, + ok = psa_crypto_call(PSA_GET_KEY_ATTRIBUTES, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_HASH_COMPUTE server call failed\n"); + printf("PSA_GET_KEY_ATTRIBUTES server call failed\n"); goto fail; } @@ -3351,16 +3333,9 @@ psa_status_t psa_hash_compute( goto fail; } - ok = psasim_deserialise_return_buffer( - &rpos, &rremain, - hash, hash_size); - if (!ok) { - goto fail; - } - - ok = psasim_deserialise_size_t( + ok = psasim_deserialise_psa_key_attributes_t( &rpos, &rremain, - hash_length); + attributes); if (!ok) { goto fail; } @@ -3373,10 +3348,8 @@ psa_status_t psa_hash_compute( } -psa_status_t psa_hash_finish( - psa_hash_operation_t *operation, - uint8_t *hash, size_t hash_size, - size_t *hash_length +psa_status_t psa_hash_abort( + psa_hash_operation_t *operation ) { uint8_t *ser_params = NULL; @@ -3386,9 +3359,7 @@ psa_status_t psa_hash_finish( size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(hash, hash_size) + - psasim_serialise_size_t_needs(*hash_length); + psasim_serialise_psa_hash_operation_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3409,23 +3380,11 @@ psa_status_t psa_hash_finish( 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_FINISH, + ok = psa_crypto_call(PSA_HASH_ABORT, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_HASH_FINISH server call failed\n"); + printf("PSA_HASH_ABORT server call failed\n"); goto fail; } @@ -3451,20 +3410,6 @@ psa_status_t psa_hash_finish( 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(ser_params); free(ser_result); @@ -3473,9 +3418,9 @@ psa_status_t psa_hash_finish( } -psa_status_t psa_hash_setup( - psa_hash_operation_t *operation, - psa_algorithm_t alg +psa_status_t psa_hash_clone( + const psa_hash_operation_t *source_operation, + psa_hash_operation_t *target_operation ) { uint8_t *ser_params = NULL; @@ -3485,8 +3430,8 @@ psa_status_t psa_hash_setup( size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation) + - psasim_serialise_psa_algorithm_t_needs(alg); + psasim_serialise_psa_hash_operation_t_needs(*source_operation) + + psasim_serialise_psa_hash_operation_t_needs(*target_operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3503,21 +3448,21 @@ psa_status_t psa_hash_setup( } ok = psasim_serialise_psa_hash_operation_t( &pos, &remaining, - *operation); + *source_operation); if (!ok) { goto fail; } - ok = psasim_serialise_psa_algorithm_t( + ok = psasim_serialise_psa_hash_operation_t( &pos, &remaining, - alg); + *target_operation); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_HASH_SETUP, + ok = psa_crypto_call(PSA_HASH_CLONE, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_HASH_SETUP server call failed\n"); + printf("PSA_HASH_CLONE server call failed\n"); goto fail; } @@ -3538,7 +3483,7 @@ psa_status_t psa_hash_setup( ok = psasim_deserialise_psa_hash_operation_t( &rpos, &rremain, - operation); + target_operation); if (!ok) { goto fail; } @@ -3551,9 +3496,10 @@ psa_status_t psa_hash_setup( } -psa_status_t psa_hash_update( - psa_hash_operation_t *operation, - const uint8_t *input, size_t input_length +psa_status_t psa_hash_compare( + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *hash, size_t hash_length ) { uint8_t *ser_params = NULL; @@ -3563,8 +3509,9 @@ psa_status_t psa_hash_update( size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(input, input_length); + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_buffer_needs(input, input_length) + + psasim_serialise_buffer_needs(hash, hash_length); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3579,9 +3526,9 @@ psa_status_t psa_hash_update( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t( + ok = psasim_serialise_psa_algorithm_t( &pos, &remaining, - *operation); + alg); if (!ok) { goto fail; } @@ -3591,11 +3538,17 @@ psa_status_t psa_hash_update( if (!ok) { goto fail; } + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_length); + if (!ok) { + goto fail; + } - ok = psa_crypto_call(PSA_HASH_UPDATE, + ok = psa_crypto_call(PSA_HASH_COMPARE, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_HASH_UPDATE server call failed\n"); + printf("PSA_HASH_COMPARE server call failed\n"); goto fail; } @@ -3614,13 +3567,6 @@ psa_status_t psa_hash_update( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t( - &rpos, &rremain, - operation); - if (!ok) { - goto fail; - } - fail: free(ser_params); free(ser_result); @@ -3629,11 +3575,644 @@ psa_status_t psa_hash_update( } -psa_status_t psa_hash_verify( - psa_hash_operation_t *operation, - const uint8_t *hash, size_t hash_length - ) -{ +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 *ser_params = NULL; + uint8_t *ser_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); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_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, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_HASH_COMPUTE server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_hash_finish( + psa_hash_operation_t *operation, + uint8_t *hash, size_t hash_size, + size_t *hash_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(hash, hash_size) + + psasim_serialise_size_t_needs(*hash_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); + 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_FINISH, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_HASH_FINISH server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_hash_operation_t( + &rpos, &rremain, + operation); + 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(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_hash_setup( + psa_hash_operation_t *operation, + psa_algorithm_t alg + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation) + + psasim_serialise_psa_algorithm_t_needs(alg); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_SETUP, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_HASH_SETUP server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_hash_operation_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_hash_update( + psa_hash_operation_t *operation, + const uint8_t *input, size_t input_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(input, input_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer( + &pos, &remaining, + input, input_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_UPDATE, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_HASH_UPDATE server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_hash_operation_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_hash_verify( + psa_hash_operation_t *operation, + const uint8_t *hash, size_t hash_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_hash_operation_t_needs(*operation) + + psasim_serialise_buffer_needs(hash, hash_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_hash_operation_t( + &pos, &remaining, + *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer( + &pos, &remaining, + hash, hash_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_HASH_VERIFY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_HASH_VERIFY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_hash_operation_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_import_key( + const psa_key_attributes_t *attributes, + const uint8_t *data, size_t data_length, + mbedtls_svc_key_id_t *key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_buffer_needs(data, data_length) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer( + &pos, &remaining, + data, data_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + *key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_IMPORT_KEY, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_IMPORT_KEY server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +uint32_t psa_interruptible_get_max_ops( + void + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + uint32_t value = 0; + + size_t needed = + psasim_serialise_begin_needs() + + 0; + + ser_params = malloc(needed); + if (ser_params == NULL) { + value = 0; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_INTERRUPTIBLE_GET_MAX_OPS, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_INTERRUPTIBLE_GET_MAX_OPS server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_uint32_t( + &rpos, &rremain, + &value); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return value; +} + + +void psa_interruptible_set_max_ops( + uint32_t max_ops + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_uint32_t_needs(max_ops); + + ser_params = malloc(needed); + if (ser_params == NULL) { + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_uint32_t( + &pos, &remaining, + max_ops); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_INTERRUPTIBLE_SET_MAX_OPS, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_INTERRUPTIBLE_SET_MAX_OPS server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); +} + + +psa_status_t psa_key_agreement( + mbedtls_svc_key_id_t private_key, + const uint8_t *peer_key, size_t peer_key_length, + psa_algorithm_t alg, + const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *key + ) +{ uint8_t *ser_params = NULL; uint8_t *ser_result = NULL; size_t result_length; @@ -3641,8 +4220,11 @@ psa_status_t psa_hash_verify( size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_hash_operation_t_needs(*operation) + - psasim_serialise_buffer_needs(hash, hash_length); + psasim_serialise_mbedtls_svc_key_id_t_needs(private_key) + + psasim_serialise_buffer_needs(peer_key, peer_key_length) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_psa_key_attributes_t_needs(*attributes) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3657,23 +4239,41 @@ psa_status_t psa_hash_verify( if (!ok) { goto fail; } - ok = psasim_serialise_psa_hash_operation_t( + ok = psasim_serialise_mbedtls_svc_key_id_t( &pos, &remaining, - *operation); + private_key); if (!ok) { goto fail; } ok = psasim_serialise_buffer( &pos, &remaining, - hash, hash_length); + peer_key, peer_key_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + *key); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_HASH_VERIFY, + ok = psa_crypto_call(PSA_KEY_AGREEMENT, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_HASH_VERIFY server call failed\n"); + printf("PSA_KEY_AGREEMENT server call failed\n"); goto fail; } @@ -3692,9 +4292,9 @@ psa_status_t psa_hash_verify( goto fail; } - ok = psasim_deserialise_psa_hash_operation_t( + ok = psasim_deserialise_mbedtls_svc_key_id_t( &rpos, &rremain, - operation); + key); if (!ok) { goto fail; } @@ -3707,10 +4307,8 @@ psa_status_t psa_hash_verify( } -psa_status_t psa_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, size_t data_length, - mbedtls_svc_key_id_t *key +psa_status_t psa_key_agreement_iop_abort( + psa_key_agreement_iop_t *operation ) { uint8_t *ser_params = NULL; @@ -3720,9 +4318,7 @@ psa_status_t psa_import_key( size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_psa_key_attributes_t_needs(*attributes) + - psasim_serialise_buffer_needs(data, data_length) + - psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + psasim_serialise_psa_key_agreement_iop_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3737,15 +4333,81 @@ psa_status_t psa_import_key( if (!ok) { goto fail; } - ok = psasim_serialise_psa_key_attributes_t( + ok = psasim_serialise_psa_key_agreement_iop_t( &pos, &remaining, - *attributes); + *operation); if (!ok) { goto fail; } - ok = psasim_serialise_buffer( + + ok = psa_crypto_call(PSA_KEY_AGREEMENT_IOP_ABORT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_KEY_AGREEMENT_IOP_ABORT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_key_agreement_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_key_agreement_iop_complete( + psa_key_agreement_iop_t *operation, + mbedtls_svc_key_id_t *key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_key_agreement_iop_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(*key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_agreement_iop_t( &pos, &remaining, - data, data_length); + *operation); if (!ok) { goto fail; } @@ -3756,10 +4418,10 @@ psa_status_t psa_import_key( goto fail; } - ok = psa_crypto_call(PSA_IMPORT_KEY, + ok = psa_crypto_call(PSA_KEY_AGREEMENT_IOP_COMPLETE, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_IMPORT_KEY server call failed\n"); + printf("PSA_KEY_AGREEMENT_IOP_COMPLETE server call failed\n"); goto fail; } @@ -3778,6 +4440,13 @@ psa_status_t psa_import_key( goto fail; } + ok = psasim_deserialise_psa_key_agreement_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + ok = psasim_deserialise_mbedtls_svc_key_id_t( &rpos, &rremain, key); @@ -3793,8 +4462,8 @@ psa_status_t psa_import_key( } -uint32_t psa_interruptible_get_max_ops( - void +uint32_t psa_key_agreement_iop_get_num_ops( + psa_key_agreement_iop_t *operation ) { uint8_t *ser_params = NULL; @@ -3804,7 +4473,7 @@ uint32_t psa_interruptible_get_max_ops( size_t needed = psasim_serialise_begin_needs() + - 0; + psasim_serialise_psa_key_agreement_iop_t_needs(*operation); ser_params = malloc(needed); if (ser_params == NULL) { @@ -3819,11 +4488,17 @@ uint32_t psa_interruptible_get_max_ops( if (!ok) { goto fail; } + ok = psasim_serialise_psa_key_agreement_iop_t( + &pos, &remaining, + *operation); + if (!ok) { + goto fail; + } - ok = psa_crypto_call(PSA_INTERRUPTIBLE_GET_MAX_OPS, + ok = psa_crypto_call(PSA_KEY_AGREEMENT_IOP_GET_NUM_OPS, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_INTERRUPTIBLE_GET_MAX_OPS server call failed\n"); + printf("PSA_KEY_AGREEMENT_IOP_GET_NUM_OPS server call failed\n"); goto fail; } @@ -3842,6 +4517,13 @@ uint32_t psa_interruptible_get_max_ops( goto fail; } + ok = psasim_deserialise_psa_key_agreement_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + fail: free(ser_params); free(ser_result); @@ -3850,20 +4532,30 @@ uint32_t psa_interruptible_get_max_ops( } -void psa_interruptible_set_max_ops( - uint32_t max_ops +psa_status_t psa_key_agreement_iop_setup( + psa_key_agreement_iop_t *operation, + mbedtls_svc_key_id_t private_key, + const uint8_t *peer_key, size_t peer_key_length, + psa_algorithm_t alg, + const psa_key_attributes_t *attributes ) { uint8_t *ser_params = NULL; uint8_t *ser_result = NULL; size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t needed = psasim_serialise_begin_needs() + - psasim_serialise_uint32_t_needs(max_ops); + psasim_serialise_psa_key_agreement_iop_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(private_key) + + psasim_serialise_buffer_needs(peer_key, peer_key_length) + + psasim_serialise_psa_algorithm_t_needs(alg) + + psasim_serialise_psa_key_attributes_t_needs(*attributes); ser_params = malloc(needed); if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; goto fail; } @@ -3874,17 +4566,41 @@ void psa_interruptible_set_max_ops( if (!ok) { goto fail; } - ok = psasim_serialise_uint32_t( + ok = psasim_serialise_psa_key_agreement_iop_t( &pos, &remaining, - max_ops); + *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + private_key); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer( + &pos, &remaining, + peer_key, peer_key_length); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_algorithm_t( + &pos, &remaining, + alg); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_key_attributes_t( + &pos, &remaining, + *attributes); if (!ok) { goto fail; } - ok = psa_crypto_call(PSA_INTERRUPTIBLE_SET_MAX_OPS, + ok = psa_crypto_call(PSA_KEY_AGREEMENT_IOP_SETUP, ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); if (!ok) { - printf("PSA_INTERRUPTIBLE_SET_MAX_OPS server call failed\n"); + printf("PSA_KEY_AGREEMENT_IOP_SETUP server call failed\n"); goto fail; } @@ -3896,9 +4612,25 @@ void psa_interruptible_set_max_ops( goto fail; } + ok = psasim_deserialise_psa_status_t( + &rpos, &rremain, + &status); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_agreement_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + fail: free(ser_params); free(ser_result); + + return status; } diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index a88fc51cce..599e55f3e4 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -3227,13 +3227,12 @@ int psa_generate_key_custom_wrapper( } // Returns 1 for success, 0 for failure -int psa_generate_random_wrapper( +int psa_generate_key_iop_abort_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 *output = NULL; - size_t output_size; + psa_generate_key_iop_t operation; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3245,24 +3244,24 @@ int psa_generate_random_wrapper( goto fail; } - ok = psasim_deserialise_buffer( + ok = psasim_deserialise_psa_generate_key_iop_t( &pos, &remaining, - &output, &output_size); + &operation); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_generate_random( - output, output_size + status = psa_generate_key_iop_abort( + &operation ); // 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(output, output_size); + psasim_serialise_psa_generate_key_iop_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -3284,9 +3283,9 @@ int psa_generate_random_wrapper( goto fail; } - ok = psasim_serialise_buffer( + ok = psasim_serialise_psa_generate_key_iop_t( &rpos, &rremain, - output, output_size); + operation); if (!ok) { goto fail; } @@ -3294,26 +3293,22 @@ int psa_generate_random_wrapper( *out_params = result; *out_params_len = result_size; - free(output); - return 1; // success fail: free(result); - free(output); - return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_get_key_attributes_wrapper( +int psa_generate_key_iop_complete_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_generate_key_iop_t operation; mbedtls_svc_key_id_t key; - psa_key_attributes_t attributes; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3325,32 +3320,33 @@ int psa_get_key_attributes_wrapper( goto fail; } - ok = psasim_deserialise_mbedtls_svc_key_id_t( + ok = psasim_deserialise_psa_generate_key_iop_t( &pos, &remaining, - &key); + &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_psa_key_attributes_t( + ok = psasim_deserialise_mbedtls_svc_key_id_t( &pos, &remaining, - &attributes); + &key); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_get_key_attributes( - key, - &attributes + status = psa_generate_key_iop_complete( + &operation, + &key ); // 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_psa_key_attributes_t_needs(attributes); + psasim_serialise_psa_generate_key_iop_t_needs(operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); result = malloc(result_size); if (result == NULL) { @@ -3372,9 +3368,16 @@ int psa_get_key_attributes_wrapper( goto fail; } - ok = psasim_serialise_psa_key_attributes_t( + ok = psasim_serialise_psa_generate_key_iop_t( &rpos, &rremain, - attributes); + operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); if (!ok) { goto fail; } @@ -3391,12 +3394,12 @@ int psa_get_key_attributes_wrapper( } // Returns 1 for success, 0 for failure -int psa_hash_abort_wrapper( +int psa_generate_key_iop_get_num_ops_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_hash_operation_t *operation; + uint32_t value = 0; + psa_generate_key_iop_t operation; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3408,7 +3411,7 @@ int psa_hash_abort_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t( + ok = psasim_deserialise_psa_generate_key_iop_t( &pos, &remaining, &operation); if (!ok) { @@ -3417,15 +3420,15 @@ int psa_hash_abort_wrapper( // Now we call the actual target function - status = psa_hash_abort( - operation + value = psa_generate_key_iop_get_num_ops( + &operation ); // 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_server_serialise_psa_hash_operation_t_needs(operation); + psasim_serialise_uint32_t_needs(value) + + psasim_serialise_psa_generate_key_iop_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -3440,16 +3443,16 @@ int psa_hash_abort_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t( + ok = psasim_serialise_uint32_t( &rpos, &rremain, - status); + value); if (!ok) { goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t( + ok = psasim_serialise_psa_generate_key_iop_t( &rpos, &rremain, - operation, 1); + operation); if (!ok) { goto fail; } @@ -3466,13 +3469,13 @@ int psa_hash_abort_wrapper( } // Returns 1 for success, 0 for failure -int psa_hash_clone_wrapper( +int psa_generate_key_iop_setup_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_hash_operation_t *source_operation; - psa_hash_operation_t *target_operation; + psa_generate_key_iop_t operation; + psa_key_attributes_t attributes; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3484,32 +3487,32 @@ int psa_hash_clone_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t( + ok = psasim_deserialise_psa_generate_key_iop_t( &pos, &remaining, - &source_operation); + &operation); if (!ok) { goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t( + ok = psasim_deserialise_psa_key_attributes_t( &pos, &remaining, - &target_operation); + &attributes); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_hash_clone( - source_operation, - target_operation + status = psa_generate_key_iop_setup( + &operation, + &attributes ); // 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_server_serialise_psa_hash_operation_t_needs(target_operation); + psasim_serialise_psa_generate_key_iop_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -3531,9 +3534,9 @@ int psa_hash_clone_wrapper( goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t( + ok = psasim_serialise_psa_generate_key_iop_t( &rpos, &rremain, - target_operation, 0); + operation); if (!ok) { goto fail; } @@ -3550,16 +3553,13 @@ int psa_hash_clone_wrapper( } // Returns 1 for success, 0 for failure -int psa_hash_compare_wrapper( +int psa_generate_random_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_length; + uint8_t *output = NULL; + size_t output_size; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3571,39 +3571,24 @@ int psa_hash_compare_wrapper( 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_length); + &output, &output_size); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_hash_compare( - alg, - input, input_length, - hash, hash_length + status = psa_generate_random( + output, output_size ); // 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_psa_status_t_needs(status) + + psasim_serialise_buffer_needs(output, output_size); result = malloc(result_size); if (result == NULL) { @@ -3625,35 +3610,36 @@ int psa_hash_compare_wrapper( goto fail; } + ok = psasim_serialise_buffer( + &rpos, &rremain, + output, output_size); + if (!ok) { + goto fail; + } + *out_params = result; *out_params_len = result_size; - free(input); - free(hash); + free(output); return 1; // success fail: free(result); - free(input); - free(hash); + free(output); return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_hash_compute_wrapper( +int psa_get_key_attributes_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; + mbedtls_svc_key_id_t key; + psa_key_attributes_t attributes; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3665,49 +3651,32 @@ int psa_hash_compute_wrapper( 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( + ok = psasim_deserialise_mbedtls_svc_key_id_t( &pos, &remaining, - &hash, &hash_size); + &key); if (!ok) { goto fail; } - ok = psasim_deserialise_size_t( + ok = psasim_deserialise_psa_key_attributes_t( &pos, &remaining, - &hash_length); + &attributes); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_hash_compute( - alg, - input, input_length, - hash, hash_size, - &hash_length + status = psa_get_key_attributes( + key, + &attributes ); // 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); + psasim_serialise_psa_key_attributes_t_needs(attributes); result = malloc(result_size); if (result == NULL) { @@ -3729,16 +3698,9 @@ int psa_hash_compute_wrapper( goto fail; } - ok = psasim_serialise_buffer( - &rpos, &rremain, - hash, hash_size); - if (!ok) { - goto fail; - } - - ok = psasim_serialise_size_t( + ok = psasim_serialise_psa_key_attributes_t( &rpos, &rremain, - hash_length); + attributes); if (!ok) { goto fail; } @@ -3746,30 +3708,21 @@ int psa_hash_compute_wrapper( *out_params = result; *out_params_len = result_size; - free(input); - free(hash); - return 1; // success fail: free(result); - free(input); - free(hash); - return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_hash_finish_wrapper( +int psa_hash_abort_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_hash_operation_t *operation; - uint8_t *hash = NULL; - size_t hash_size; - size_t hash_length; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3788,35 +3741,17 @@ int psa_hash_finish_wrapper( 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_finish( - operation, - hash, hash_size, - &hash_length + status = psa_hash_abort( + operation ); // 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_server_serialise_psa_hash_operation_t_needs(operation) + - psasim_serialise_buffer_needs(hash, hash_size) + - psasim_serialise_size_t_needs(hash_length); + psasim_server_serialise_psa_hash_operation_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -3845,16 +3780,822 @@ int psa_hash_finish_wrapper( goto fail; } - ok = psasim_serialise_buffer( - &rpos, &rremain, - hash, hash_size); + *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_clone_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_hash_operation_t *source_operation; + psa_hash_operation_t *target_operation; + + 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_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &source_operation); + if (!ok) { + goto fail; + } + + ok = psasim_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &target_operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_clone( + source_operation, + target_operation + ); + + // 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_server_serialise_psa_hash_operation_t_needs(target_operation); + + 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_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + target_operation, 0); + 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_compare_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_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_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_compare( + alg, + input, input_length, + hash, 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); + + 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; + + free(input); + free(hash); + + return 1; // success + +fail: + free(result); + + free(input); + free(hash); + + 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; + + free(input); + free(hash); + + return 1; // success + +fail: + free(result); + + free(input); + free(hash); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_hash_finish_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_hash_operation_t *operation; + 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_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); + 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_finish( + operation, + 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_server_serialise_psa_hash_operation_t_needs(operation) + + 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_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation, 1); + 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; + + free(hash); + + return 1; // success + +fail: + free(result); + + free(hash); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_hash_setup_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_hash_operation_t *operation; + psa_algorithm_t alg; + + 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_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_setup( + operation, + alg + ); + + // 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_server_serialise_psa_hash_operation_t_needs(operation); + + 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_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation, 0); + 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_update_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_hash_operation_t *operation; + uint8_t *input = NULL; + size_t input_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_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer( + &pos, &remaining, + &input, &input_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_update( + operation, + input, input_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_server_serialise_psa_hash_operation_t_needs(operation); + + 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_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation, 0); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(input); + + return 1; // success + +fail: + free(result); + + free(input); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_hash_verify_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_hash_operation_t *operation; + uint8_t *hash = NULL; + 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_server_deserialise_psa_hash_operation_t( + &pos, &remaining, + &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer( + &pos, &remaining, + &hash, &hash_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_hash_verify( + operation, + hash, 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_server_serialise_psa_hash_operation_t_needs(operation); + + 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_server_serialise_psa_hash_operation_t( + &rpos, &rremain, + operation, 1); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(hash); + + return 1; // success + +fail: + free(result); + + free(hash); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_import_key_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_key_attributes_t attributes; + uint8_t *data = NULL; + size_t data_length; + mbedtls_svc_key_id_t key; + + 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_key_attributes_t( + &pos, &remaining, + &attributes); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer( + &pos, &remaining, + &data, &data_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_import_key( + &attributes, + data, data_length, + &key + ); + + // 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_mbedtls_svc_key_id_t_needs(key); + + 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_mbedtls_svc_key_id_t( + &rpos, &rremain, + key); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(data); + + return 1; // success + +fail: + free(result); + + free(data); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_interruptible_get_max_ops_wrapper( + uint8_t *in_params, size_t in_params_len, + uint8_t **out_params, size_t *out_params_len) +{ + uint32_t value = 0; + + uint8_t *result = NULL; + int ok; + + // Now we call the actual target function + + value = psa_interruptible_get_max_ops( + ); + + // NOTE: Should really check there is no overflow as we go along. + size_t result_size = + psasim_serialise_begin_needs() + + psasim_serialise_uint32_t_needs(value); + + 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_size_t( + ok = psasim_serialise_uint32_t( &rpos, &rremain, - hash_length); + value); if (!ok) { goto fail; } @@ -3862,26 +4603,20 @@ int psa_hash_finish_wrapper( *out_params = result; *out_params_len = result_size; - free(hash); - return 1; // success fail: free(result); - free(hash); - return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_hash_setup_wrapper( +int psa_interruptible_set_max_ops_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_hash_operation_t *operation; - psa_algorithm_t alg; + uint32_t max_ops; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3893,32 +4628,22 @@ int psa_hash_setup_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t( - &pos, &remaining, - &operation); - if (!ok) { - goto fail; - } - - ok = psasim_deserialise_psa_algorithm_t( + ok = psasim_deserialise_uint32_t( &pos, &remaining, - &alg); + &max_ops); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_hash_setup( - operation, - alg + psa_interruptible_set_max_ops( + max_ops ); // 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_server_serialise_psa_hash_operation_t_needs(operation); + psasim_serialise_begin_needs(); result = malloc(result_size); if (result == NULL) { @@ -3933,20 +4658,6 @@ int psa_hash_setup_wrapper( goto fail; } - ok = psasim_serialise_psa_status_t( - &rpos, &rremain, - status); - if (!ok) { - goto fail; - } - - ok = psasim_server_serialise_psa_hash_operation_t( - &rpos, &rremain, - operation, 0); - if (!ok) { - goto fail; - } - *out_params = result; *out_params_len = result_size; @@ -3959,14 +4670,17 @@ int psa_hash_setup_wrapper( } // Returns 1 for success, 0 for failure -int psa_hash_update_wrapper( +int psa_key_agreement_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_hash_operation_t *operation; - uint8_t *input = NULL; - size_t input_length; + mbedtls_svc_key_id_t private_key; + uint8_t *peer_key = NULL; + size_t peer_key_length; + psa_algorithm_t alg; + psa_key_attributes_t attributes; + mbedtls_svc_key_id_t key; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -3978,32 +4692,56 @@ int psa_hash_update_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t( + ok = psasim_deserialise_mbedtls_svc_key_id_t( &pos, &remaining, - &operation); + &private_key); if (!ok) { goto fail; } ok = psasim_deserialise_buffer( &pos, &remaining, - &input, &input_length); + &peer_key, &peer_key_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); if (!ok) { goto fail; } // Now we call the actual target function - status = psa_hash_update( - operation, - input, input_length + status = psa_key_agreement( + private_key, + peer_key, peer_key_length, + alg, + &attributes, + &key ); // 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_server_serialise_psa_hash_operation_t_needs(operation); + psasim_serialise_mbedtls_svc_key_id_t_needs(key); result = malloc(result_size); if (result == NULL) { @@ -4025,9 +4763,9 @@ int psa_hash_update_wrapper( goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t( + ok = psasim_serialise_mbedtls_svc_key_id_t( &rpos, &rremain, - operation, 0); + key); if (!ok) { goto fail; } @@ -4035,27 +4773,25 @@ int psa_hash_update_wrapper( *out_params = result; *out_params_len = result_size; - free(input); + free(peer_key); return 1; // success fail: free(result); - free(input); + free(peer_key); return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_hash_verify_wrapper( +int psa_key_agreement_iop_abort_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_hash_operation_t *operation; - uint8_t *hash = NULL; - size_t hash_length; + psa_key_agreement_iop_t operation; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -4067,32 +4803,24 @@ int psa_hash_verify_wrapper( goto fail; } - ok = psasim_server_deserialise_psa_hash_operation_t( + ok = psasim_deserialise_psa_key_agreement_iop_t( &pos, &remaining, &operation); if (!ok) { goto fail; } - ok = psasim_deserialise_buffer( - &pos, &remaining, - &hash, &hash_length); - if (!ok) { - goto fail; - } - // Now we call the actual target function - status = psa_hash_verify( - operation, - hash, hash_length + status = psa_key_agreement_iop_abort( + &operation ); // 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_server_serialise_psa_hash_operation_t_needs(operation); + psasim_serialise_psa_key_agreement_iop_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -4114,9 +4842,9 @@ int psa_hash_verify_wrapper( goto fail; } - ok = psasim_server_serialise_psa_hash_operation_t( + ok = psasim_serialise_psa_key_agreement_iop_t( &rpos, &rremain, - operation, 1); + operation); if (!ok) { goto fail; } @@ -4124,27 +4852,21 @@ int psa_hash_verify_wrapper( *out_params = result; *out_params_len = result_size; - free(hash); - return 1; // success fail: free(result); - free(hash); - return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_import_key_wrapper( +int psa_key_agreement_iop_complete_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_key_attributes_t attributes; - uint8_t *data = NULL; - size_t data_length; + psa_key_agreement_iop_t operation; mbedtls_svc_key_id_t key; uint8_t *pos = in_params; @@ -4157,16 +4879,9 @@ int psa_import_key_wrapper( goto fail; } - ok = psasim_deserialise_psa_key_attributes_t( - &pos, &remaining, - &attributes); - if (!ok) { - goto fail; - } - - ok = psasim_deserialise_buffer( + ok = psasim_deserialise_psa_key_agreement_iop_t( &pos, &remaining, - &data, &data_length); + &operation); if (!ok) { goto fail; } @@ -4180,9 +4895,8 @@ int psa_import_key_wrapper( // Now we call the actual target function - status = psa_import_key( - &attributes, - data, data_length, + status = psa_key_agreement_iop_complete( + &operation, &key ); @@ -4190,6 +4904,7 @@ int psa_import_key_wrapper( size_t result_size = psasim_serialise_begin_needs() + psasim_serialise_psa_status_t_needs(status) + + psasim_serialise_psa_key_agreement_iop_t_needs(operation) + psasim_serialise_mbedtls_svc_key_id_t_needs(key); result = malloc(result_size); @@ -4212,6 +4927,13 @@ int psa_import_key_wrapper( goto fail; } + ok = psasim_serialise_psa_key_agreement_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t( &rpos, &rremain, key); @@ -4222,37 +4944,50 @@ int psa_import_key_wrapper( *out_params = result; *out_params_len = result_size; - free(data); - return 1; // success fail: free(result); - free(data); - return 0; // This shouldn't happen! } // Returns 1 for success, 0 for failure -int psa_interruptible_get_max_ops_wrapper( +int psa_key_agreement_iop_get_num_ops_wrapper( uint8_t *in_params, size_t in_params_len, uint8_t **out_params, size_t *out_params_len) { uint32_t value = 0; + psa_key_agreement_iop_t operation; + 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_key_agreement_iop_t( + &pos, &remaining, + &operation); + if (!ok) { + goto fail; + } + // Now we call the actual target function - value = psa_interruptible_get_max_ops( + value = psa_key_agreement_iop_get_num_ops( + &operation ); // NOTE: Should really check there is no overflow as we go along. size_t result_size = psasim_serialise_begin_needs() + - psasim_serialise_uint32_t_needs(value); + psasim_serialise_uint32_t_needs(value) + + psasim_serialise_psa_key_agreement_iop_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -4274,6 +5009,13 @@ int psa_interruptible_get_max_ops_wrapper( goto fail; } + ok = psasim_serialise_psa_key_agreement_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + *out_params = result; *out_params_len = result_size; @@ -4286,11 +5028,17 @@ int psa_interruptible_get_max_ops_wrapper( } // Returns 1 for success, 0 for failure -int psa_interruptible_set_max_ops_wrapper( +int psa_key_agreement_iop_setup_wrapper( uint8_t *in_params, size_t in_params_len, uint8_t **out_params, size_t *out_params_len) { - uint32_t max_ops; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_agreement_iop_t operation; + mbedtls_svc_key_id_t private_key; + uint8_t *peer_key = NULL; + size_t peer_key_length; + psa_algorithm_t alg; + psa_key_attributes_t attributes; uint8_t *pos = in_params; size_t remaining = in_params_len; @@ -4302,22 +5050,56 @@ int psa_interruptible_set_max_ops_wrapper( goto fail; } - ok = psasim_deserialise_uint32_t( + ok = psasim_deserialise_psa_key_agreement_iop_t( &pos, &remaining, - &max_ops); + &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &private_key); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer( + &pos, &remaining, + &peer_key, &peer_key_length); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_algorithm_t( + &pos, &remaining, + &alg); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_key_attributes_t( + &pos, &remaining, + &attributes); if (!ok) { goto fail; } // Now we call the actual target function - psa_interruptible_set_max_ops( - max_ops + status = psa_key_agreement_iop_setup( + &operation, + private_key, + peer_key, peer_key_length, + alg, + &attributes ); // NOTE: Should really check there is no overflow as we go along. size_t result_size = - psasim_serialise_begin_needs(); + psasim_serialise_begin_needs() + + psasim_serialise_psa_status_t_needs(status) + + psasim_serialise_psa_key_agreement_iop_t_needs(operation); result = malloc(result_size); if (result == NULL) { @@ -4332,14 +5114,32 @@ int psa_interruptible_set_max_ops_wrapper( goto fail; } + ok = psasim_serialise_psa_status_t( + &rpos, &rremain, + status); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_psa_key_agreement_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + *out_params = result; *out_params_len = result_size; + free(peer_key); + return 1; // success fail: free(result); + free(peer_key); + return 0; // This shouldn't happen! } @@ -7738,6 +8538,22 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_generate_key_custom_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_GENERATE_KEY_IOP_ABORT: + ok = psa_generate_key_iop_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_GENERATE_KEY_IOP_COMPLETE: + ok = psa_generate_key_iop_complete_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_GENERATE_KEY_IOP_GET_NUM_OPS: + ok = psa_generate_key_iop_get_num_ops_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_GENERATE_KEY_IOP_SETUP: + ok = psa_generate_key_iop_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_GENERATE_RANDOM: ok = psa_generate_random_wrapper(in_params, in_params_len, &out_params, &out_params_len); @@ -7790,6 +8606,26 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_interruptible_set_max_ops_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_KEY_AGREEMENT: + ok = psa_key_agreement_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_AGREEMENT_IOP_ABORT: + ok = psa_key_agreement_iop_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_AGREEMENT_IOP_COMPLETE: + ok = psa_key_agreement_iop_complete_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_AGREEMENT_IOP_GET_NUM_OPS: + ok = psa_key_agreement_iop_get_num_ops_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_KEY_AGREEMENT_IOP_SETUP: + ok = psa_key_agreement_iop_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_KEY_DERIVATION_ABORT: ok = psa_key_derivation_abort_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index 44d87d60f1..cd081e479b 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -1660,6 +1660,42 @@ int psasim_deserialise_psa_key_agreement_iop_t(uint8_t **pos, return 1; } +size_t psasim_serialise_psa_generate_key_iop_t_needs( + psa_generate_key_iop_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_generate_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_generate_key_iop_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_generate_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_generate_key_iop_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + void psa_sim_serialize_reset(void) { memset(hash_operation_handles, 0, diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index 02f6bcbe32..a224d82589 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -1344,3 +1344,46 @@ int psasim_serialise_psa_key_agreement_iop_t(uint8_t **pos, int psasim_deserialise_psa_key_agreement_iop_t(uint8_t **pos, size_t *remaining, psa_key_agreement_iop_t *value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_generate_key_iop_t() + * to serialise a `psa_generate_key_iop_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_generate_key_iop_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_generate_key_iop_t_needs( + psa_generate_key_iop_t value); + +/** Serialise a `psa_generate_key_iop_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_generate_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_generate_key_iop_t value); + +/** Deserialise a `psa_generate_key_iop_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_generate_key_iop_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_generate_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_generate_key_iop_t *value); diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 054841ea3a..0dba81e1ef 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -49,7 +49,8 @@ psa_sign_hash_interruptible_operation_t psa_verify_hash_interruptible_operation_t mbedtls_svc_key_id_t - psa_key_agreement_iop_t); + psa_key_agreement_iop_t + sa_generate_key_iop_t); grep(s/-/ /g, @types); From 3beb173ef0af80995d9f4fe5caff13b241377edd Mon Sep 17 00:00:00 2001 From: Harry Ramsey Date: Tue, 22 Oct 2024 10:06:59 +0100 Subject: [PATCH 107/125] Fix paths for programs/psa This commit fixes paths for programs/psa to tf-psa-crypto/programs/psa. Signed-off-by: Harry Ramsey --- psasim/src/aut_psa_aead_encrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/src/aut_psa_aead_encrypt.c b/psasim/src/aut_psa_aead_encrypt.c index 64463f57fc..ccdb62d20f 100644 --- a/psasim/src/aut_psa_aead_encrypt.c +++ b/psasim/src/aut_psa_aead_encrypt.c @@ -47,7 +47,7 @@ void print_buf(const char *title, uint8_t *buf, size_t len) /* Run a PSA function and bail out if it fails. * The symbolic name of the error code can be recovered using: - * programs/psa/psa_constant_name status */ + * tf-psa-crypto/programs/psa/psa_constant_name status */ #define PSA_CHECK(expr) \ do \ { \ From 262f91cee74ef8a0d1daa7f0bbc9bd98f2c6829f Mon Sep 17 00:00:00 2001 From: Harry Ramsey Date: Mon, 4 Nov 2024 15:00:27 +0000 Subject: [PATCH 108/125] Refactor tests and programs comment This commit refactors comments refering to tf-psa-crypto for the correct path upon repo split. Signed-off-by: Harry Ramsey --- psasim/src/aut_psa_aead_encrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/src/aut_psa_aead_encrypt.c b/psasim/src/aut_psa_aead_encrypt.c index ccdb62d20f..64463f57fc 100644 --- a/psasim/src/aut_psa_aead_encrypt.c +++ b/psasim/src/aut_psa_aead_encrypt.c @@ -47,7 +47,7 @@ void print_buf(const char *title, uint8_t *buf, size_t len) /* Run a PSA function and bail out if it fails. * The symbolic name of the error code can be recovered using: - * tf-psa-crypto/programs/psa/psa_constant_name status */ + * programs/psa/psa_constant_name status */ #define PSA_CHECK(expr) \ do \ { \ From 014e84a3fc71ba87addae59f1bc6e83ab27dcd76 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 3 Mar 2025 15:31:55 +0100 Subject: [PATCH 109/125] psasim: add support for psa_export_public_key_iop This commit also includes regenerated C and H files. Signed-off-by: Valerio Setti --- psasim/src/psa_functions_codes.h | 4 + psasim/src/psa_sim_crypto_client.c | 318 ++++++++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 348 +++++++++++++++++++++++++++++ psasim/src/psa_sim_serialise.c | 36 +++ psasim/src/psa_sim_serialise.h | 43 ++++ psasim/src/psa_sim_serialise.pl | 3 +- 6 files changed, 751 insertions(+), 1 deletion(-) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 4be53c5973..7cb8ea80bd 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -39,6 +39,10 @@ enum { PSA_DESTROY_KEY, PSA_EXPORT_KEY, PSA_EXPORT_PUBLIC_KEY, + PSA_EXPORT_PUBLIC_KEY_IOP_ABORT, + PSA_EXPORT_PUBLIC_KEY_IOP_COMPLETE, + PSA_EXPORT_PUBLIC_KEY_IOP_GET_NUM_OPS, + PSA_EXPORT_PUBLIC_KEY_IOP_SETUP, PSA_GENERATE_KEY, PSA_GENERATE_KEY_CUSTOM, PSA_GENERATE_KEY_IOP_ABORT, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index f6efd620cf..e6368ccc6a 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -2725,6 +2725,324 @@ psa_status_t psa_export_public_key( } +psa_status_t psa_export_public_key_iop_abort( + psa_export_public_key_iop_t *operation + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_export_public_key_iop_t_needs(*operation); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_export_public_key_iop_t( + &pos, &remaining, + *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_EXPORT_PUBLIC_KEY_IOP_ABORT, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_EXPORT_PUBLIC_KEY_IOP_ABORT server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_export_public_key_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +psa_status_t psa_export_public_key_iop_complete( + psa_export_public_key_iop_t *operation, + uint8_t *data, size_t data_size, + size_t *data_length + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_export_public_key_iop_t_needs(*operation) + + psasim_serialise_buffer_needs(data, data_size) + + psasim_serialise_size_t_needs(*data_length); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_export_public_key_iop_t( + &pos, &remaining, + *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_buffer( + &pos, &remaining, + data, data_size); + if (!ok) { + goto fail; + } + ok = psasim_serialise_size_t( + &pos, &remaining, + *data_length); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_EXPORT_PUBLIC_KEY_IOP_COMPLETE, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_EXPORT_PUBLIC_KEY_IOP_COMPLETE server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_export_public_key_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_return_buffer( + &rpos, &rremain, + data, data_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t( + &rpos, &rremain, + data_length); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + +uint32_t psa_export_public_key_iop_get_num_ops( + psa_export_public_key_iop_t *operation + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + uint32_t value = 0; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_export_public_key_iop_t_needs(*operation); + + ser_params = malloc(needed); + if (ser_params == NULL) { + value = 0; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_export_public_key_iop_t( + &pos, &remaining, + *operation); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_EXPORT_PUBLIC_KEY_IOP_GET_NUM_OPS, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_EXPORT_PUBLIC_KEY_IOP_GET_NUM_OPS server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_uint32_t( + &rpos, &rremain, + &value); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_psa_export_public_key_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return value; +} + + +psa_status_t psa_export_public_key_iop_setup( + psa_export_public_key_iop_t *operation, + mbedtls_svc_key_id_t key + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_export_public_key_iop_t_needs(*operation) + + psasim_serialise_mbedtls_svc_key_id_t_needs(key); + + ser_params = malloc(needed); + if (ser_params == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto fail; + } + + uint8_t *pos = ser_params; + size_t remaining = needed; + int ok; + ok = psasim_serialise_begin(&pos, &remaining); + if (!ok) { + goto fail; + } + ok = psasim_serialise_psa_export_public_key_iop_t( + &pos, &remaining, + *operation); + if (!ok) { + goto fail; + } + ok = psasim_serialise_mbedtls_svc_key_id_t( + &pos, &remaining, + key); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_EXPORT_PUBLIC_KEY_IOP_SETUP, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_EXPORT_PUBLIC_KEY_IOP_SETUP server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_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_psa_export_public_key_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return status; +} + + psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *key diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index 599e55f3e4..cf09842b62 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -3035,6 +3035,354 @@ int psa_export_public_key_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_export_public_key_iop_abort_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_export_public_key_iop_t operation; + + 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_export_public_key_iop_t( + &pos, &remaining, + &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_export_public_key_iop_abort( + &operation + ); + + // 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_psa_export_public_key_iop_t_needs(operation); + + 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_psa_export_public_key_iop_t( + &rpos, &rremain, + operation); + 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_export_public_key_iop_complete_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_export_public_key_iop_t operation; + uint8_t *data = NULL; + size_t data_size; + size_t data_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_export_public_key_iop_t( + &pos, &remaining, + &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_buffer( + &pos, &remaining, + &data, &data_size); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_size_t( + &pos, &remaining, + &data_length); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_export_public_key_iop_complete( + &operation, + data, data_size, + &data_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_psa_export_public_key_iop_t_needs(operation) + + psasim_serialise_buffer_needs(data, data_size) + + psasim_serialise_size_t_needs(data_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_psa_export_public_key_iop_t( + &rpos, &rremain, + operation); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_buffer( + &rpos, &rremain, + data, data_size); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_size_t( + &rpos, &rremain, + data_length); + if (!ok) { + goto fail; + } + + *out_params = result; + *out_params_len = result_size; + + free(data); + + return 1; // success + +fail: + free(result); + + free(data); + + return 0; // This shouldn't happen! +} + +// Returns 1 for success, 0 for failure +int psa_export_public_key_iop_get_num_ops_wrapper( + uint8_t *in_params, size_t in_params_len, + uint8_t **out_params, size_t *out_params_len) +{ + uint32_t value = 0; + psa_export_public_key_iop_t operation; + + 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_export_public_key_iop_t( + &pos, &remaining, + &operation); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + value = psa_export_public_key_iop_get_num_ops( + &operation + ); + + // NOTE: Should really check there is no overflow as we go along. + size_t result_size = + psasim_serialise_begin_needs() + + psasim_serialise_uint32_t_needs(value) + + psasim_serialise_psa_export_public_key_iop_t_needs(operation); + + 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_uint32_t( + &rpos, &rremain, + value); + if (!ok) { + goto fail; + } + + ok = psasim_serialise_psa_export_public_key_iop_t( + &rpos, &rremain, + operation); + 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_export_public_key_iop_setup_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_export_public_key_iop_t operation; + mbedtls_svc_key_id_t key; + + 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_export_public_key_iop_t( + &pos, &remaining, + &operation); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_mbedtls_svc_key_id_t( + &pos, &remaining, + &key); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + status = psa_export_public_key_iop_setup( + &operation, + key + ); + + // 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_psa_export_public_key_iop_t_needs(operation); + + 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_psa_export_public_key_iop_t( + &rpos, &rremain, + operation); + 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_generate_key_wrapper( uint8_t *in_params, size_t in_params_len, diff --git a/psasim/src/psa_sim_serialise.c b/psasim/src/psa_sim_serialise.c index cd081e479b..0dde934ada 100644 --- a/psasim/src/psa_sim_serialise.c +++ b/psasim/src/psa_sim_serialise.c @@ -1696,6 +1696,42 @@ int psasim_deserialise_psa_generate_key_iop_t(uint8_t **pos, return 1; } +size_t psasim_serialise_psa_export_public_key_iop_t_needs( + psa_export_public_key_iop_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_export_public_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_export_public_key_iop_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_export_public_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_export_public_key_iop_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + void psa_sim_serialize_reset(void) { memset(hash_operation_handles, 0, diff --git a/psasim/src/psa_sim_serialise.h b/psasim/src/psa_sim_serialise.h index a224d82589..3b6f08e19d 100644 --- a/psasim/src/psa_sim_serialise.h +++ b/psasim/src/psa_sim_serialise.h @@ -1387,3 +1387,46 @@ int psasim_serialise_psa_generate_key_iop_t(uint8_t **pos, int psasim_deserialise_psa_generate_key_iop_t(uint8_t **pos, size_t *remaining, psa_generate_key_iop_t *value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_export_public_key_iop_t() + * to serialise a `psa_export_public_key_iop_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_export_public_key_iop_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_export_public_key_iop_t_needs( + psa_export_public_key_iop_t value); + +/** Serialise a `psa_export_public_key_iop_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_export_public_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_export_public_key_iop_t value); + +/** Deserialise a `psa_export_public_key_iop_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_export_public_key_iop_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_export_public_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_export_public_key_iop_t *value); diff --git a/psasim/src/psa_sim_serialise.pl b/psasim/src/psa_sim_serialise.pl index 0dba81e1ef..0c9faf42ef 100755 --- a/psasim/src/psa_sim_serialise.pl +++ b/psasim/src/psa_sim_serialise.pl @@ -50,7 +50,8 @@ psa_verify_hash_interruptible_operation_t mbedtls_svc_key_id_t psa_key_agreement_iop_t - sa_generate_key_iop_t); + psa_generate_key_iop_t + psa_export_public_key_iop_t); grep(s/-/ /g, @types); From 5c2687a2921ab7c31679d7bb1c222f69de29712c Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 3 Mar 2025 15:36:00 +0100 Subject: [PATCH 110/125] psasim: add support for psa_can_do_hash() This commit also includes regenerated C and H files. Signed-off-by: Valerio Setti --- psasim/src/psa_functions_codes.h | 1 + psasim/src/psa_sim_crypto_client.c | 62 +++++++++++++++++++++ psasim/src/psa_sim_crypto_server.c | 87 ++++++++++++++++++++++++++++++ psasim/src/psa_sim_generate.pl | 2 + 4 files changed, 152 insertions(+) diff --git a/psasim/src/psa_functions_codes.h b/psasim/src/psa_functions_codes.h index 7cb8ea80bd..74746b653b 100644 --- a/psasim/src/psa_functions_codes.h +++ b/psasim/src/psa_functions_codes.h @@ -26,6 +26,7 @@ enum { PSA_AEAD_VERIFY, PSA_ASYMMETRIC_DECRYPT, PSA_ASYMMETRIC_ENCRYPT, + PSA_CAN_DO_HASH, PSA_CIPHER_ABORT, PSA_CIPHER_DECRYPT, PSA_CIPHER_DECRYPT_SETUP, diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index e6368ccc6a..635a70545a 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -1544,6 +1544,68 @@ psa_status_t psa_asymmetric_encrypt( } +int psa_can_do_hash( + psa_algorithm_t hash_alg + ) +{ + uint8_t *ser_params = NULL; + uint8_t *ser_result = NULL; + size_t result_length; + int value = 0; + + size_t needed = + psasim_serialise_begin_needs() + + psasim_serialise_psa_algorithm_t_needs(hash_alg); + + ser_params = malloc(needed); + if (ser_params == NULL) { + goto fail; + } + + uint8_t *pos = ser_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, + hash_alg); + if (!ok) { + goto fail; + } + + ok = psa_crypto_call(PSA_CAN_DO_HASH, + ser_params, (size_t) (pos - ser_params), &ser_result, &result_length); + if (!ok) { + printf("PSA_CAN_DO_HASH server call failed\n"); + goto fail; + } + + uint8_t *rpos = ser_result; + size_t rremain = result_length; + + ok = psasim_deserialise_begin(&rpos, &rremain); + if (!ok) { + goto fail; + } + + ok = psasim_deserialise_int( + &rpos, &rremain, + &value); + if (!ok) { + goto fail; + } + +fail: + free(ser_params); + free(ser_result); + + return value; +} + + psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) diff --git a/psasim/src/psa_sim_crypto_server.c b/psasim/src/psa_sim_crypto_server.c index cf09842b62..bd121c5433 100644 --- a/psasim/src/psa_sim_crypto_server.c +++ b/psasim/src/psa_sim_crypto_server.c @@ -1705,6 +1705,73 @@ int psa_asymmetric_encrypt_wrapper( return 0; // This shouldn't happen! } +// Returns 1 for success, 0 for failure +int psa_can_do_hash_wrapper( + uint8_t *in_params, size_t in_params_len, + uint8_t **out_params, size_t *out_params_len) +{ + int value = 0; + psa_algorithm_t hash_alg; + + 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, + &hash_alg); + if (!ok) { + goto fail; + } + + // Now we call the actual target function + + value = psa_can_do_hash( + hash_alg + ); + + // NOTE: Should really check there is no overflow as we go along. + size_t result_size = + psasim_serialise_begin_needs() + + psasim_serialise_int_needs(value); + + 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_int( + &rpos, &rremain, + value); + 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_cipher_abort_wrapper( uint8_t *in_params, size_t in_params_len, @@ -8826,6 +8893,10 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_asymmetric_encrypt_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_CAN_DO_HASH: + ok = psa_can_do_hash_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_CIPHER_ABORT: ok = psa_cipher_abort_wrapper(in_params, in_params_len, &out_params, &out_params_len); @@ -8878,6 +8949,22 @@ psa_status_t psa_crypto_call(psa_msg_t msg) ok = psa_export_public_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); break; + case PSA_EXPORT_PUBLIC_KEY_IOP_ABORT: + ok = psa_export_public_key_iop_abort_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_EXPORT_PUBLIC_KEY_IOP_COMPLETE: + ok = psa_export_public_key_iop_complete_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_EXPORT_PUBLIC_KEY_IOP_GET_NUM_OPS: + ok = psa_export_public_key_iop_get_num_ops_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; + case PSA_EXPORT_PUBLIC_KEY_IOP_SETUP: + ok = psa_export_public_key_iop_setup_wrapper(in_params, in_params_len, + &out_params, &out_params_len); + break; case PSA_GENERATE_KEY: ok = psa_generate_key_wrapper(in_params, in_params_len, &out_params, &out_params_len); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index fbceddf8d2..5490337cf8 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -1107,11 +1107,13 @@ sub get_functions my $ret_name = ""; $ret_name = "status" if $ret_type eq "psa_status_t"; $ret_name = "value" if $ret_type eq "uint32_t"; + $ret_name = "value" if $ret_type eq "int"; $ret_name = "(void)" if $ret_type eq "void"; die("ret_name for $ret_type?") unless length($ret_name); my $ret_default = ""; $ret_default = "PSA_ERROR_CORRUPTION_DETECTED" if $ret_type eq "psa_status_t"; $ret_default = "0" if $ret_type eq "uint32_t"; + $ret_default = "0" if $ret_type eq "int"; $ret_default = "(void)" if $ret_type eq "void"; die("ret_default for $ret_type?") unless length($ret_default); From efbb0f4321214499aad6dcb8a81f4b915751db20 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 4 Mar 2025 10:14:29 +0100 Subject: [PATCH 111/125] psasim: update README file The README file content dates back to the early stages of PSASIM development. Since then a lot of things have changed, so the README file required a complete rewrite. Signed-off-by: Valerio Setti --- psasim/README.md | 77 ++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 48 deletions(-) diff --git a/psasim/README.md b/psasim/README.md index 1b950d6b1d..db49ae9473 100644 --- a/psasim/README.md +++ b/psasim/README.md @@ -1,61 +1,42 @@ # psasim -This tool simulates a PSA Firmware Framework implementation. -It allows you to develop secure partitions and their clients on a desktop computer. -It should be able to run on all systems that support POSIX and System V IPC: -e.g. macOS, Linux, FreeBSD, and perhaps Windows 10 WSL2. +PSASIM holds necessary C source and header files which allows to test Mbed TLS in a "pure crypto client" scenario, i.e `MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C`. +In practical terms it means that this allow to build PSASIM with Mbed TLS sources and get 2 Linux applications, a client and a server, which are connected through Linux's shared memeory, and in which the client relies on the server to perform all PSA Crypto operations. -Please note that the code in this directory is maintained by the Mbed TLS / PSA Crypto project solely for the purpose of testing the use of Mbed TLS with client/service separation. We do not recommend using this code for any other purpose. In particular: +The goal of PSASIM is _not_ to provide a ready-to-use solution for anyone looking to implement the pure crypto client structure (see [Limitations](#limitations) for details), but to provide an example of TF-PSA-Crypto RPC (Remote Procedure Call) implementation using Mbed TLS. +## Limitations -* This simulator is not intended to pass or demonstrate compliance. -* This code is only intended for simulation and does not have any security goals. It does not isolate services from clients. +In the current implementation: -## Building +- Only Linux PC is supported. +- There can be only 1 client connected to 1 server. +- Shared memory is the only communication medium allowed. Others can be implemented (ex: net sockets), but in terms of simulation speed shared memory proved to be the fastest. +- Server is not secure at all: keys and operation structs are stored on the RAM, so they can easily be dumped. -To build and run the test program make sure you have `make`, `python` and a -C compiler installed and then enter the following commands: +## Testing -```sh -make run -``` +Please refer to `tests/scripts/components-psasim.sh` for guidance on how to build & test PSASIM: -Optionally the `DEBUG=1` command line option can be enabled to increase verbosity: +- `component_test_psasim()`: builds the server and a couple of test clients which are used to evaluate some basic PSA Crypto API commands. +- `component_test_suite_with_psasim()`: builds the server and _all_ the usual test suites (those found under the `/tests/suites/*` folder) which are used by the CI and runs them. A small subset of test suites (`test_suite_constant_time_hmac`,`test_suite_lmots`,`test_suite_lms`) are being skipped, for CI turnover time optimization. They can be run locally if required. -```sh -make DEBUG=1 run -``` +## How to update automatically generated files -Once done with the test, it is possible to clean all the generated files with: +A significant portion of the intermediate code of PSASIM is auto-generated using Perl. In particular: -```sh -make clean -``` +- `psa_sim_serialise.[c|h]`: + - Generated by `psa_sim_serialise.pl`. + - These files provide the serialisation/deserialisation support that is required to pass functions' parameters between client and server. +- `psa_sim_crypto_[client|server].c` and `psa_functions_codes.h`: + - Generated by `psa_sim_generate.pl`. + - `psa_sim_crypto_[client|server].c` provide interfaces for PSA Crypto APIs on client and server sides, while `psa_functions_codes.h` simply enumerates all PSA Crypto APIs. -## Features +These files need to be regenerated whenever some PSA Crypto API is added/deleted/modified. The procedure is as follows: -The implemented API is intended to be compliant with PSA-FF 1.0.0 with the exception of a couple of things that are a work in progress: - -* `psa_notify` support -* "strict" policy in manifest - -The only supported "interrupts" are POSIX signals, which act -as a "virtual interrupt". - -The standard PSA RoT APIs are not included (e.g. cryptography, attestation, lifecycle etc). - -## Design - -The code is designed to be readable rather than fast or secure. -In this implementation only one message is delivered to a -RoT service at a time. -The code is not thread-safe. - -## Unsupported features - -Because this is a simulator there are a few things that -can't be reasonably emulated: - -* Manifest MMIO regions are unsupported -* Manifest priority field is ignored -* Partition IDs are in fact POSIX `pid_t`, which are only assigned at runtime, - making it infeasible to populate pid.h with correct values. +- `psa_sim_serialise.[c|h]`: + - go to `/tests/psa-client-server/psasim/src/` + - run `./psa_sim_serialise.pl h > psa_sim_serialise.h` + - run `./psa_sim_serialise.pl c > psa_sim_serialise.c` +- `psa_sim_crypto_[client|server].c` and `psa_functions_codes.h`: + - go to Mbed TLS' root folder + - run `./tests/psa-client-server/psasim/src/psa_sim_generate.pl` From b5d675a5ad18136dcc16b0de5357ed140894d8db Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 21 Mar 2025 15:32:09 +0100 Subject: [PATCH 112/125] tests: psasim: remove references to mbedtls_psa_register_se_key() Signed-off-by: Valerio Setti --- psasim/src/psa_sim_generate.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 5490337cf8..5770deaa80 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -29,7 +29,6 @@ 'mbedtls_psa_get_stats', # uses unsupported type 'mbedtls_psa_inject_entropy', # not in the default config, generally not for client use anyway 'mbedtls_psa_platform_get_builtin_key', # not in the default config, uses unsupported type - 'mbedtls_psa_register_se_key', # not in the default config, generally not for client use anyway 'psa_get_key_slot_number', # not in the default config, uses unsupported type 'psa_key_derivation_verify_bytes', # not implemented yet 'psa_key_derivation_verify_key', # not implemented yet From 5e1cd71053a8d61da3b15ec94be792b12c185657 Mon Sep 17 00:00:00 2001 From: Felix Conway Date: Wed, 19 Mar 2025 09:31:59 +0000 Subject: [PATCH 113/125] [development] Remove code relating to MBEDTLS_PSA_INJECT_ENTROPY Signed-off-by: Felix Conway --- psasim/src/psa_sim_generate.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 5770deaa80..3eec226e16 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -27,7 +27,6 @@ 'mbedtls_psa_crypto_free', # redefined rather than wrapped 'mbedtls_psa_external_get_random', # not in the default config, uses unsupported type 'mbedtls_psa_get_stats', # uses unsupported type - 'mbedtls_psa_inject_entropy', # not in the default config, generally not for client use anyway 'mbedtls_psa_platform_get_builtin_key', # not in the default config, uses unsupported type 'psa_get_key_slot_number', # not in the default config, uses unsupported type 'psa_key_derivation_verify_bytes', # not implemented yet From 21fb2409c77f278beedfa227f51cfd3cbd290d23 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 8 Apr 2025 14:04:57 +0200 Subject: [PATCH 114/125] psasim: add timeout while waiting for psa_server to start Signed-off-by: Valerio Setti --- psasim/test/start_server.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/psasim/test/start_server.sh b/psasim/test/start_server.sh index ef11439777..1249930af1 100755 --- a/psasim/test/start_server.sh +++ b/psasim/test/start_server.sh @@ -8,7 +8,14 @@ set -e # The server creates some local files when it starts up so we can wait for this # event as signal that the server is ready so that we can start client(s). function wait_for_server_startup() { + SECONDS=0 + TIMEOUT=10 + while [ $(find . -name "psa_notify_*" | wc -l) -eq 0 ]; do + if [ "$SECONDS" -ge "$TIMEOUT" ]; then + echo "Timeout: psa_server not started within $TIMEOUT seconds." + return 1 + fi sleep 0.1 done } From 5378540ce1a99096307e833c8bf1537966629602 Mon Sep 17 00:00:00 2001 From: Felix Conway Date: Wed, 11 Jun 2025 16:04:06 +0100 Subject: [PATCH 115/125] Add __attribute__ ((nonstring)) to remove unterminated-string-initialization warning Signed-off-by: Felix Conway --- psasim/src/aut_psa_aead_encrypt_decrypt.c | 3 ++- psasim/src/aut_psa_cipher_encrypt_decrypt.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/psasim/src/aut_psa_aead_encrypt_decrypt.c b/psasim/src/aut_psa_aead_encrypt_decrypt.c index ca090ccc66..83cd3c00dd 100644 --- a/psasim/src/aut_psa_aead_encrypt_decrypt.c +++ b/psasim/src/aut_psa_aead_encrypt_decrypt.c @@ -25,7 +25,8 @@ int psa_aead_encrypt_decrypt_main(void) uint8_t encrypt[BUFFER_SIZE] = { 0 }; uint8_t decrypt[BUFFER_SIZE] = { 0 }; const uint8_t plaintext[] = "Hello World!"; - const uint8_t key_bytes[32] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + /* We need to tell the compiler that we meant to leave out the null character. */ + const uint8_t key_bytes[32] __attribute__ ((nonstring)) = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; uint8_t nonce[PSA_AEAD_NONCE_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CCM)]; size_t nonce_length = sizeof(nonce); size_t ciphertext_length; diff --git a/psasim/src/aut_psa_cipher_encrypt_decrypt.c b/psasim/src/aut_psa_cipher_encrypt_decrypt.c index a923feb618..22d0bfb0f0 100644 --- a/psasim/src/aut_psa_cipher_encrypt_decrypt.c +++ b/psasim/src/aut_psa_cipher_encrypt_decrypt.c @@ -25,7 +25,8 @@ int psa_cipher_encrypt_decrypt_main(void) uint8_t original[BUFFER_SIZE] = { 0 }; uint8_t encrypt[BUFFER_SIZE] = { 0 }; uint8_t decrypt[BUFFER_SIZE] = { 0 }; - const uint8_t key_bytes[32] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + /* We need to tell the compiler that we meant to leave out the null character. */ + const uint8_t key_bytes[32] __attribute__ ((nonstring)) = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; size_t encrypted_length; size_t decrypted_length; From 4d73e5edbc9ef0d5621f342a34723ae846856861 Mon Sep 17 00:00:00 2001 From: Felix Conway Date: Thu, 12 Jun 2025 11:28:56 +0100 Subject: [PATCH 116/125] Replace __attribute__((nonstring)) with macro MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING This macro applies __attribute__((nonstring)) when using a compiler that supports it Signed-off-by: Felix Conway --- psasim/src/aut_psa_aead_encrypt_decrypt.c | 3 ++- psasim/src/aut_psa_cipher_encrypt_decrypt.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/psasim/src/aut_psa_aead_encrypt_decrypt.c b/psasim/src/aut_psa_aead_encrypt_decrypt.c index 83cd3c00dd..313397bbcd 100644 --- a/psasim/src/aut_psa_aead_encrypt_decrypt.c +++ b/psasim/src/aut_psa_aead_encrypt_decrypt.c @@ -26,7 +26,8 @@ int psa_aead_encrypt_decrypt_main(void) uint8_t decrypt[BUFFER_SIZE] = { 0 }; const uint8_t plaintext[] = "Hello World!"; /* We need to tell the compiler that we meant to leave out the null character. */ - const uint8_t key_bytes[32] __attribute__ ((nonstring)) = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + const uint8_t key_bytes[32] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; uint8_t nonce[PSA_AEAD_NONCE_LENGTH(PSA_KEY_TYPE_AES, PSA_ALG_CCM)]; size_t nonce_length = sizeof(nonce); size_t ciphertext_length; diff --git a/psasim/src/aut_psa_cipher_encrypt_decrypt.c b/psasim/src/aut_psa_cipher_encrypt_decrypt.c index 22d0bfb0f0..30b6982e04 100644 --- a/psasim/src/aut_psa_cipher_encrypt_decrypt.c +++ b/psasim/src/aut_psa_cipher_encrypt_decrypt.c @@ -26,7 +26,8 @@ int psa_cipher_encrypt_decrypt_main(void) uint8_t encrypt[BUFFER_SIZE] = { 0 }; uint8_t decrypt[BUFFER_SIZE] = { 0 }; /* We need to tell the compiler that we meant to leave out the null character. */ - const uint8_t key_bytes[32] __attribute__ ((nonstring)) = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + const uint8_t key_bytes[32] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; size_t encrypted_length; size_t decrypted_length; From c5e4828f66814332fba26bfc5e5a7badee1bf973 Mon Sep 17 00:00:00 2001 From: Felix Conway Date: Sat, 14 Jun 2025 22:13:35 +0100 Subject: [PATCH 117/125] Add include so psasim files can find new macro Signed-off-by: Felix Conway --- psasim/src/aut_psa_aead_encrypt_decrypt.c | 1 + psasim/src/aut_psa_cipher_encrypt_decrypt.c | 1 + 2 files changed, 2 insertions(+) diff --git a/psasim/src/aut_psa_aead_encrypt_decrypt.c b/psasim/src/aut_psa_aead_encrypt_decrypt.c index 313397bbcd..a8b57c2efb 100644 --- a/psasim/src/aut_psa_aead_encrypt_decrypt.c +++ b/psasim/src/aut_psa_aead_encrypt_decrypt.c @@ -4,6 +4,7 @@ */ #include "psa/crypto.h" +#include "../tf-psa-crypto/core/common.h" #include #include #include diff --git a/psasim/src/aut_psa_cipher_encrypt_decrypt.c b/psasim/src/aut_psa_cipher_encrypt_decrypt.c index 30b6982e04..25c0b8a61e 100644 --- a/psasim/src/aut_psa_cipher_encrypt_decrypt.c +++ b/psasim/src/aut_psa_cipher_encrypt_decrypt.c @@ -4,6 +4,7 @@ */ #include "psa/crypto.h" +#include "../tf-psa-crypto/core/common.h" #include #include #include From 5453522e2662194bc742f204d72e7f6b09b78cb1 Mon Sep 17 00:00:00 2001 From: Ari Weiler-Ofek Date: Thu, 19 Jun 2025 08:55:15 +0100 Subject: [PATCH 118/125] Add explanatory comment above #include "../tf-psa-crypto/core/common.h" Signed-off-by: Ari Weiler-Ofek --- psasim/src/aut_psa_aead_encrypt_decrypt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/psasim/src/aut_psa_aead_encrypt_decrypt.c b/psasim/src/aut_psa_aead_encrypt_decrypt.c index a8b57c2efb..17219938b8 100644 --- a/psasim/src/aut_psa_aead_encrypt_decrypt.c +++ b/psasim/src/aut_psa_aead_encrypt_decrypt.c @@ -4,6 +4,22 @@ */ #include "psa/crypto.h" +/* + * Temporary hack: psasim’s Makefile only does: + * -Itests/psa-client-server/psasim/include + * -I$(MBEDTLS_ROOT_PATH)/include + * -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include + * -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include + * + * None of those cover tf-psa-crypto/core, so we rely on the + * “-I$(MBEDTLS_ROOT_PATH)/include” entry plus a parent-relative + * include "../tf-psa-crypto/core/common.h" in order to pull in common.h here, + * which in turn gets MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING (to silence the + * new GCC-15 unterminated-string-initialization warning). + * + * See GitHub issue #10223 for the proper long-term fix. + * https://github.com/Mbed-TLS/mbedtls/issues/10223 + */ #include "../tf-psa-crypto/core/common.h" #include #include From ceaf614e13d2cf52ddd3b22ed5ec4008a63c1291 Mon Sep 17 00:00:00 2001 From: Ari Weiler-Ofek Date: Thu, 19 Jun 2025 18:23:32 +0100 Subject: [PATCH 119/125] Remove trailing whitespace Signed-off-by: Ari Weiler-Ofek --- psasim/src/aut_psa_aead_encrypt_decrypt.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/psasim/src/aut_psa_aead_encrypt_decrypt.c b/psasim/src/aut_psa_aead_encrypt_decrypt.c index 17219938b8..71173d2b52 100644 --- a/psasim/src/aut_psa_aead_encrypt_decrypt.c +++ b/psasim/src/aut_psa_aead_encrypt_decrypt.c @@ -6,17 +6,15 @@ #include "psa/crypto.h" /* * Temporary hack: psasim’s Makefile only does: - * -Itests/psa-client-server/psasim/include - * -I$(MBEDTLS_ROOT_PATH)/include - * -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include - * -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include - * + * -Itests/psa-client-server/psasim/include + * -I$(MBEDTLS_ROOT_PATH)/include + * -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include + * -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include * None of those cover tf-psa-crypto/core, so we rely on the * “-I$(MBEDTLS_ROOT_PATH)/include” entry plus a parent-relative * include "../tf-psa-crypto/core/common.h" in order to pull in common.h here, * which in turn gets MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING (to silence the * new GCC-15 unterminated-string-initialization warning). - * * See GitHub issue #10223 for the proper long-term fix. * https://github.com/Mbed-TLS/mbedtls/issues/10223 */ From 9a7c0219b31232ecefd4f3f399bbcafa6c4c7bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= Date: Fri, 18 Jul 2025 19:10:04 +0200 Subject: [PATCH 120/125] Update references to tf-psa-crypto/core/common.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit was generated using the following command: sed -i 's/\(^\|[^_]\)common\.h/\1tf_psa_crypto_common.h/g' \ $(git ls-files . \ ':!:programs/fuzz' \ ':!:tests/psa-client-server' \ ':!:tf-psa-crypto' \ ':!:framework') \ $(git grep -l 'tf-psa-crypto/core/common.h') Signed-off-by: Bence Szépkúti --- psasim/src/aut_psa_aead_encrypt_decrypt.c | 4 ++-- psasim/src/aut_psa_cipher_encrypt_decrypt.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/psasim/src/aut_psa_aead_encrypt_decrypt.c b/psasim/src/aut_psa_aead_encrypt_decrypt.c index 71173d2b52..87ef39a9ed 100644 --- a/psasim/src/aut_psa_aead_encrypt_decrypt.c +++ b/psasim/src/aut_psa_aead_encrypt_decrypt.c @@ -12,13 +12,13 @@ * -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include * None of those cover tf-psa-crypto/core, so we rely on the * “-I$(MBEDTLS_ROOT_PATH)/include” entry plus a parent-relative - * include "../tf-psa-crypto/core/common.h" in order to pull in common.h here, + * include "../tf-psa-crypto/core/tf_psa_crypto_common.h" in order to pull in tf_psa_crypto_common.h here, * which in turn gets MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING (to silence the * new GCC-15 unterminated-string-initialization warning). * See GitHub issue #10223 for the proper long-term fix. * https://github.com/Mbed-TLS/mbedtls/issues/10223 */ -#include "../tf-psa-crypto/core/common.h" +#include "../tf-psa-crypto/core/tf_psa_crypto_common.h" #include #include #include diff --git a/psasim/src/aut_psa_cipher_encrypt_decrypt.c b/psasim/src/aut_psa_cipher_encrypt_decrypt.c index 25c0b8a61e..82bdca54dc 100644 --- a/psasim/src/aut_psa_cipher_encrypt_decrypt.c +++ b/psasim/src/aut_psa_cipher_encrypt_decrypt.c @@ -4,7 +4,7 @@ */ #include "psa/crypto.h" -#include "../tf-psa-crypto/core/common.h" +#include "../tf-psa-crypto/core/tf_psa_crypto_common.h" #include #include #include From 8aa61ae26254037c3eebe0cf67f946edea315080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= Date: Mon, 18 Aug 2025 14:38:01 +0200 Subject: [PATCH 121/125] Update PSASim tests to new call signature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bence Szépkúti --- psasim/src/psa_sim_crypto_client.c | 4 ++-- psasim/src/psa_sim_generate.pl | 4 ++-- psasim/src/server.c | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/psasim/src/psa_sim_crypto_client.c b/psasim/src/psa_sim_crypto_client.c index 635a70545a..9051f20535 100644 --- a/psasim/src/psa_sim_crypto_client.c +++ b/psasim/src/psa_sim_crypto_client.c @@ -73,12 +73,12 @@ int psa_crypto_call(int function, psa_status_t psa_crypto_init(void) { - char mbedtls_version[18]; + const char *mbedtls_version; uint8_t *result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_version_get_string_full(mbedtls_version); + mbedtls_version = mbedtls_version_get_string_full(); CLIENT_PRINT("%s", mbedtls_version); CLIENT_PRINT("My PID: %d", getpid()); diff --git a/psasim/src/psa_sim_generate.pl b/psasim/src/psa_sim_generate.pl index 3eec226e16..0f4c86f817 100755 --- a/psasim/src/psa_sim_generate.pl +++ b/psasim/src/psa_sim_generate.pl @@ -390,12 +390,12 @@ sub client_calls_header psa_status_t psa_crypto_init(void) { - char mbedtls_version[18]; + const char *mbedtls_version; uint8_t *result = NULL; size_t result_length; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - mbedtls_version_get_string_full(mbedtls_version); + mbedtls_version = mbedtls_version_get_string_full(); CLIENT_PRINT("%s", mbedtls_version); CLIENT_PRINT("My PID: %d", getpid()); diff --git a/psasim/src/server.c b/psasim/src/server.c index 44939f1c2a..aa0c75a488 100644 --- a/psasim/src/server.c +++ b/psasim/src/server.c @@ -56,8 +56,7 @@ int psa_server_main(int argc, char *argv[]) extern psa_status_t psa_crypto_close(void); #if defined(MBEDTLS_VERSION_C) - char mbedtls_version[18]; - mbedtls_version_get_string_full(mbedtls_version); + const char *mbedtls_version = mbedtls_version_get_string_full(); SERVER_PRINT("%s", mbedtls_version); #endif From 831a70a94cf880630ff819fda9c9df9099aeebf8 Mon Sep 17 00:00:00 2001 From: Anton Matkin Date: Mon, 16 Jun 2025 13:37:03 +0200 Subject: [PATCH 122/125] Include fixups (headers moves to private directory) Signed-off-by: Anton Matkin --- psasim/src/aut_psa_random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psasim/src/aut_psa_random.c b/psasim/src/aut_psa_random.c index 5880c4deb9..203f4d44ba 100644 --- a/psasim/src/aut_psa_random.c +++ b/psasim/src/aut_psa_random.c @@ -10,7 +10,7 @@ #include #include -#include "mbedtls/entropy.h" +#include "mbedtls/private/entropy.h" #define BUFFER_SIZE 100 From bb25443571ec17d9035d667d3ab6df1331e1a946 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 26 Sep 2025 16:30:36 +0100 Subject: [PATCH 123/125] Add missing include of stdio.h This is required in util.h in PSASIM as it uses fprintf. Previously stdio was inadvertantly included via psa/crypto_struct.h (of all places). Signed-off-by: David Horstmann --- psasim/include/util.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/psasim/include/util.h b/psasim/include/util.h index 5eb8238c5c..dfc9a32379 100644 --- a/psasim/include/util.h +++ b/psasim/include/util.h @@ -7,6 +7,8 @@ #include "service.h" +#include + #define PRINT(fmt, ...) \ fprintf(stdout, fmt "\n", ##__VA_ARGS__) From cf7fa68367f701d982f9a4fa68483111f791858c Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 3 Dec 2025 23:35:02 +0000 Subject: [PATCH 124/125] psasim: Preparation for importing the Mbedtls:psasim Remove all the files that have been deprecated, and move the files that will be modified by the merge in the appropriate location. This is necessary to allow history parsing using git log --follow after the merge. Signed-off-by: Minos Galanakis --- psasim/include/{psa => }/client.h | 0 psasim/include/{psasim => }/init.h | 0 psasim/include/{psa => }/lifecycle.h | 0 psasim/include/psa/error.h | 36 -- psasim/include/{psa => }/service.h | 0 psasim/src/common.c | 23 - psasim/src/common.h | 85 ---- psasim/src/service.c | 655 --------------------------- psasim/test/Makefile | 12 - psasim/test/client.c | 48 -- psasim/test/manifest.json | 29 -- psasim/test/server.c | 105 ----- 12 files changed, 993 deletions(-) rename psasim/include/{psa => }/client.h (100%) rename psasim/include/{psasim => }/init.h (100%) rename psasim/include/{psa => }/lifecycle.h (100%) delete mode 100644 psasim/include/psa/error.h rename psasim/include/{psa => }/service.h (100%) delete mode 100644 psasim/src/common.c delete mode 100644 psasim/src/common.h delete mode 100644 psasim/src/service.c delete mode 100644 psasim/test/Makefile delete mode 100644 psasim/test/client.c delete mode 100644 psasim/test/manifest.json delete mode 100644 psasim/test/server.c diff --git a/psasim/include/psa/client.h b/psasim/include/client.h similarity index 100% rename from psasim/include/psa/client.h rename to psasim/include/client.h diff --git a/psasim/include/psasim/init.h b/psasim/include/init.h similarity index 100% rename from psasim/include/psasim/init.h rename to psasim/include/init.h diff --git a/psasim/include/psa/lifecycle.h b/psasim/include/lifecycle.h similarity index 100% rename from psasim/include/psa/lifecycle.h rename to psasim/include/lifecycle.h diff --git a/psasim/include/psa/error.h b/psasim/include/psa/error.h deleted file mode 100644 index 2a7558a5d0..0000000000 --- a/psasim/include/psa/error.h +++ /dev/null @@ -1,36 +0,0 @@ -/* PSA status codes used by psasim. */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#ifndef PSA_ERROR_H -#define PSA_ERROR_H -#include -typedef int32_t psa_status_t; - -#define PSA_SUCCESS ((psa_status_t) 0) - -#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t) -129) -#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t) -130) -#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t) -131) -#define PSA_ERROR_GENERIC_ERROR ((psa_status_t) -132) -#define PSA_ERROR_NOT_PERMITTED ((psa_status_t) -133) -#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t) -134) -#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t) -135) -#define PSA_ERROR_INVALID_HANDLE ((psa_status_t) -136) -#define PSA_ERROR_BAD_STATE ((psa_status_t) -137) -#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t) -138) -#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t) -139) -#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t) -140) -#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t) -141) -#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t) -142) -#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t) -143) -#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t) -144) -#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t) -145) -#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t) -146) -#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t) -147) -#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t) -149) - -#endif diff --git a/psasim/include/psa/service.h b/psasim/include/service.h similarity index 100% rename from psasim/include/psa/service.h rename to psasim/include/service.h diff --git a/psasim/src/common.c b/psasim/src/common.c deleted file mode 100644 index 26f3719089..0000000000 --- a/psasim/src/common.c +++ /dev/null @@ -1,23 +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 "common.h" -int __psa_ff_client_security_state = NON_SECURE; - -#if 0 -static void _printbits(uint32_t num) -{ - for (int i = 0; i < 32; i++) { - if ((num >> (31-i) & 0x1)) { - INFO("1"); - } else { - INFO("0"); - } - } - INFO("\n"); -} -#endif diff --git a/psasim/src/common.h b/psasim/src/common.h deleted file mode 100644 index 96760d909f..0000000000 --- a/psasim/src/common.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Common definitions used for clients and services */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include - -#ifdef DEBUG -#define DEBUG_TEST 1 -#else -#define DEBUG_TEST 0 -#endif - -#define PRINT(...) \ - do { if (DEBUG_TEST) fprintf(stderr, __VA_ARGS__); } while (0) -#define INFO(...) \ - do { if (DEBUG_TEST) { PRINT("%s", __FILE__); PRINT(" INFO: " __VA_ARGS__); printf("\n"); \ - } } while (0) - -#define PROGRAMMER_ERROR(...) \ - do { if (DEBUG_TEST) { PRINT("%s:%d:%s(): PROGRAMMER ERROR", __FILE__, __LINE__, __func__); \ - PRINT(__VA_ARGS__); } abort(); } while (0) - -#define FATAL(...) \ - do { if (DEBUG_TEST) { PRINT("%s:%d:%s(): INTERNAL ERROR", __FILE__, __LINE__, __func__); PRINT( \ - __VA_ARGS__); } abort(); } while (0) - - -#define PROJECT_ID 'M' -#define PATHNAMESIZE 64 - -/* Increasing this might break on some platforms */ -#define MAX_FRAGMENT_SIZE 200 - -#define CONNECT_REQUEST 1 -#define CALL_REQUEST 2 -#define CLOSE_REQUEST 3 -#define VERSION_REQUEST 4 -#define READ_REQUEST 5 -#define READ_RESPONSE 6 -#define WRITE_REQUEST 7 -#define WRITE_RESPONSE 8 -#define SKIP_REQUEST 9 -#define PSA_REPLY 10 - -#define NON_SECURE (1 << 30) - -/* Note that this implementation is functional and not secure */ -extern int __psa_ff_client_security_state; - -struct message_text { - int qid; - int32_t psa_type; - char buf[MAX_FRAGMENT_SIZE]; -}; - - -struct message { - long message_type; - struct message_text message_text; -}; - -struct request_msg_internal { - psa_invec invec; - size_t skip_num; -}; - -struct skip_request_msg { - long message_type; - struct request_msg_internal message_text; -}; - -typedef struct vectors { - const psa_invec *in_vec; - size_t in_len; - psa_outvec *out_vec; - size_t out_len; -} vectors_t; - -typedef struct vector_sizes { - size_t invec_sizes[PSA_MAX_IOVEC]; - size_t outvec_sizes[PSA_MAX_IOVEC]; -} vector_sizes_t; diff --git a/psasim/src/service.c b/psasim/src/service.c deleted file mode 100644 index 9bfe20f78a..0000000000 --- a/psasim/src/service.c +++ /dev/null @@ -1,655 +0,0 @@ -/* PSA Firmware Framework service 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 -#include "common.h" - -#define MAX_CLIENTS 128 -#define MAX_MESSAGES 32 - -struct connection { - uint32_t client; - void *rhandle; - int client_to_server_q; // this should be called client to server -}; - -static psa_msg_t messages[MAX_MESSAGES]; /* Message slots */ -static uint8_t pending_message[MAX_MESSAGES] = { 0 }; /* Booleans indicating active message slots */ -static uint32_t message_client[MAX_MESSAGES] = { 0 }; /* Each client's response queue */ -static int nsacl[32]; -static int strict_policy[32] = { 0 }; -static uint32_t rot_svc_versions[32]; -static int rot_svc_incoming_queue[32] = { -1 }; -static struct connection connections[MAX_CLIENTS] = { { 0 } }; - -static uint32_t exposed_signals = 0; - -void print_vectors(vector_sizes_t *sizes) -{ - INFO("Printing iovec sizes"); - for (int j = 0; j < PSA_MAX_IOVEC; j++) { - INFO("Invec %d: %lu", j, sizes->invec_sizes[j]); - } - - for (int j = 0; j < PSA_MAX_IOVEC; j++) { - INFO("Outvec %d: %lu", j, sizes->outvec_sizes[j]); - } -} - -int find_connection(uint32_t client) -{ - for (int i = 1; i < MAX_CLIENTS; i++) { - if (client == connections[i].client) { - return i; - } - } - return -1; -} - -void destroy_connection(uint32_t client) -{ - int idx = find_connection(client); - if (idx >= 0) { - connections[idx].client = 0; - connections[idx].rhandle = 0; - INFO("Destroying connection"); - } else { - INFO("Couldn't destroy connection for %u", client); - } -} - -int find_free_connection() -{ - INFO("Allocating connection"); - return find_connection(0); -} - -static void reply(psa_handle_t msg_handle, psa_status_t status) -{ - pending_message[msg_handle] = 1; - psa_reply(msg_handle, status); - pending_message[msg_handle] = 0; -} - -psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout) -{ - - psa_signal_t mask; - struct message msg; - vector_sizes_t sizes; - struct msqid_ds qinfo; - uint32_t requested_version; - ssize_t len; - int idx; - - if (timeout == PSA_POLL) { - INFO("psa_wait: Called in polling mode"); - } - - do { - mask = signal_mask; - - /* Check the status of each queue */ - for (int i = 0; i < 32; i++) { - if (mask & 0x1) { - if (i < 3) { - // do nothing (reserved) - } else if (i == 3) { - // this must be psa doorbell - } else { - - /* Check if this signal corresponds to a queue */ - if (rot_svc_incoming_queue[i] >= 0 && (pending_message[i] == 0)) { - - /* AFAIK there is no "peek" method in SysV, so try to get a message */ - len = msgrcv(rot_svc_incoming_queue[i], - &msg, - sizeof(struct message_text), - 0, - IPC_NOWAIT); - if (len > 0) { - - INFO("Storing that QID in message_client[%d]\n", i); - INFO("The message handle will be %d\n", i); - - msgctl(rot_svc_incoming_queue[i], IPC_STAT, &qinfo); - messages[i].client_id = qinfo.msg_lspid; /* PID of last msgsnd(2) call */ - message_client[i] = msg.message_text.qid; - idx = find_connection(msg.message_text.qid); - - if (msg.message_type & NON_SECURE) { - /* This is a non-secure message */ - - /* Check if NS client is allowed for this RoT service */ - if (nsacl[i] <= 0) { -#if 0 - INFO( - "Rejecting non-secure client due to manifest security policy"); - reply(i, PSA_ERROR_CONNECTION_REFUSED); - continue; /* Skip to next signal */ -#endif - } - - msg.message_type &= ~(NON_SECURE); /* clear */ - messages[i].client_id = messages[i].client_id * -1; - } - - INFO("Got a message from client ID %d\n", messages[i].client_id); - INFO("Message type is %lu\n", msg.message_type); - INFO("PSA message type is %d\n", msg.message_text.psa_type); - - messages[i].handle = i; - - switch (msg.message_text.psa_type) { - case PSA_IPC_CONNECT: - - if (len >= 16) { - memcpy(&requested_version, msg.message_text.buf, - sizeof(requested_version)); - INFO("Requesting version %u\n", requested_version); - INFO("Implemented version %u\n", rot_svc_versions[i]); - /* TODO: need to check whether the policy is strict, - * and if so, then reject the client if the number doesn't match */ - - if (requested_version > rot_svc_versions[i]) { - INFO( - "Rejecting client because requested version that was too high"); - reply(i, PSA_ERROR_CONNECTION_REFUSED); - continue; /* Skip to next signal */ - } - - if (strict_policy[i] == 1 && - (requested_version != rot_svc_versions[i])) { - INFO( - "Rejecting client because enforcing a STRICT version policy"); - reply(i, PSA_ERROR_CONNECTION_REFUSED); - continue; /* Skip to next signal */ - } else { - INFO("Not rejecting client"); - } - } - - messages[i].type = PSA_IPC_CONNECT; - - if (idx < 0) { - idx = find_free_connection(); - } - - if (idx >= 0) { - connections[idx].client = msg.message_text.qid; - } else { - /* We've run out of system wide connections */ - reply(i, PSA_ERROR_CONNECTION_BUSY); - INFO("Ran out of free connections"); - continue; - } - - break; - case PSA_IPC_DISCONNECT: - messages[i].type = PSA_IPC_DISCONNECT; - break; - case VERSION_REQUEST: - INFO("Got a version request"); - reply(i, rot_svc_versions[i]); - continue; /* Skip to next signal */ - break; - - default: - - /* PSA CALL */ - if (msg.message_text.psa_type >= 0) { - messages[i].type = msg.message_text.psa_type; - memcpy(&sizes, msg.message_text.buf, sizeof(sizes)); - print_vectors(&sizes); - memcpy(&messages[i].in_size, &sizes.invec_sizes, - (sizeof(size_t) * PSA_MAX_IOVEC)); - memcpy(&messages[i].out_size, &sizes.outvec_sizes, - (sizeof(size_t) * PSA_MAX_IOVEC)); - } else { - FATAL("UNKNOWN MESSAGE TYPE RECEIVED %li\n", - msg.message_type); - } - break; - } - messages[i].handle = i; - - /* Check if the client has a connection */ - if (idx >= 0) { - messages[i].rhandle = connections[idx].rhandle; - } else { - /* Client is begging for a programmer error */ - reply(i, PSA_ERROR_PROGRAMMER_ERROR); - continue; - } - - /* House keeping */ - pending_message[i] = 1; /* set message as pending */ - exposed_signals |= (0x1 << i); /* assert the signal */ - } - } - } - mask = mask >> 1; - } - } - - if ((timeout == PSA_BLOCK) && (exposed_signals > 0)) { - break; - } else { - /* There is no 'select' function in SysV to block on multiple queues, so busy-wait :( */ - usleep(50000); - } - } while (timeout == PSA_BLOCK); - - INFO("\n"); - - /* Assert signals */ - return signal_mask & exposed_signals; -} - -static int signal_to_index(psa_signal_t signal) -{ - - int i; - int count = 0; - int ret = -1; - - for (i = 0; i < 32; i++) { - if (signal & 0x1) { - ret = i; - count++; - } - signal = signal >> 1; - } - - if (count > 1) { - INFO("ERROR: Too many signals"); - return -1; /* Too many signals */ - } - return ret; -} - -static void clear_signal(psa_signal_t signal) -{ - exposed_signals = exposed_signals & ~signal; -} - -void raise_signal(psa_signal_t signal) -{ - exposed_signals |= signal; -} - -psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg) -{ - int index = signal_to_index(signal); - if (index < 0) { - PROGRAMMER_ERROR("Bad signal\n"); - } - - clear_signal(signal); - - assert(messages[index].handle != 0); - - if (pending_message[index] == 1) { - INFO("There is a pending message!"); - memcpy(msg, &messages[index], sizeof(struct psa_msg_t)); - assert(msg->handle != 0); - return PSA_SUCCESS; - } else { - INFO("no pending message"); - } - - return PSA_ERROR_DOES_NOT_EXIST; -} - -static int is_valid_msg_handle(psa_handle_t h) -{ - if (h > 0 && h < MAX_MESSAGES) { - return 1; - } - PROGRAMMER_ERROR("Not a valid message handle"); -} - -static inline int is_call_msg(psa_handle_t h) -{ - assert(messages[h].type >= PSA_IPC_CALL); - return 1; -} - -void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle) -{ - is_valid_msg_handle(msg_handle); - int idx = find_connection(message_client[msg_handle]); - INFO("Setting rhandle to %p", rhandle); - assert(idx >= 0); - connections[idx].rhandle = rhandle; -} - -/* Sends a message from the server to the client. Does not wait for a response */ -static void send_msg(psa_handle_t msg_handle, - int ctrl_msg, - psa_status_t status, - size_t amount, - const void *data, - size_t data_amount) -{ - - struct message response; - int flags = 0; - - assert(ctrl_msg > 0); /* According to System V, it must be greater than 0 */ - - response.message_type = ctrl_msg; - if (ctrl_msg == PSA_REPLY) { - memcpy(response.message_text.buf, &status, sizeof(psa_status_t)); - } else if (ctrl_msg == READ_REQUEST || ctrl_msg == WRITE_REQUEST || ctrl_msg == SKIP_REQUEST) { - memcpy(response.message_text.buf, &status, sizeof(psa_status_t)); - memcpy(response.message_text.buf+sizeof(size_t), &amount, sizeof(size_t)); - if (ctrl_msg == WRITE_REQUEST) { - /* TODO: Check if too big */ - memcpy(response.message_text.buf + (sizeof(size_t) * 2), data, data_amount); - } - } - - /* TODO: sizeof doesn't need to be so big here for small responses */ - if (msgsnd(message_client[msg_handle], &response, sizeof(response.message_text), flags) == -1) { - INFO("Failed to reply"); - } -} - -static size_t skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes) -{ - if (num_bytes < (messages[msg_handle].in_size[invec_idx] - num_bytes)) { - messages[msg_handle].in_size[invec_idx] = messages[msg_handle].in_size[invec_idx] - - num_bytes; - return num_bytes; - } else { - if (num_bytes >= messages[msg_handle].in_size[invec_idx]) { - size_t ret = messages[msg_handle].in_size[invec_idx]; - messages[msg_handle].in_size[invec_idx] = 0; - return ret; - } else { - return num_bytes; - } - } -} - -size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx, - void *buffer, size_t num_bytes) -{ - size_t sofar = 0; - struct message msg = { 0 }; - int idx; - ssize_t len; - - is_valid_msg_handle(msg_handle); - is_call_msg(msg_handle); - - if (invec_idx >= PSA_MAX_IOVEC) { - PROGRAMMER_ERROR("Invalid iovec number"); - } - - /* If user wants more data than what's available, truncate their request */ - if (num_bytes > messages[msg_handle].in_size[invec_idx]) { - num_bytes = messages[msg_handle].in_size[invec_idx]; - } - - while (sofar < num_bytes) { - INFO("Server: requesting %lu bytes from client\n", (num_bytes - sofar)); - send_msg(msg_handle, READ_REQUEST, invec_idx, (num_bytes - sofar), NULL, 0); - - idx = find_connection(message_client[msg_handle]); - assert(idx >= 0); - - len = msgrcv(connections[idx].client_to_server_q, &msg, sizeof(struct message_text), 0, 0); - len = (len - sizeof(msg.message_text.qid)); - - if (len < 0) { - FATAL("Internal error: failed to dispatch read request to the client"); - } - - if (len > (num_bytes - sofar)) { - if ((num_bytes - sofar) > 0) { - memcpy(buffer+sofar, msg.message_text.buf, (num_bytes - sofar)); - } - } else { - memcpy(buffer + sofar, msg.message_text.buf, len); - } - - INFO("Printing what i got so far: %s\n", msg.message_text.buf); - - sofar = sofar + len; - } - - /* Update the seek count */ - skip(msg_handle, invec_idx, num_bytes); - INFO("Finished psa_read"); - return sofar; -} - -void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, - const void *buffer, size_t num_bytes) -{ - - size_t sofar = 0; - struct message msg = { 0 }; - int idx; - ssize_t len; - - is_valid_msg_handle(msg_handle); - is_call_msg(msg_handle); - - if (outvec_idx >= PSA_MAX_IOVEC) { - PROGRAMMER_ERROR("Invalid iovec number"); - } - - if (num_bytes > messages[msg_handle].out_size[outvec_idx]) { - PROGRAMMER_ERROR("Program tried to write too much data %lu/%lu", num_bytes, - messages[msg_handle].out_size[outvec_idx]); - } - - while (sofar < num_bytes) { - size_t sending = (num_bytes - sofar); - if (sending >= MAX_FRAGMENT_SIZE) { - sending = MAX_FRAGMENT_SIZE - (sizeof(size_t) * 2); - } - - INFO("Server: sending %lu bytes to client\n", sending); - - send_msg(msg_handle, WRITE_REQUEST, outvec_idx, sending, buffer, sending); - - idx = find_connection(message_client[msg_handle]); - assert(idx >= 0); - - len = msgrcv(connections[idx].client_to_server_q, &msg, sizeof(struct message_text), 0, 0); - if (len < 1) { - FATAL("Client didn't give me a full response"); - } - sofar = sofar + len; - } - - /* Update the seek count */ - messages[msg_handle].out_size[outvec_idx] -= num_bytes; -} - -size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes) -{ - - is_valid_msg_handle(msg_handle); - is_call_msg(msg_handle); - - size_t ret = skip(msg_handle, invec_idx, num_bytes); - - /* notify client to skip */ - send_msg(msg_handle, SKIP_REQUEST, invec_idx, num_bytes, NULL, 0); - return ret; -} - -static void destroy_temporary_queue(int myqid) -{ - - if (msgctl(myqid, IPC_RMID, NULL) != 0) { - INFO("ERROR: Failed to delete msg queue %d", myqid); - } -} - -static int make_temporary_queue() -{ - int myqid; - if ((myqid = msgget(IPC_PRIVATE, 0660)) == -1) { - INFO("msgget: myqid"); - return -1; - } - return myqid; -} - -/** - * Assumes msg_handle is the index into the message array - */ -void psa_reply(psa_handle_t msg_handle, psa_status_t status) -{ - int idx, q; - is_valid_msg_handle(msg_handle); - - if (pending_message[msg_handle] != 1) { - PROGRAMMER_ERROR("Not a valid message handle"); - } - - if (messages[msg_handle].type == PSA_IPC_CONNECT) { - switch (status) { - case PSA_SUCCESS: - idx = find_connection(message_client[msg_handle]); - q = make_temporary_queue(); - if (q > 0 && idx >= 0) { - connections[idx].client_to_server_q = q; - status = q; - } else { - FATAL("What happened?"); - } - break; - case PSA_ERROR_CONNECTION_REFUSED: - destroy_connection(message_client[msg_handle]); - break; - case PSA_ERROR_CONNECTION_BUSY: - destroy_connection(message_client[msg_handle]); - break; - case PSA_ERROR_PROGRAMMER_ERROR: - destroy_connection(message_client[msg_handle]); - break; - default: - PROGRAMMER_ERROR("Not a valid reply %d\n", status); - } - } else if (messages[msg_handle].type == PSA_IPC_DISCONNECT) { - idx = find_connection(message_client[msg_handle]); - if (idx >= 0) { - destroy_temporary_queue(connections[idx].client_to_server_q); - } - destroy_connection(message_client[msg_handle]); - } - - send_msg(msg_handle, PSA_REPLY, status, 0, NULL, 0); - - pending_message[msg_handle] = 0; - message_client[msg_handle] = 0; -} - -/* TODO: make sure you only clear interrupt signals, and not others */ -void psa_eoi(psa_signal_t signal) -{ - int index = signal_to_index(signal); - if (index >= 0 && (rot_svc_incoming_queue[index] >= 0)) { - clear_signal(signal); - } else { - PROGRAMMER_ERROR("Tried to EOI a signal that isn't an interrupt"); - } -} - -void psa_notify(int32_t partition_id) -{ - char pathname[PATHNAMESIZE] = { 0 }; - - if (partition_id < 0) { - PROGRAMMER_ERROR("Not a valid secure partition"); - } - - snprintf(pathname, PATHNAMESIZE, "/tmp/psa_notify_%u", partition_id); - INFO("psa_notify: notifying partition %u using %s", - partition_id, pathname); - INFO("psa_notify is unimplemented"); -} - -void psa_clear(void) -{ - clear_signal(PSA_DOORBELL); -} - -void __init_psasim(const char **array, - int size, - const int allow_ns_clients_array[32], - const uint32_t versions[32], - const int strict_policy_array[32]) -{ - - static uint8_t library_initialised = 0; - key_t key; - int qid; - FILE *fp; - char doorbell_path[PATHNAMESIZE] = { 0 }; - snprintf(doorbell_path, PATHNAMESIZE, "/tmp/psa_notify_%u", getpid()); - - if (library_initialised > 0) { - return; - } else { - library_initialised = 1; - } - - if (size != 32) { - FATAL("Unsupported value. Aborting."); - } - - array[3] = doorbell_path; - - for (int i = 0; i < 32; i++) { - if (strncmp(array[i], "", 1) != 0) { - INFO("Setting up %s", array[i]); - - /* Create file if doesn't exist */ - fp = fopen(array[i], "ab+"); - if (fp) { - fclose(fp); - } - - if ((key = ftok(array[i], PROJECT_ID)) == -1) { - FATAL("Error finding message queue during initialisation"); - } - - /* TODO: Investigate. Permissions are likely to be too relaxed */ - if ((qid = msgget(key, IPC_CREAT | 0660)) == -1) { - FATAL("Error opening message queue during initialisation"); - } else { - rot_svc_incoming_queue[i] = qid; - } - } - } - - memcpy(nsacl, allow_ns_clients_array, sizeof(int) * 32); - memcpy(strict_policy, strict_policy_array, sizeof(int) * 32); - memcpy(rot_svc_versions, versions, sizeof(uint32_t) * 32); - bzero(&connections, sizeof(struct connection) * MAX_CLIENTS); - - __psa_ff_client_security_state = 0; /* Set the client status to SECURE */ -} diff --git a/psasim/test/Makefile b/psasim/test/Makefile deleted file mode 100644 index 07d1586cd6..0000000000 --- a/psasim/test/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -INCLUDE := -I../include/ -I./psa_manifest - -.PHONY: all clean - -all: - psa_autogen manifest.json - $(CC) psa_ff_bootstrap_TEST_PARTITION.c -lpsaff -o partition - $(CC) client.c -lpsaff -o client - -clean: - rm -rf psa_manifest - rm -f client partition psa_ff_bootstrap_TEST_PARTITION.c diff --git a/psasim/test/client.c b/psasim/test/client.c deleted file mode 100644 index c768a71a97..0000000000 --- a/psasim/test/client.c +++ /dev/null @@ -1,48 +0,0 @@ -/* psasim test client */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include -#include "psa_manifest/sid.h" -#include -#include - -int main() -{ - - const char *text = "FOOBARCOOL!!"; - - char output[100] = { 0 }; - printf("My PID is %d\n", getpid()); - - printf("The version of the service is %u\n", psa_version(PSA_SID_SHA256_SID)); - psa_handle_t h = psa_connect(PSA_SID_SHA256_SID, 1); - - if (h < 0) { - printf("Couldn't connect %d\n", h); - return 1; - } else { - int type = 2; - puts("Calling!"); - puts("Trying without invec"); - printf("Answer to my call was %d (no invec)\n", psa_call(h, type, NULL, 0, NULL, 0)); - psa_invec invecs[1]; - psa_outvec outvecs[1]; - invecs[0].base = text; - invecs[0].len = 24; - outvecs[0].base = output; - outvecs[0].len = 99; - - printf("My iovec size should be %lu\n", invecs[0].len); - printf("Answer to my call was %d (with invec)\n", psa_call(h, type, invecs, 1, outvecs, 1)); - printf("Here's the payload I recieved: %s\n", output); - printf("Apparently the server wrote %lu bytes in outvec %d\n", outvecs[0].len, 0); - puts("Closing handle"); - psa_close(h); - } - - return 0; -} diff --git a/psasim/test/manifest.json b/psasim/test/manifest.json deleted file mode 100644 index 0ab83ef907..0000000000 --- a/psasim/test/manifest.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "psa_framework_version":1.0, - "name":"TEST_PARTITION", - "type":"PSA-ROT", - "priority":"LOW", - "entry_point":"psa_sha256_main", - "stack_size":"0x400", - "heap_size":"0x100", - "services":[ - { - "name":"PSA_SID_SHA256", - "sid":"0x0000F000", - "signal":"PSA_SHA256", - "non_secure_clients": "true", - "minor_version":1, - "minor_policy":"STRICT" - } - ], - "irqs": [ - { - "source": "SIGINT", - "signal": "SIGINT_SIG" - }, - { - "source": "SIGTSTP", - "signal": "SIGSTP_SIG" - } - ] -} diff --git a/psasim/test/server.c b/psasim/test/server.c deleted file mode 100644 index bbd90f20fc..0000000000 --- a/psasim/test/server.c +++ /dev/null @@ -1,105 +0,0 @@ -/* psasim test server */ - -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - -#include -#include "psa_manifest/manifest.h" -#include -#include - -void printbits(uint32_t num) -{ - for (int i = 0; i < 32; i++) { - if ((num >> (31-i) & 0x1)) { - printf("1"); - } else { - printf("0"); - } - } - printf("\n"); -} - -#define BUF_SIZE 25 - -int psa_sha256_main() -{ - psa_status_t ret = PSA_ERROR_PROGRAMMER_ERROR; - psa_msg_t msg = { -1 }; - char foo[BUF_SIZE] = { 0 }; - const int magic_num = 66; - - puts("Starting"); - - while (1) { - puts("Calling psa_wait"); - psa_signal_t signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK); - - if (signals > 0) { - printbits(signals); - } - - if (signals & PSA_SHA256_SIGNAL) { - puts("Oooh a signal!"); - - if (PSA_SUCCESS == psa_get(PSA_SHA256_SIGNAL, &msg)) { - printf("My handle is %d\n", msg.handle); - printf("My rhandle is %p\n", (int *) msg.rhandle); - switch (msg.type) { - case PSA_IPC_CONNECT: - puts("Got a connection message"); - psa_set_rhandle(msg.handle, (void *) &magic_num); - ret = PSA_SUCCESS; - break; - case PSA_IPC_DISCONNECT: - puts("Got a disconnection message"); - ret = PSA_SUCCESS; - break; - - default: - printf("Got an IPC call of type %d\n", msg.type); - ret = 42; - size_t size = msg.in_size[0]; - - if ((size > 0) && (size <= sizeof(foo))) { - psa_read(msg.handle, 0, foo, 6); - foo[(BUF_SIZE-1)] = '\0'; - printf("Reading payload: %s\n", foo); - psa_read(msg.handle, 0, foo+6, 6); - foo[(BUF_SIZE-1)] = '\0'; - printf("Reading payload: %s\n", foo); - } - - size = msg.out_size[0]; - if ((size > 0)) { - puts("Writing response"); - psa_write(msg.handle, 0, "RESP", 4); - psa_write(msg.handle, 0, "ONSE", 4); - } - - if (msg.client_id > 0) { - psa_notify(msg.client_id); - } else { - puts("Client is non-secure, so won't notify"); - } - - } - - psa_reply(msg.handle, ret); - } else { - puts("Failed to retrieve message"); - } - } else if (SIGSTP_SIG & signals) { - puts("Recieved SIGSTP signal. Gonna EOI it."); - psa_eoi(SIGSTP_SIG); - } else if (SIGINT_SIG & signals) { - puts("Handling interrupt!\n"); - puts("Gracefully quitting"); - psa_panic(); - } else { - puts("No signal asserted"); - } - } -} From 2583436474b87aa47ee462295a41153d5bd47a82 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 3 Dec 2025 23:46:09 +0000 Subject: [PATCH 125/125] psasim: Update location in Makefile and all-core.sh Signed-off-by: Minos Galanakis --- psasim/Makefile | 2 +- scripts/all-core.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/psasim/Makefile b/psasim/Makefile index ec6691f422..a141807b39 100644 --- a/psasim/Makefile +++ b/psasim/Makefile @@ -7,7 +7,7 @@ endif CLIENT_LIBS := -Lclient_libs -lpsaclient -lmbedtls -lmbedx509 -lmbedcrypto SERVER_LIBS := -Lserver_libs -lmbedcrypto -MBEDTLS_ROOT_PATH = ../../.. +MBEDTLS_ROOT_PATH = ../.. COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include \ -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/include \ -I$(MBEDTLS_ROOT_PATH)/tf-psa-crypto/drivers/builtin/include diff --git a/scripts/all-core.sh b/scripts/all-core.sh index a9070a8e20..50038c10a4 100644 --- a/scripts/all-core.sh +++ b/scripts/all-core.sh @@ -267,7 +267,7 @@ pre_initialize_variables () { # defined in this script whose name starts with "component_". ALL_COMPONENTS=$(compgen -A function component_ | sed 's/component_//') - PSASIM_PATH='tests/psa-client-server/psasim/' + PSASIM_PATH='framework/psasim/' # Delay determining SUPPORTED_COMPONENTS until the command line options have a chance to override # the commands set by the environment