Merge pull request #9310 from valeriosetti/psasim_more_aut_tests

psasim: complete support of PSA functions in `psasim` and add basic "smoke test" applications
This commit is contained in:
Tom Cosgrove 2024-06-26 11:46:25 +00:00 committed by GitHub
commit c4dfc08464
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 17057 additions and 805 deletions

View File

@ -1,5 +1,3 @@
MAIN ?= src/client.c
CFLAGS += -Wall -Werror -std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L
ifeq ($(DEBUG),1)
@ -16,11 +14,15 @@ GENERATED_H_FILES = include/psa_manifest/manifest.h \
include/psa_manifest/pid.h \
include/psa_manifest/sid.h
PSA_CLIENT_SRC = src/psa_ff_client.c \
$(MAIN) \
PSA_CLIENT_COMMON_SRC = src/psa_ff_client.c \
src/psa_sim_crypto_client.c \
src/psa_sim_serialise.c
PSA_CLIENT_BASE_SRC = $(PSA_CLIENT_COMMON_SRC) src/client.c
PSA_CLIENT_FULL_SRC = $(PSA_CLIENT_COMMON_SRC) \
$(wildcard src/aut_*.c)
PARTITION_SERVER_BOOTSTRAP = src/psa_ff_bootstrap_TEST_PARTITION.c
PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \
@ -35,8 +37,11 @@ all:
test/seedfile:
dd if=/dev/urandom of=./test/seedfile bs=64 count=1
test/psa_client: $(PSA_CLIENT_SRC) $(GENERATED_H_FILES)
$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@
test/psa_client_base: $(PSA_CLIENT_BASE_SRC) $(GENERATED_H_FILES)
$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_BASE_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@
test/psa_client_full: $(PSA_CLIENT_FULL_SRC) $(GENERATED_H_FILES)
$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_CLIENT_FULL_SRC) $(LIBPSACLIENT) $(LDFLAGS) -o $@
test/psa_partition: $(PSA_SERVER_SRC) $(GENERATED_H_FILES) test/seedfile
$(CC) $(COMMON_INCLUDE) $(CFLAGS) $(PSA_SERVER_SRC) $(LIBPSASERVER) $(LDFLAGS) -o $@
@ -56,7 +61,7 @@ libpsaclient libpsaserver:
$(MAKE) -C $(MBEDTLS_ROOT_PATH) clean
clean:
rm -f test/psa_client test/psa_partition
rm -f test/psa_client_base test/psa_client_full test/psa_partition
rm -f $(PARTITION_SERVER_BOOTSTRAP)
rm -rf libpsaclient libpsaserver
rm -rf include/psa_manifest

View File

@ -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;
}

View File

@ -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 @@ exit:
/*
* 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 @@ int main(int argc, char **argv)
exit:
return status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
}
#endif

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,13 +1,4 @@
/*
* Example computing a SHA-256 hash using the PSA Crypto API
*
* The example computes the SHA-256 hash of a test string using the
* one-shot API call psa_hash_compute() and the using multi-part
* operation, which requires psa_hash_setup(), psa_hash_update() and
* psa_hash_finish(). The multi-part operation is popular on embedded
* devices where a rolling hash needs to be computed.
*
*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
@ -20,33 +11,13 @@
#include "mbedtls/build_info.h"
#include "mbedtls/platform.h"
/* Information about hashing with the PSA API can be
* found here:
* https://arm-software.github.io/psa-api/crypto/1.1/api/ops/hashes.html
*
* The algorithm used by this demo is SHA 256.
* Please see include/psa/crypto_values.h to see the other
* algorithms that are supported by Mbed TLS.
* If you switch to a different algorithm you will need to update
* the hash data in the EXAMPLE_HASH_VALUE macro below. */
#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
(!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256))
int main(void)
{
mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256"
"not defined, and not MBEDTLS_PSA_CRYPTO_CLIENT.\r\n");
return EXIT_SUCCESS;
}
#else
#define HASH_ALG PSA_ALG_SHA_256
const uint8_t sample_message[] = "Hello World!";
static const uint8_t sample_message[] = "Hello World!";
/* sample_message is terminated with a null byte which is not part of
* the message itself so we make sure to subtract it in order to get
* the message length. */
const size_t sample_message_length = sizeof(sample_message) - 1;
static const size_t sample_message_length = sizeof(sample_message) - 1;
#define EXPECTED_HASH_VALUE { \
0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \
@ -54,10 +25,10 @@ const size_t sample_message_length = sizeof(sample_message) - 1;
0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \
}
const uint8_t expected_hash[] = EXPECTED_HASH_VALUE;
const size_t expected_hash_len = sizeof(expected_hash);
static const uint8_t expected_hash[] = EXPECTED_HASH_VALUE;
static const size_t expected_hash_len = sizeof(expected_hash);
int main(void)
int psa_hash_main(void)
{
psa_status_t status;
uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)];
@ -157,4 +128,3 @@ cleanup:
psa_hash_abort(&cloned_hash_operation);
return EXIT_FAILURE;
}
#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */

