Merge pull request #9310 from valeriosetti/psasim_more_aut_tests
psasim: complete support of PSA functions in `psasim` and add basic "smoke test" applications
diff --git a/tests/psa-client-server/psasim/Makefile b/tests/psa-client-server/psasim/Makefile
index a7e22e1..4b0c46e 100644
--- a/tests/psa-client-server/psasim/Makefile
+++ b/tests/psa-client-server/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 @@
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 @@
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 @@
$(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/tests/psa-client-server/psasim/src/aut_main.c b/tests/psa-client-server/psasim/src/aut_main.c
new file mode 100644
index 0000000..ed19879
--- /dev/null
+++ b/tests/psa-client-server/psasim/src/aut_main.c
@@ -0,0 +1,71 @@
+/**
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+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_asymmetric_encrypt_decrypt_main(void);
+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 { \
+ 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_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_aead_encrypt_decrypt_main());
+ TEST_MODULE(psa_cipher_encrypt_decrypt_main());
+ TEST_MODULE(psa_asymmetric_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_hkdf_main());
+
+exit:
+ return (ret != 0) ? 1 : 0;
+}
diff --git a/tests/psa-client-server/psasim/src/aut_psa_aead_demo.c b/tests/psa-client-server/psasim/src/aut_psa_aead_encrypt.c
similarity index 76%
rename from tests/psa-client-server/psasim/src/aut_psa_aead_demo.c
rename to tests/psa-client-server/psasim/src/aut_psa_aead_encrypt.c
index 4a46c40..64463f5 100644
--- a/tests/psa-client-server/psasim/src/aut_psa_aead_demo.c
+++ b/tests/psa-client-server/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 <stdio.h>
#include <string.h>
-/* 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]";
@@ -257,21 +209,15 @@
/*
* Main function
*/
-int main(int argc, char **argv)
+int psa_aead_encrypt_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();
@@ -279,5 +225,3 @@
exit:
return status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
}
-
-#endif
diff --git a/tests/psa-client-server/psasim/src/aut_psa_aead_encrypt_decrypt.c b/tests/psa-client-server/psasim/src/aut_psa_aead_encrypt_decrypt.c
new file mode 100644
index 0000000..ca090cc
--- /dev/null
+++ b/tests/psa-client-server/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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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;
+}
diff --git a/tests/psa-client-server/psasim/src/aut_psa_asymmetric_encrypt_decrypt.c b/tests/psa-client-server/psasim/src/aut_psa_asymmetric_encrypt_decrypt.c
new file mode 100644
index 0000000..02d8cf4
--- /dev/null
+++ b/tests/psa-client-server/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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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;
+}
diff --git a/tests/psa-client-server/psasim/src/aut_psa_cipher_encrypt_decrypt.c b/tests/psa-client-server/psasim/src/aut_psa_cipher_encrypt_decrypt.c
new file mode 100644
index 0000000..a923feb
--- /dev/null
+++ b/tests/psa-client-server/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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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;
+}
diff --git a/tests/psa-client-server/psasim/src/aut_psa_hash.c b/tests/psa-client-server/psasim/src/aut_psa_hash.c
index 6c2c07e..0446e7a 100644
--- a/tests/psa-client-server/psasim/src/aut_psa_hash.c
+++ b/tests/psa-client-server/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 @@
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 @@
psa_hash_abort(&cloned_hash_operation);
return EXIT_FAILURE;
}
-#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */
diff --git a/tests/psa-client-server/psasim/src/aut_psa_hash_compute.c b/tests/psa-client-server/psasim/src/aut_psa_hash_compute.c
index 70c3e5b..959e0c3 100644
--- a/tests/psa-client-server/psasim/src/aut_psa_hash_compute.c
+++ b/tests/psa-client-server/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 @@
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 @@
cleanup:
return EXIT_FAILURE;
}
-#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */
diff --git a/tests/psa-client-server/psasim/src/aut_psa_hkdf.c b/tests/psa-client-server/psasim/src/aut_psa_hkdf.c
new file mode 100644
index 0000000..891fdb3
--- /dev/null
+++ b/tests/psa-client-server/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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#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;
+}
diff --git a/tests/psa-client-server/psasim/src/aut_psa_key_agreement.c b/tests/psa-client-server/psasim/src/aut_psa_key_agreement.c
new file mode 100644
index 0000000..4a0aab1
--- /dev/null
+++ b/tests/psa-client-server/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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#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;
+}
diff --git a/tests/psa-client-server/psasim/src/aut_psa_mac.c b/tests/psa-client-server/psasim/src/aut_psa_mac.c
new file mode 100644
index 0000000..18b4b57
--- /dev/null
+++ b/tests/psa-client-server/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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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;
+}
diff --git a/tests/psa-client-server/psasim/src/aut_psa_random.c b/tests/psa-client-server/psasim/src/aut_psa_random.c
new file mode 100644
index 0000000..5880c4d
--- /dev/null
+++ b/tests/psa-client-server/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 <psa/crypto.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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;
+}
diff --git a/tests/psa-client-server/psasim/src/aut_psa_sign_verify.c b/tests/psa-client-server/psasim/src/aut_psa_sign_verify.c
new file mode 100644
index 0000000..98df9e5
--- /dev/null
+++ b/tests/psa-client-server/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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#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;
+}
diff --git a/tests/psa-client-server/psasim/src/psa_functions_codes.h b/tests/psa-client-server/psasim/src/psa_functions_codes.h
index c68b416..bc1b844 100644
--- a/tests/psa-client-server/psasim/src/psa_functions_codes.h
+++ b/tests/psa-client-server/psasim/src/psa_functions_codes.h
@@ -24,7 +24,24 @@
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,
+ PSA_CIPHER_ENCRYPT,
+ PSA_CIPHER_ENCRYPT_SETUP,
+ PSA_CIPHER_FINISH,
+ PSA_CIPHER_GENERATE_IV,
+ PSA_CIPHER_SET_IV,
+ PSA_CIPHER_UPDATE,
+ PSA_COPY_KEY,
PSA_DESTROY_KEY,
+ PSA_EXPORT_KEY,
+ PSA_EXPORT_PUBLIC_KEY,
+ PSA_GENERATE_KEY,
+ PSA_GENERATE_KEY_EXT,
+ PSA_GENERATE_RANDOM,
PSA_GET_KEY_ATTRIBUTES,
PSA_HASH_ABORT,
PSA_HASH_CLONE,
@@ -35,6 +52,42 @@
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,
+ 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,
+ PSA_MAC_SIGN_SETUP,
+ PSA_MAC_UPDATE,
+ PSA_MAC_VERIFY,
+ PSA_MAC_VERIFY_FINISH,
+ 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,
+ 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,
};
#endif /* _PSA_FUNCTIONS_CODES_H_ */
diff --git a/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c b/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
index 758e9b2..28dff38 100644
--- a/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
+++ b/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
@@ -129,40 +129,43 @@
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);
+ 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);
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 = 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);
@@ -170,19 +173,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -198,70 +205,85 @@
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;
- 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);
- 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);
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;
}
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);
@@ -269,24 +291,30 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -298,50 +326,57 @@
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;
- 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);
- 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);
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;
}
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);
@@ -349,19 +384,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -377,70 +416,85 @@
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;
- 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);
- 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);
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;
}
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);
@@ -448,24 +502,30 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -477,50 +537,57 @@
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;
- 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);
- 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);
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;
}
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);
@@ -528,19 +595,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -554,60 +625,71 @@
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;
- 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);
- 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);
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;
}
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);
@@ -615,39 +697,51 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -659,50 +753,57 @@
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;
- 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);
- 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);
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;
}
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);
@@ -710,29 +811,37 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -744,50 +853,57 @@
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;
- 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);
- 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);
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;
}
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);
@@ -795,19 +911,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -818,45 +938,50 @@
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;
- 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);
- 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);
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;
}
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);
@@ -864,19 +989,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -889,55 +1018,64 @@
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;
- 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);
- 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);
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;
}
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);
@@ -945,29 +1083,37 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -978,45 +1124,50 @@
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;
- 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);
- 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);
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 = 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);
@@ -1024,19 +1175,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1049,55 +1204,64 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1105,29 +1269,1203 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
+
+ return status;
+}
+
+
+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
+ )
+{
+ 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);
+
+ 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_cipher_operation_t(
+ &pos, &remaining,
+ *operation);
+ if (!ok) {
+ goto fail;
+ }
+
+ ok = psa_crypto_call(PSA_CIPHER_ABORT,
+ 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 = 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_cipher_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_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 *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(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,
+ 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,
+ 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 = 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_decrypt_setup(
+ psa_cipher_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ 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_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) {
+ 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_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,
+ 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 = 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_cipher_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_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 *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(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,
+ 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,
+ 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 = 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_encrypt_setup(
+ psa_cipher_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ 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_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) {
+ 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_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,
+ 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 = 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_cipher_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_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 *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) +
+ 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_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,
+ 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 = 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_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(ser_params);
+ free(ser_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 *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) +
+ psasim_serialise_buffer_needs(iv, iv_size) +
+ psasim_serialise_size_t_needs(*iv_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_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,
+ 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 = 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_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(ser_params);
+ free(ser_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 *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) +
+ psasim_serialise_buffer_needs(iv, iv_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_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,
+ 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 = 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_cipher_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_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 *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) +
+ 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) {
+ 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_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,
+ 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 = 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_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(ser_params);
+ free(ser_result);
+
+ return status;
+}
+
+
+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;
}
@@ -1137,40 +2475,43 @@
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);
+ 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);
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 = 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);
@@ -1178,14 +2519,436 @@
goto fail;
}
- ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status);
+ ok = psasim_deserialise_psa_status_t(
+ &rpos, &rremain,
+ &status);
if (!ok) {
goto fail;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
+
+ return status;
+}
+
+
+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
+ )
+{
+ 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
+ )
+{
+ 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);
+
+ 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_buffer(
+ &pos, &remaining,
+ output, output_size);
+ if (!ok) {
+ goto fail;
+ }
+
+ ok = psa_crypto_call(PSA_GENERATE_RANDOM,
+ 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 = 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;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1196,45 +2959,50 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1242,19 +3010,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1264,40 +3036,43 @@
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);
+ 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);
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 = 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);
@@ -1305,19 +3080,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1328,45 +3107,50 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1374,19 +3158,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1398,50 +3186,57 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1449,14 +3244,16 @@
goto fail;
}
- ok = psasim_deserialise_psa_status_t(&rpos, &rremain, &status);
+ ok = psasim_deserialise_psa_status_t(
+ &rpos, &rremain,
+ &status);
if (!ok) {
goto fail;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1469,55 +3266,64 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1525,24 +3331,30 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1554,50 +3366,57 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1605,29 +3424,37 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1638,45 +3465,50 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1684,19 +3516,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1707,45 +3543,50 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1753,19 +3594,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1776,45 +3621,50 @@
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;
- 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);
- 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);
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;
}
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);
@@ -1822,19 +3672,23 @@
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;
}
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
return status;
}
@@ -1846,50 +3700,57 @@
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_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);
- 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);
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;
}
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);
@@ -1897,19 +3758,3016 @@
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;
}
fail:
- free(params);
- free(result);
+ 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_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
+ )
+{
+ 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);
+
+ 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_mac_operation_t(
+ &pos, &remaining,
+ *operation);
+ if (!ok) {
+ goto fail;
+ }
+
+ ok = psa_crypto_call(PSA_MAC_ABORT,
+ 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 = 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_mac_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_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 *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(mac, mac_size) +
+ psasim_serialise_size_t_needs(*mac_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,
+ 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,
+ 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 = 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,
+ mac, mac_size);
+ if (!ok) {
+ goto fail;
+ }
+
+ ok = psasim_deserialise_size_t(
+ &rpos, &rremain,
+ mac_length);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_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 *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) +
+ psasim_serialise_buffer_needs(mac, mac_size) +
+ psasim_serialise_size_t_needs(*mac_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_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,
+ 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 = 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_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(ser_params);
+ free(ser_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 *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) +
+ psasim_serialise_mbedtls_svc_key_id_t_needs(key) +
+ 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_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,
+ 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 = 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_mac_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_result);
+
+ return status;
+}
+
+
+psa_status_t psa_mac_update(
+ psa_mac_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_mac_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_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,
+ 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 = 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_mac_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_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 *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(mac, mac_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,
+ mac, mac_length);
+ if (!ok) {
+ goto fail;
+ }
+
+ ok = psa_crypto_call(PSA_MAC_VERIFY,
+ 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 = 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_mac_verify_finish(
+ psa_mac_operation_t *operation,
+ const uint8_t *mac, size_t mac_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_mac_operation_t_needs(*operation) +
+ psasim_serialise_buffer_needs(mac, mac_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_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,
+ 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 = 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_mac_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_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 *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) +
+ psasim_serialise_mbedtls_svc_key_id_t_needs(key) +
+ 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_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,
+ 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 = 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_mac_operation_t(
+ &rpos, &rremain,
+ operation);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_result);
+
+ return status;
+}
+
+
+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,
+ 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;
+}
+
+
+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,
+ 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_hash_abort(
+ psa_sign_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_sign_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_sign_hash_interruptible_operation_t(
+ &pos, &remaining,
+ *operation);
+ if (!ok) {
+ goto fail;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+ 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_COMPLETE,
+ ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
+ if (!ok) {
+ printf("PSA_SIGN_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_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;
+ }
+
+ ok = psasim_deserialise_size_t(
+ &rpos, &rremain,
+ signature_length);
+ if (!ok) {
+ goto fail;
+ }
+
+fail:
+ free(ser_params);
+ free(ser_result);
+
+ return status;
+}
+
+
+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
+ )
+{
+ 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_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) {
+ 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;
+ }
+ 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 = psa_crypto_call(PSA_SIGN_HASH_START,
+ ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
+ if (!ok) {
+ printf("PSA_SIGN_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_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);
+
+ 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/tests/psa-client-server/psasim/src/psa_sim_crypto_server.c b/tests/psa-client-server/psasim/src/psa_sim_crypto_server.c
index 30d4b26..5259751 100644
--- a/tests/psa-client-server/psasim/src/psa_sim_crypto_server.c
+++ b/tests/psa-client-server/psasim/src/psa_sim_crypto_server.c
@@ -54,7 +54,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
}
@@ -1262,6 +1424,1335 @@
}
// 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,
+ 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_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,
uint8_t **out_params, size_t *out_params_len)
@@ -1279,7 +2770,9 @@
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;
}
@@ -1308,7 +2801,9 @@
goto fail;
}
- ok = psasim_serialise_psa_status_t(&rpos, &rremain, status);
+ ok = psasim_serialise_psa_status_t(
+ &rpos, &rremain,
+ status);
if (!ok) {
goto fail;
}
@@ -1325,6 +2820,480 @@
}
// 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,
+ 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,
+ 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,
uint8_t **out_params, size_t *out_params_len)
@@ -1343,12 +3312,16 @@
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;
}
@@ -1379,12 +3352,16 @@
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;
}
@@ -1418,7 +3395,9 @@
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;
}
@@ -1448,12 +3427,16 @@
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;
}
@@ -1488,12 +3471,16 @@
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;
}
@@ -1524,12 +3511,16 @@
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;
}
@@ -1567,17 +3558,23 @@
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;
}
@@ -1608,7 +3605,9 @@
goto fail;
}
- ok = psasim_serialise_psa_status_t(&rpos, &rremain, status);
+ ok = psasim_serialise_psa_status_t(
+ &rpos, &rremain,
+ status);
if (!ok) {
goto fail;
}
@@ -1653,22 +3652,30 @@
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;
}
@@ -1702,17 +3709,23 @@
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;
}
@@ -1755,17 +3768,23 @@
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;
}
@@ -1799,22 +3818,30 @@
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;
}
@@ -1853,12 +3880,16 @@
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;
}
@@ -1889,12 +3920,16 @@
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;
}
@@ -1930,12 +3965,16 @@
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;
}
@@ -1966,12 +4005,16 @@
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;
}
@@ -2011,12 +4054,16 @@
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;
}
@@ -2047,12 +4094,16 @@
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;
}
@@ -2093,17 +4144,23 @@
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;
}
@@ -2135,12 +4192,16 @@
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;
}
@@ -2160,6 +4221,3345 @@
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,
+ 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,
+ 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!
+}
+
+// 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,
+ 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!
+}
+
+// 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,
+ 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_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_sign_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_sign_hash_interruptible_operation_t(
+ &pos, &remaining,
+ &operation);
+ if (!ok) {
+ goto fail;
+ }
+
+ // 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_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;
+ }
+
+ 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_complete(
+ operation,
+ 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_server_serialise_psa_sign_hash_interruptible_operation_t_needs(operation) +
+ 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_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;
+ }
+
+ ok = psasim_serialise_size_t(
+ &rpos, &rremain,
+ signature_length);
+ if (!ok) {
+ goto fail;
+ }
+
+ *out_params = result;
+ *out_params_len = result_size;
+
+ free(signature);
+
+ return 1; // success
+
+fail:
+ free(result);
+
+ free(signature);
+
+ return 0; // This shouldn't happen!
+}
+
+// Returns 1 for success, 0 for failure
+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)
+{
+ uint32_t value = 0;
+ psa_sign_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_sign_hash_interruptible_operation_t(
+ &pos, &remaining,
+ &operation);
+ if (!ok) {
+ goto fail;
+ }
+
+ // Now we call the actual target function
+
+ 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_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_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 *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_sign_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;
+ }
+
+ // Now we call the actual target function
+
+ status = psa_sign_hash_start(
+ operation,
+ key,
+ alg,
+ 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_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_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;
+
+ 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_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_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;
@@ -2248,10 +7648,78 @@
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);
+ 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_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);
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);
+ 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);
+ break;
case PSA_GET_KEY_ATTRIBUTES:
ok = psa_get_key_attributes_wrapper(in_params, in_params_len,
&out_params, &out_params_len);
@@ -2292,6 +7760,150 @@
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);
+ 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);
+ 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;
+ 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);
+ 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);
+ 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);
+ break;
+ case PSA_VERIFY_HASH:
+ 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);
+ break;
}
free(in_params);
diff --git a/tests/psa-client-server/psasim/src/psa_sim_generate.pl b/tests/psa-client-server/psasim/src/psa_sim_generate.pl
index 43de1db..ac23807 100755
--- a/tests/psa-client-server/psasim/src/psa_sim_generate.pl
+++ b/tests/psa-client-server/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
@@ -519,6 +529,9 @@
uint8_t *in_params, size_t in_params_len,
uint8_t **out_params, size_t *out_params_len)
{
+EOF
+
+ print $fh <<EOF unless $ret_type eq "void";
$ret_type $ret_name = $ret_default;
EOF
# Output the variables we will need when we call the target function
@@ -538,6 +551,13 @@
size_t $n2;
EOF
push(@buffers, $n1); # Add to the list to be free()d at end
+ } elsif ($argtype =~ /^(const )?psa_key_production_parameters_t$/) {
+ my ($n1, $n2) = split(/,\s*/, $argname);
+ print $fh <<EOF;
+ psa_key_production_parameters_t *$n1 = NULL;
+ size_t $n2;
+EOF
+ 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/) ? "*" : "";
@@ -586,7 +606,20 @@
my ($n1, $n2) = split(/,\s*/, $argname);
print $fh <<EOF;
- ok = psasim_deserialise_${argtype}(&pos, &remaining, &$n1, &$n2);
+ ok = psasim_deserialise_${argtype}(
+ &pos, &remaining,
+ &$n1, &$n2);
+ if (!ok) {
+ goto fail;
+ }
+EOF
+ } elsif ($argtype =~ /^(const )?psa_key_production_parameters_t$/) {
+ my ($n1, $n2) = split(/,\s*/, $argname);
+ print $fh <<EOF;
+
+ ok = psasim_deserialise_${argtype}(
+ &pos, &remaining,
+ &$n1, &$n2);
if (!ok) {
goto fail;
}
@@ -596,7 +629,9 @@
my $server_specific = ($argtype =~ /^psa_\w+_operation_t/) ? "server_" : "";
print $fh <<EOF;
- ok = psasim_${server_specific}deserialise_${argtype}(&pos, &remaining, &$argname);
+ ok = psasim_${server_specific}deserialise_${argtype}(
+ &pos, &remaining,
+ &$argname);
if (!ok) {
goto fail;
}
@@ -612,7 +647,7 @@
my @outputs = grep($_->{is_output}, @$args);
- my $sep1 = ($ret_type eq "void") ? ";" : " +";
+ my $sep1 = (($ret_type eq "void") and ($#outputs < 0)) ? ";" : " +";
print $fh <<EOF;
@@ -662,7 +697,9 @@
if ($ret_type ne "void") {
print $fh <<EOF;
- ok = psasim_serialise_${ret_type}(&rpos, &rremain, $ret_name);
+ ok = psasim_serialise_${ret_type}(
+ &rpos, &rremain,
+ $ret_name);
if (!ok) {
goto fail;
}
@@ -682,7 +719,19 @@
if ($argtype eq "buffer") {
print $fh <<EOF;
- ok = psasim_serialise_buffer(&rpos, &rremain, $argname);
+ ok = psasim_serialise_buffer(
+ &rpos, &rremain,
+ $argname);
+ if (!ok) {
+ goto fail;
+ }
+EOF
+ } elsif ($argtype eq "psa_key_production_parameters_t") {
+ print $fh <<EOF;
+
+ ok = psasim_serialise_psa_key_production_parameters_t(
+ &rpos, &rremain,
+ $argname);
if (!ok) {
goto fail;
}
@@ -698,7 +747,9 @@
print $fh <<EOF;
- ok = psasim_${server_specific}serialise_${argtype}(&rpos, &rremain, $argname);
+ ok = psasim_${server_specific}serialise_${argtype}(
+ &rpos, &rremain,
+ $argname);
if (!ok) {
goto fail;
}
@@ -738,9 +789,11 @@
print $fh <<EOF;
{
- uint8_t *params = NULL;
- uint8_t *result = NULL;
+ uint8_t *ser_params = NULL;
+ uint8_t *ser_result = NULL;
size_t result_length;
+EOF
+ print $fh <<EOF unless $ret_type eq "void";
$ret_type $ret_name = $ret_default;
EOF
@@ -751,7 +804,8 @@
print $fh <<EOF;
- size_t needed = psasim_serialise_begin_needs() +
+ size_t needed =
+ psasim_serialise_begin_needs() +
EOF
my $args = $f->{args};
@@ -764,19 +818,35 @@
$argtype =~ s/^const //;
print $fh <<EOF;
- psasim_serialise_${argtype}_needs($argname)$sep
+ psasim_serialise_${argtype}_needs($argname)$sep
+EOF
+ }
+
+ print $fh <<EOF if $#$args < 0;
+ 0;
+EOF
+
+ print $fh <<EOF;
+
+ ser_params = malloc(needed);
+ if (ser_params == NULL) {
+EOF
+
+ if ($ret_type eq "psa_status_t") {
+ print $fh <<EOF if $;
+ $ret_name = PSA_ERROR_INSUFFICIENT_MEMORY;
+EOF
+ } elsif ($ret_type eq "uint32_t") {
+ print $fh <<EOF if $;
+ $ret_name = 0;
EOF
}
print $fh <<EOF;
-
- params = malloc(needed);
- if (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);
@@ -793,7 +863,9 @@
$argtype =~ s/^const //;
print $fh <<EOF;
- ok = psasim_serialise_${argtype}(&pos, &remaining, $argname);
+ ok = psasim_serialise_${argtype}(
+ &pos, &remaining,
+ $argname);
if (!ok) {
goto fail;
}
@@ -802,8 +874,8 @@
print $fh <<EOF if $debug;
- printf("client sending %d:\\n", (int)(pos - params));
- dump_buffer(params, (size_t)(pos - params));
+ printf("client sending %d:\\n", (int)(pos - ser_params));
+ dump_buffer(ser_params, (size_t)(pos - ser_params));
EOF
my $enum = uc($name);
@@ -811,7 +883,7 @@
print $fh <<EOF;
ok = psa_crypto_call($enum,
- params, (size_t) (pos - params), &result, &result_length);
+ ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
if (!ok) {
printf("$enum server call failed\\n");
goto fail;
@@ -821,12 +893,12 @@
print $fh <<EOF if $debug;
printf("client receiving %d:\\n", (int)result_length);
- dump_buffer(result, result_length);
+ dump_buffer(ser_result, result_length);
EOF
print $fh <<EOF;
- uint8_t *rpos = result;
+ uint8_t *rpos = ser_result;
size_t rremain = result_length;
ok = psasim_deserialise_begin(&rpos, &rremain);
@@ -835,9 +907,11 @@
}
EOF
- print $fh <<EOF;
+ print $fh <<EOF if $ret_type ne "void";
- ok = psasim_deserialise_$ret_type(&rpos, &rremain, &$ret_name);
+ ok = psasim_deserialise_$ret_type(
+ &rpos, &rremain,
+ &$ret_name);
if (!ok) {
goto fail;
}
@@ -856,7 +930,9 @@
if ($argtype eq "buffer") {
print $fh <<EOF;
- ok = psasim_deserialise_return_buffer(&rpos, &rremain, $argname);
+ ok = psasim_deserialise_return_buffer(
+ &rpos, &rremain,
+ $argname);
if (!ok) {
goto fail;
}
@@ -870,7 +946,9 @@
print $fh <<EOF;
- ok = psasim_deserialise_${argtype}(&rpos, &rremain, $argname);
+ ok = psasim_deserialise_${argtype}(
+ &rpos, &rremain,
+ $argname);
if (!ok) {
goto fail;
}
@@ -880,10 +958,16 @@
print $fh <<EOF;
fail:
- free(params);
- free(result);
+ free(ser_params);
+ free(ser_result);
+EOF
+
+ print $fh <<EOF if $ret_type ne "void";
return $ret_name;
+EOF
+
+ print $fh <<EOF;
}
EOF
}
@@ -906,10 +990,15 @@
{
my ($fh, $f, $name, $is_server) = @_;
+ my $ret_type = $f->{return}->{type};
my $ret_name = $f->{return}->{name};
my $args = $f->{args};
- print $fh "\n $ret_name = $name(\n";
+ if ($ret_type 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
@@ -921,6 +1010,9 @@
if ($argtype =~ /^(const )?buffer$/) {
my ($n1, $n2) = split(/,\s*/, $argname);
print $fh " $n1, $n2";
+ } elsif ($argtype =~ /^(const )?psa_key_production_parameters_t$/) {
+ my ($n1, $n2) = split(/,\s*/, $argname);
+ print $fh " $n1, $n2";
} else {
$argname =~ s/^\*/\&/; # Replace leading * with &
if ($is_server && $argtype =~ /^psa_\w+_operation_t/) {
@@ -944,7 +1036,7 @@
print $fh "\n$ret_type $name(\n";
- print $fh " void\n)\n" if $#$args < 0; # No arguments
+ print $fh " void\n )\n" if $#$args < 0; # No arguments
for my $i (0 .. $#$args) {
my $arg = $args->[$i];
@@ -956,6 +1048,10 @@
my $const = length($1) ? "const " : "";
my ($n1, $n2) = split(/,/, $argname);
print $fh " ${const}uint8_t *$n1, size_t $n2";
+ } elsif ($argtype =~ /^(const )?psa_key_production_parameters_t$/) {
+ my $const = length($1) ? "const " : "";
+ my ($n1, $n2) = split(/,/, $argname);
+ print $fh " ${const}psa_key_production_parameters_t *$n1, size_t $n2";
} else {
print $fh " $ctypename$argname";
}
@@ -984,7 +1080,7 @@
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];
@@ -1003,9 +1099,13 @@
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";
@@ -1037,10 +1137,28 @@
#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;
$name .= ", " . $nname;
+ } elsif ($arg =~ /^((const)\s+)?psa_key_production_parameters_t\s*\*\s*(\w+)$/) {
+ $type = "psa_key_production_parameters_t";
+ $is_output = (length($1) == 0) ? 1 : 0;
+ $type = "const psa_key_production_parameters_t" if !$is_output;
+ $ctype = "";
+ $name = $3;
+ #print("$arg: $name: might be a psa_key_production_parameters_t?\n");
+ die("$arg: not a psa_key_production_parameters_t 1!\n") if $i == $#args;
+ my $next = $args[$i + 1];
+ die("$arg: $func: $name: $next: not a psa_key_production_parameters_t 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 . " ";
@@ -2371,3 +2489,3068 @@
* 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);
diff --git a/tests/psa-client-server/psasim/src/psa_sim_serialise.c b/tests/psa-client-server/psasim/src/psa_sim_serialise.c
index 651e046..e655e07 100644
--- a/tests/psa-client-server/psasim/src/psa_sim_serialise.c
+++ b/tests/psa-client-server/psasim/src/psa_sim_serialise.c
@@ -63,8 +63,10 @@
#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 @@
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,6 +143,206 @@
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 */
+}
+
+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 */
+}
+
+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 */
+}
+
+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
@@ -213,7 +417,8 @@
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);
}
@@ -248,7 +453,8 @@
return 1;
}
-size_t psasim_serialise_int_needs(int value)
+size_t psasim_serialise_int_needs(
+ int value)
{
return sizeof(value);
}
@@ -283,7 +489,8 @@
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);
}
@@ -318,6 +525,114 @@
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_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);
+}
+
+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;
@@ -420,7 +735,102 @@
return 1;
}
-size_t psasim_serialise_psa_status_t_needs(psa_status_t value)
+#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);
}
@@ -439,7 +849,8 @@
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);
}
@@ -458,7 +869,28 @@
return psasim_deserialise_unsigned_int(pos, remaining, value);
}
-size_t psasim_serialise_psa_hash_operation_t_needs(psa_hash_operation_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);
+}
+
+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);
}
@@ -493,7 +925,8 @@
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;
@@ -551,7 +984,8 @@
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);
}
@@ -586,7 +1020,8 @@
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;
@@ -644,7 +1079,8 @@
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);
}
@@ -679,7 +1115,483 @@
return 1;
}
-size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value)
+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_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_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_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);
}
@@ -716,8 +1628,32 @@
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(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/tests/psa-client-server/psasim/src/psa_sim_serialise.h b/tests/psa-client-server/psasim/src/psa_sim_serialise.h
index 537730c..f85faad 100644
--- a/tests/psa-client-server/psasim/src/psa_sim_serialise.h
+++ b/tests/psa-client-server/psasim/src/psa_sim_serialise.h
@@ -107,7 +107,8 @@
* \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 @@
* \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 @@
* \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.
*
@@ -222,6 +225,135 @@
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_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`.
+ *
+ * \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 +421,56 @@
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`.
*
@@ -300,7 +482,8 @@
* \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.
*
@@ -342,7 +525,8 @@
* \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.
*
@@ -373,6 +557,49 @@
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`.
*
@@ -384,7 +611,8 @@
* \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.
*
@@ -426,7 +654,8 @@
* \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.
*
@@ -468,7 +697,8 @@
* \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.
*
@@ -510,7 +740,8 @@
* \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.
*
@@ -552,7 +783,8 @@
* \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.
*
@@ -583,6 +815,436 @@
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_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_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_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`.
*
@@ -594,7 +1256,8 @@
* \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/tests/psa-client-server/psasim/src/psa_sim_serialise.pl b/tests/psa-client-server/psasim/src/psa_sim_serialise.pl
index e89fafe..81808ca 100755
--- a/tests/psa-client-server/psasim/src/psa_sim_serialise.pl
+++ b/tests/psa-client-server/psasim/src/psa_sim_serialise.pl
@@ -36,11 +36,18 @@
# are).
#
my @types = qw(unsigned-int int size_t
+ uint16_t uint32_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
+ psa_sign_hash_interruptible_operation_t
+ psa_verify_hash_interruptible_operation_t
mbedtls_svc_key_id_t);
grep(s/-/ /g, @types);
@@ -49,6 +56,7 @@
my %isa = (
"psa_status_t" => "int",
"psa_algorithm_t" => "unsigned int",
+ "psa_key_derivation_step_t" => "uint16_t",
);
if ($which eq "h") {
@@ -58,6 +66,8 @@
for my $type (@types) {
if ($type eq "buffer") {
print declare_buffer_functions();
+ } elsif ($type eq "psa_key_production_parameters_t") {
+ print declare_psa_key_production_parameters_t_functions();
} else {
print declare_needs($type, "");
print declare_serialise($type, "");
@@ -88,6 +98,8 @@
for my $type (@types) {
if ($type eq "buffer") {
print define_buffer_functions();
+ } elsif ($type eq "psa_key_production_parameters_t") {
+ print define_psa_key_production_parameters_t_functions();
} elsif (exists($isa{$type})) {
print define_needs_isa($type, $isa{$type});
print define_serialise_isa($type, $isa{$type});
@@ -133,7 +145,8 @@
* \\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
}
@@ -271,6 +284,62 @@
EOF
}
+sub declare_psa_key_production_parameters_t_functions
+{
+ return <<'EOF';
+
+/** 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);
+EOF
+}
+
sub h_header
{
return <<'EOF';
@@ -383,7 +452,8 @@
return <<EOF;
-size_t psasim_serialise_${type_d}_needs($type value)
+size_t psasim_serialise_${type_d}_needs(
+ $type value)
{
return sizeof(value);
}
@@ -399,7 +469,8 @@
return <<EOF;
-size_t psasim_server_serialise_${type_d}_needs($type *operation)
+size_t psasim_server_serialise_${type_d}_needs(
+ $type *operation)
{
(void) operation;
@@ -421,7 +492,8 @@
return <<EOF;
-size_t psasim_serialise_${type_d}_needs($type value)
+size_t psasim_serialise_${type_d}_needs(
+ $type value)
{
return psasim_serialise_${isa_d}_needs(value);
}
@@ -716,6 +788,106 @@
EOF
}
+sub define_psa_key_production_parameters_t_functions
+{
+ return <<'EOF';
+
+#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;
+}
+EOF
+}
+
sub c_header
{
return <<'EOF';
@@ -800,8 +972,10 @@
return <<EOF;
-static psa_${type}_operation_t ${type}_operations[MAX_LIVE_HANDLES_PER_CLASS];
-static psasim_client_handle_t ${type}_operation_handles[MAX_LIVE_HANDLES_PER_CLASS];
+static psa_${type}_operation_t ${type}_operations[
+ MAX_LIVE_HANDLES_PER_CLASS];
+static psasim_client_handle_t ${type}_operation_handles[
+ MAX_LIVE_HANDLES_PER_CLASS];
static psasim_client_handle_t next_${type}_operation_handle = 1;
/* Get a free slot */
@@ -937,8 +1111,10 @@
my $what = $1; # e.g. "hash_operation"
$code .= <<EOF;
- memset(${what}_handles, 0, sizeof(${what}_handles));
- memset(${what}s, 0, sizeof(${what}s));
+ memset(${what}_handles, 0,
+ sizeof(${what}_handles));
+ memset(${what}s, 0,
+ sizeof(${what}s));
EOF
}
diff --git a/tests/psa-client-server/psasim/test/run_test.sh b/tests/psa-client-server/psasim/test/run_test.sh
index 45a317a..7c1011e 100755
--- a/tests/psa-client-server/psasim/test/run_test.sh
+++ b/tests/psa-client-server/psasim/test/run_test.sh
@@ -13,6 +13,9 @@
cd "$(dirname "$0")"
+CLIENT_BIN=$1
+shift
+
function clean_run() {
rm -f psa_notify_*
pkill psa_partition || true
@@ -30,8 +33,9 @@
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
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 93054e5..3bff3a8 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -6044,47 +6044,16 @@
msg "build library for client"
helper_crypto_client_build client
- msg "build psasim to test psa_client"
- rm -f tests/psa-client-server/psasim/test/psa_client # In case left behind
- make -C tests/psa-client-server/psasim CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" test/psa_client
+ msg "build basic psasim client"
+ make -C tests/psa-client-server/psasim CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" test/psa_client_base
+ msg "test basic psasim client"
+ tests/psa-client-server/psasim/test/run_test.sh psa_client_base
- msg "test psasim"
- tests/psa-client-server/psasim/test/run_test.sh
+ msg "build full psasim client"
+ make -C tests/psa-client-server/psasim CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" test/psa_client_full
+ msg "test full psasim client"
+ tests/psa-client-server/psasim/test/run_test.sh psa_client_full
-
- msg "build psasim to test psa_hash_compute"
- # Delete the executable to ensure we build using the right MAIN
- rm tests/psa-client-server/psasim/test/psa_client
- # API under test: psa_hash_compute()
- make -C tests/psa-client-server/psasim CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" MAIN="src/aut_psa_hash_compute.c" test/psa_client
-
- msg "test psasim running psa_hash_compute"
- tests/psa-client-server/psasim/test/run_test.sh
-
-
- # Next APIs under test: psa_hash_*(). Use our copy of the PSA hash example.
- msg "build psasim to test all psa_hash_* APIs"
- # Delete the executable to ensure we build using the right MAIN
- rm tests/psa-client-server/psasim/test/psa_client
- make -C tests/psa-client-server/psasim CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" MAIN="src/aut_psa_hash.c" test/psa_client
-
- msg "test psasim running psa_hash sample"
- tests/psa-client-server/psasim/test/run_test.sh
-
-
- # Next APIs under test: psa_aead_*(). Use our copy of the PSA aead example.
- msg "build psasim to test all psa_aead_* APIs"
- # Delete the executable to ensure we build using the right MAIN
- rm tests/psa-client-server/psasim/test/psa_client
- make -C tests/psa-client-server/psasim CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" MAIN="src/aut_psa_aead_demo.c" test/psa_client
-
- msg "test psasim running psa_aead_demo sample"
- tests/psa-client-server/psasim/test/run_test.sh aes128-gcm
- tests/psa-client-server/psasim/test/run_test.sh aes256-gcm
- tests/psa-client-server/psasim/test/run_test.sh aes128-gcm_8
- tests/psa-client-server/psasim/test/run_test.sh chachapoly
-
- msg "clean psasim"
make -C tests/psa-client-server/psasim clean
}