View File

@ -1,15 +1,4 @@
/*
* API(s) under test: psa_hash_compute()
*
* Taken from programs/psa/psa_hash.c, and calls to all hash APIs
* but psa_hash_compute() removed.
*
* Example computing a SHA-256 hash using the PSA Crypto API
*
* The example computes the SHA-256 hash of a test string using the
* one-shot API call psa_hash_compute().
*
*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
@ -22,33 +11,13 @@
#include "mbedtls/build_info.h"
#include "mbedtls/platform.h"
/* Information about hashing with the PSA API can be
* found here:
* https://arm-software.github.io/psa-api/crypto/1.1/api/ops/hashes.html
*
* The algorithm used by this demo is SHA 256.
* Please see include/psa/crypto_values.h to see the other
* algorithms that are supported by Mbed TLS.
* If you switch to a different algorithm you will need to update
* the hash data in the EXAMPLE_HASH_VALUE macro below. */
#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
(!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256))
int main(void)
{
mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256"
"not defined, and not MBEDTLS_PSA_CRYPTO_CLIENT.\r\n");
return EXIT_SUCCESS;
}
#else
#define HASH_ALG PSA_ALG_SHA_256
const uint8_t sample_message[] = "Hello World!";
static const uint8_t sample_message[] = "Hello World!";
/* sample_message is terminated with a null byte which is not part of
* the message itself so we make sure to subtract it in order to get
* the message length. */
const size_t sample_message_length = sizeof(sample_message) - 1;
static const size_t sample_message_length = sizeof(sample_message) - 1;
#define EXPECTED_HASH_VALUE { \
0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \
@ -56,10 +25,10 @@ const size_t sample_message_length = sizeof(sample_message) - 1;
0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \
}
const uint8_t expected_hash[] = EXPECTED_HASH_VALUE;
const size_t expected_hash_len = sizeof(expected_hash);
static const uint8_t expected_hash[] = EXPECTED_HASH_VALUE;
static const size_t expected_hash_len = sizeof(expected_hash);
int main(void)
int psa_hash_compute_main(void)
{
psa_status_t status;
uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)];
@ -110,4 +79,3 @@ int main(void)
cleanup:
return EXIT_FAILURE;
}
#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -24,7 +24,24 @@ enum {
PSA_AEAD_UPDATE,
PSA_AEAD_UPDATE_AD,
PSA_AEAD_VERIFY,
PSA_ASYMMETRIC_DECRYPT,
PSA_ASYMMETRIC_ENCRYPT,
PSA_CIPHER_ABORT,
PSA_CIPHER_DECRYPT,
PSA_CIPHER_DECRYPT_SETUP,
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 @@ enum {
PSA_HASH_UPDATE,
PSA_HASH_VERIFY,
PSA_IMPORT_KEY,
PSA_INTERRUPTIBLE_GET_MAX_OPS,
PSA_INTERRUPTIBLE_SET_MAX_OPS,
PSA_KEY_DERIVATION_ABORT,
PSA_KEY_DERIVATION_GET_CAPACITY,
PSA_KEY_DERIVATION_INPUT_BYTES,
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_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -107,7 +107,8 @@ int psasim_deserialise_begin(uint8_t **pos, size_t *remaining);
* \c psasim_serialise_unsigned_int() to serialise
* the given value.
*/
size_t psasim_serialise_unsigned_int_needs(unsigned int value);
size_t psasim_serialise_unsigned_int_needs(
unsigned int value);
/** Serialise an `unsigned int` into a buffer.
*
@ -149,7 +150,8 @@ int psasim_deserialise_unsigned_int(uint8_t **pos,
* \c psasim_serialise_int() to serialise
* the given value.
*/
size_t psasim_serialise_int_needs(int value);
size_t psasim_serialise_int_needs(
int value);
/** Serialise an `int` into a buffer.
*
@ -191,7 +193,8 @@ int psasim_deserialise_int(uint8_t **pos,
* \c psasim_serialise_size_t() to serialise
* the given value.
*/
size_t psasim_serialise_size_t_needs(size_t value);
size_t psasim_serialise_size_t_needs(
size_t value);
/** Serialise a `size_t` into a buffer.
*
@ -222,6 +225,135 @@ int psasim_deserialise_size_t(uint8_t **pos,
size_t *remaining,
size_t *value);
/** Return how much buffer space is needed by \c psasim_serialise_uint16_t()
* to serialise an `uint16_t`.
*
* \param value The value that will be serialised into the buffer
* (needed in case some serialisations are value-
* dependent).
*
* \return The number of bytes needed in the buffer by
* \c psasim_serialise_uint16_t() to serialise
* the given value.
*/
size_t psasim_serialise_uint16_t_needs(
uint16_t value);
/** Serialise an `uint16_t` into a buffer.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param value The value to serialise into the buffer.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_serialise_uint16_t(uint8_t **pos,
size_t *remaining,
uint16_t value);
/** Deserialise an `uint16_t` from a buffer.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param value Pointer to an `uint16_t` to receive the value
* deserialised from the buffer.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_deserialise_uint16_t(uint8_t **pos,
size_t *remaining,
uint16_t *value);
/** Return how much buffer space is needed by \c psasim_serialise_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_buffer(uint8_t **pos, size_t *remaining,
int psasim_deserialise_return_buffer(uint8_t **pos, size_t *remaining,
uint8_t *buffer, size_t buffer_length);
/** Return how much space is needed by \c psasim_serialise_psa_key_production_parameters_t()
* to serialise a psa_key_production_parameters_t (a structure with a flexible array member).
*
* \param params Pointer to the struct to be serialised
* (needed in case some serialisations are value-
* dependent).
* \param data_length Number of bytes in the data[] of the struct to be serialised.
*
* \return The number of bytes needed in the serialisation buffer by
* \c psasim_serialise_psa_key_production_parameters_t() to serialise
* the specified structure.
*/
size_t psasim_serialise_psa_key_production_parameters_t_needs(
const psa_key_production_parameters_t *params,
size_t buffer_size);
/** Serialise a psa_key_production_parameters_t.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param params Pointer to the structure to be serialised.
* \param data_length Number of bytes in the data[] of the struct to be serialised.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos,
size_t *remaining,
const psa_key_production_parameters_t *params,
size_t data_length);
/** Deserialise a psa_key_production_parameters_t.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the serialisation buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the serialisation buffer.
* \param params Pointer to a `psa_key_production_parameters_t *` to
* receive the address of a newly-allocated structure,
* which the caller must `free()`.
* \param data_length Pointer to a `size_t` to receive the number of
* bytes in the data[] member of the structure deserialised.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, size_t *remaining,
psa_key_production_parameters_t **params,
size_t *buffer_length);
/** Return how much buffer space is needed by \c psasim_serialise_psa_status_t()
* to serialise a `psa_status_t`.
*
@ -300,7 +482,8 @@ int psasim_deserialise_return_buffer(uint8_t **pos, size_t *remaining,
* \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 @@ int psasim_deserialise_psa_status_t(uint8_t **pos,
* \c psasim_serialise_psa_algorithm_t() to serialise
* the given value.
*/
size_t psasim_serialise_psa_algorithm_t_needs(psa_algorithm_t value);
size_t psasim_serialise_psa_algorithm_t_needs(
psa_algorithm_t value);
/** Serialise a `psa_algorithm_t` into a buffer.
*
@ -373,6 +557,49 @@ int psasim_deserialise_psa_algorithm_t(uint8_t **pos,
size_t *remaining,
psa_algorithm_t *value);
/** Return how much buffer space is needed by \c psasim_serialise_psa_key_derivation_step_t()
* to serialise a `psa_key_derivation_step_t`.
*
* \param value The value that will be serialised into the buffer
* (needed in case some serialisations are value-
* dependent).
*
* \return The number of bytes needed in the buffer by
* \c psasim_serialise_psa_key_derivation_step_t() to serialise
* the given value.
*/
size_t psasim_serialise_psa_key_derivation_step_t_needs(
psa_key_derivation_step_t value);
/** Serialise a `psa_key_derivation_step_t` into a buffer.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param value The value to serialise into the buffer.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_serialise_psa_key_derivation_step_t(uint8_t **pos,
size_t *remaining,
psa_key_derivation_step_t value);
/** Deserialise a `psa_key_derivation_step_t` from a buffer.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param value Pointer to a `psa_key_derivation_step_t` to receive the value
* deserialised from the buffer.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_deserialise_psa_key_derivation_step_t(uint8_t **pos,
size_t *remaining,
psa_key_derivation_step_t *value);
/** Return how much buffer space is needed by \c psasim_serialise_psa_hash_operation_t()
* to serialise a `psa_hash_operation_t`.
*
@ -384,7 +611,8 @@ int psasim_deserialise_psa_algorithm_t(uint8_t **pos,
* \c psasim_serialise_psa_hash_operation_t() to serialise
* the given value.
*/
size_t psasim_serialise_psa_hash_operation_t_needs(psa_hash_operation_t value);
size_t psasim_serialise_psa_hash_operation_t_needs(
psa_hash_operation_t value);
/** Serialise a `psa_hash_operation_t` into a buffer.
*
@ -426,7 +654,8 @@ int psasim_deserialise_psa_hash_operation_t(uint8_t **pos,
* \c psasim_serialise_psa_hash_operation_t() to serialise
* the given value.
*/
size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *value);
size_t psasim_server_serialise_psa_hash_operation_t_needs(
psa_hash_operation_t *value);
/** Serialise a `psa_hash_operation_t` into a buffer on the server side.
*
@ -468,7 +697,8 @@ int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos,
* \c psasim_serialise_psa_aead_operation_t() to serialise
* the given value.
*/
size_t psasim_serialise_psa_aead_operation_t_needs(psa_aead_operation_t value);
size_t psasim_serialise_psa_aead_operation_t_needs(
psa_aead_operation_t value);
/** Serialise a `psa_aead_operation_t` into a buffer.
*
@ -510,7 +740,8 @@ int psasim_deserialise_psa_aead_operation_t(uint8_t **pos,
* \c psasim_serialise_psa_aead_operation_t() to serialise
* the given value.
*/
size_t psasim_server_serialise_psa_aead_operation_t_needs(psa_aead_operation_t *value);
size_t psasim_server_serialise_psa_aead_operation_t_needs(
psa_aead_operation_t *value);
/** Serialise a `psa_aead_operation_t` into a buffer on the server side.
*
@ -552,7 +783,8 @@ int psasim_server_deserialise_psa_aead_operation_t(uint8_t **pos,
* \c psasim_serialise_psa_key_attributes_t() to serialise
* the given value.
*/
size_t psasim_serialise_psa_key_attributes_t_needs(psa_key_attributes_t value);
size_t psasim_serialise_psa_key_attributes_t_needs(
psa_key_attributes_t value);
/** Serialise a `psa_key_attributes_t` into a buffer.
*
@ -583,6 +815,436 @@ int psasim_deserialise_psa_key_attributes_t(uint8_t **pos,
size_t *remaining,
psa_key_attributes_t *value);
/** Return how much buffer space is needed by \c psasim_serialise_psa_mac_operation_t()
* to serialise a `psa_mac_operation_t`.
*
* \param value The value that will be serialised into the buffer
* (needed in case some serialisations are value-
* dependent).
*
* \return The number of bytes needed in the buffer by
* \c psasim_serialise_psa_mac_operation_t() to serialise
* the given value.
*/
size_t psasim_serialise_psa_mac_operation_t_needs(
psa_mac_operation_t value);
/** Serialise a `psa_mac_operation_t` into a buffer.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param value The value to serialise into the buffer.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_serialise_psa_mac_operation_t(uint8_t **pos,
size_t *remaining,
psa_mac_operation_t value);
/** Deserialise a `psa_mac_operation_t` from a buffer.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param value Pointer to a `psa_mac_operation_t` to receive the value
* deserialised from the buffer.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_deserialise_psa_mac_operation_t(uint8_t **pos,
size_t *remaining,
psa_mac_operation_t *value);
/** Return how much buffer space is needed by \c psasim_server_serialise_psa_mac_operation_t()
* to serialise a `psa_mac_operation_t`.
*
* \param value The value that will be serialised into the buffer
* (needed in case some serialisations are value-
* dependent).
*
* \return The number of bytes needed in the buffer by
* \c psasim_serialise_psa_mac_operation_t() to serialise
* the given value.
*/
size_t psasim_server_serialise_psa_mac_operation_t_needs(
psa_mac_operation_t *value);
/** Serialise a `psa_mac_operation_t` into a buffer on the server side.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param value The value to serialise into the buffer.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_server_serialise_psa_mac_operation_t(uint8_t **pos,
size_t *remaining,
psa_mac_operation_t *value);
/** Deserialise a `psa_mac_operation_t` from a buffer on the server side.
*
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
* in the buffer.
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
* remaining in the buffer.
* \param value Pointer to a `psa_mac_operation_t` to receive the value
* deserialised from the buffer.
*
* \return \c 1 on success ("okay"), \c 0 on error.
*/
int psasim_server_deserialise_psa_mac_operation_t(uint8_t **pos,
size_t *remaining,
psa_mac_operation_t **value);
/** Return how much buffer space is needed by \c psasim_serialise_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 @@ int psasim_deserialise_psa_key_attributes_t(uint8_t **pos,
* \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.
*

View File

@ -36,11 +36,18 @@ die($usage) unless $which eq "c" || $which eq "h";
# 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 @@ grep(s/-/ /g, @types);
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 @@ if ($which eq "h") {
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 @@ if ($which eq "h") {
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 @@ sub declare_needs
* \\c psasim_serialise_$type_d() to serialise
* the given value.
*/
size_t psasim_${server}serialise_${type_d}_needs($type ${ptr}value);
size_t psasim_${server}serialise_${type_d}_needs(
$type ${ptr}value);
EOF
}
@ -271,6 +284,62 @@ int psasim_deserialise_return_buffer(uint8_t **pos, size_t *remaining,
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 @@ sub define_needs
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 @@ sub define_server_needs
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 @@ sub define_needs_isa
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 @@ int psasim_deserialise_return_buffer(uint8_t **pos,
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 @@ sub define_operation_type_data_and_functions
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 @@ EOF
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
}

View File

@ -13,6 +13,9 @@ set -e
cd "$(dirname "$0")"
CLIENT_BIN=$1
shift
function clean_run() {
rm -f psa_notify_*
pkill psa_partition || true
@ -30,8 +33,9 @@ function wait_for_server_startup() {
clean_run
./psa_partition -k &
SERV_PID=$!
./psa_partition &
wait_for_server_startup
./psa_client "$@"
wait $SERV_PID
./$CLIENT_BIN "$@"
# Kill server once client exited
pkill psa_partition

View File

@ -6044,47 +6044,16 @@ component_test_psasim() {
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
}