mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-01-26 21:35:35 +00:00
Merge pull request #9238 from tom-cosgrove-arm/psasim_update_for_operation_types
Update PSA simulator C code to do operations by handles
This commit is contained in:
commit
7c52100fbd
@ -12,9 +12,6 @@ LIBPSASERVER := -Llibpsaserver/ -lmbedcrypto
|
||||
MBEDTLS_ROOT_PATH = ../../..
|
||||
COMMON_INCLUDE := -I./include -I$(MBEDTLS_ROOT_PATH)/include
|
||||
|
||||
TEST_BIN = test/psa_client \
|
||||
test/psa_partition
|
||||
|
||||
GENERATED_H_FILES = include/psa_manifest/manifest.h \
|
||||
include/psa_manifest/pid.h \
|
||||
include/psa_manifest/sid.h
|
||||
@ -33,7 +30,7 @@ PSA_SERVER_SRC = $(PARTITION_SERVER_BOOTSTRAP) \
|
||||
|
||||
.PHONY: all clean libpsaclient libpsaserver
|
||||
|
||||
all: $(TEST_BIN)
|
||||
all:
|
||||
|
||||
test/seedfile:
|
||||
dd if=/dev/urandom of=./test/seedfile bs=64 count=1
|
||||
@ -59,7 +56,7 @@ libpsaclient libpsaserver:
|
||||
$(MAKE) -C $(MBEDTLS_ROOT_PATH) clean
|
||||
|
||||
clean:
|
||||
rm -f $(TEST_BIN)
|
||||
rm -f test/psa_client test/psa_partition
|
||||
rm -f $(PARTITION_SERVER_BOOTSTRAP)
|
||||
rm -rf libpsaclient libpsaserver
|
||||
rm -rf include/psa_manifest
|
||||
|
283
tests/psa-client-server/psasim/src/aut_psa_aead_demo.c
Normal file
283
tests/psa-client-server/psasim/src/aut_psa_aead_demo.c
Normal file
@ -0,0 +1,283 @@
|
||||
/**
|
||||
* PSA API multi-part AEAD demonstration.
|
||||
*
|
||||
* This program AEAD-encrypts a message, using the algorithm and key size
|
||||
* specified on the command line, using the multi-part API.
|
||||
*
|
||||
* It comes with a companion program cipher/cipher_aead_demo.c, which does the
|
||||
* same operations with the legacy Cipher API. The goal is that comparing the
|
||||
* two programs will help people migrating to the PSA Crypto API.
|
||||
*
|
||||
* When used with multi-part AEAD operations, the `mbedtls_cipher_context`
|
||||
* serves a triple purpose (1) hold the key, (2) store the algorithm when no
|
||||
* operation is active, and (3) save progress information for the current
|
||||
* operation. With PSA those roles are held by disinct objects: (1) a
|
||||
* psa_key_id_t to hold the key, a (2) psa_algorithm_t to represent the
|
||||
* algorithm, and (3) a psa_operation_t for multi-part progress.
|
||||
*
|
||||
* On the other hand, with PSA, the algorithms encodes the desired tag length;
|
||||
* with Cipher the desired tag length needs to be tracked separately.
|
||||
*
|
||||
* This program and its companion cipher/cipher_aead_demo.c illustrate this by
|
||||
* doing the same sequence of multi-part AEAD computation with both APIs;
|
||||
* looking at the two side by side should make the differences and
|
||||
* similarities clear.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/* First include Mbed TLS headers to get the Mbed TLS configuration and
|
||||
* platform definitions that we'll use in this program. Also include
|
||||
* standard C headers for functions we'll use here. */
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#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]";
|
||||
|
||||
/* Dummy data for encryption: IV/nonce, additional data, 2-part message */
|
||||
const unsigned char iv1[12] = { 0x00 };
|
||||
const unsigned char add_data1[] = { 0x01, 0x02 };
|
||||
const unsigned char msg1_part1[] = { 0x03, 0x04 };
|
||||
const unsigned char msg1_part2[] = { 0x05, 0x06, 0x07 };
|
||||
|
||||
/* Dummy data (2nd message) */
|
||||
const unsigned char iv2[12] = { 0x10 };
|
||||
const unsigned char add_data2[] = { 0x11, 0x12 };
|
||||
const unsigned char msg2_part1[] = { 0x13, 0x14 };
|
||||
const unsigned char msg2_part2[] = { 0x15, 0x16, 0x17 };
|
||||
|
||||
/* Maximum total size of the messages */
|
||||
#define MSG1_SIZE (sizeof(msg1_part1) + sizeof(msg1_part2))
|
||||
#define MSG2_SIZE (sizeof(msg2_part1) + sizeof(msg2_part2))
|
||||
#define MSG_MAX_SIZE (MSG1_SIZE > MSG2_SIZE ? MSG1_SIZE : MSG2_SIZE)
|
||||
|
||||
/* Dummy key material - never do this in production!
|
||||
* 32-byte is enough to all the key size supported by this program. */
|
||||
const unsigned char key_bytes[32] = { 0x2a };
|
||||
|
||||
/* Print the contents of a buffer in hex */
|
||||
void print_buf(const char *title, uint8_t *buf, size_t len)
|
||||
{
|
||||
printf("%s:", title);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
printf(" %02x", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Run a PSA function and bail out if it fails.
|
||||
* The symbolic name of the error code can be recovered using:
|
||||
* programs/psa/psa_constant_name status <value> */
|
||||
#define PSA_CHECK(expr) \
|
||||
do \
|
||||
{ \
|
||||
status = (expr); \
|
||||
if (status != PSA_SUCCESS) \
|
||||
{ \
|
||||
printf("Error %d at line %d: %s\n", \
|
||||
(int) status, \
|
||||
__LINE__, \
|
||||
#expr); \
|
||||
goto exit; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/*
|
||||
* Prepare encryption material:
|
||||
* - interpret command-line argument
|
||||
* - set up key
|
||||
* - outputs: key and algorithm, which together hold all the information
|
||||
*/
|
||||
static psa_status_t aead_prepare(const char *info,
|
||||
psa_key_id_t *key,
|
||||
psa_algorithm_t *alg)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
/* Convert arg to alg + key_bits + key_type */
|
||||
size_t key_bits;
|
||||
psa_key_type_t key_type;
|
||||
if (strcmp(info, "aes128-gcm") == 0) {
|
||||
*alg = PSA_ALG_GCM;
|
||||
key_bits = 128;
|
||||
key_type = PSA_KEY_TYPE_AES;
|
||||
} else if (strcmp(info, "aes256-gcm") == 0) {
|
||||
*alg = PSA_ALG_GCM;
|
||||
key_bits = 256;
|
||||
key_type = PSA_KEY_TYPE_AES;
|
||||
} else if (strcmp(info, "aes128-gcm_8") == 0) {
|
||||
*alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 8);
|
||||
key_bits = 128;
|
||||
key_type = PSA_KEY_TYPE_AES;
|
||||
} else if (strcmp(info, "chachapoly") == 0) {
|
||||
*alg = PSA_ALG_CHACHA20_POLY1305;
|
||||
key_bits = 256;
|
||||
key_type = PSA_KEY_TYPE_CHACHA20;
|
||||
} else {
|
||||
puts(usage);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/* Prepare key attributes */
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
|
||||
psa_set_key_algorithm(&attributes, *alg);
|
||||
psa_set_key_type(&attributes, key_type);
|
||||
psa_set_key_bits(&attributes, key_bits); // optional
|
||||
|
||||
/* Import key */
|
||||
PSA_CHECK(psa_import_key(&attributes, key_bytes, key_bits / 8, key));
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out some information.
|
||||
*
|
||||
* All of this information was present in the command line argument, but his
|
||||
* function demonstrates how each piece can be recovered from (key, alg).
|
||||
*/
|
||||
static void aead_info(psa_key_id_t key, psa_algorithm_t alg)
|
||||
{
|
||||
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
(void) psa_get_key_attributes(key, &attr);
|
||||
psa_key_type_t key_type = psa_get_key_type(&attr);
|
||||
size_t key_bits = psa_get_key_bits(&attr);
|
||||
psa_algorithm_t base_alg = PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg);
|
||||
size_t tag_len = PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg);
|
||||
|
||||
const char *type_str = key_type == PSA_KEY_TYPE_AES ? "AES"
|
||||
: key_type == PSA_KEY_TYPE_CHACHA20 ? "Chacha"
|
||||
: "???";
|
||||
const char *base_str = base_alg == PSA_ALG_GCM ? "GCM"
|
||||
: base_alg == PSA_ALG_CHACHA20_POLY1305 ? "ChachaPoly"
|
||||
: "???";
|
||||
|
||||
printf("%s, %u, %s, %u\n",
|
||||
type_str, (unsigned) key_bits, base_str, (unsigned) tag_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypt a 2-part message.
|
||||
*/
|
||||
static int aead_encrypt(psa_key_id_t key, psa_algorithm_t alg,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *part1, size_t part1_len,
|
||||
const unsigned char *part2, size_t part2_len)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t olen, olen_tag;
|
||||
unsigned char out[PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(MSG_MAX_SIZE)];
|
||||
unsigned char *p = out, *end = out + sizeof(out);
|
||||
unsigned char tag[PSA_AEAD_TAG_MAX_SIZE];
|
||||
|
||||
psa_aead_operation_t op = PSA_AEAD_OPERATION_INIT;
|
||||
PSA_CHECK(psa_aead_encrypt_setup(&op, key, alg));
|
||||
|
||||
PSA_CHECK(psa_aead_set_nonce(&op, iv, iv_len));
|
||||
PSA_CHECK(psa_aead_update_ad(&op, ad, ad_len));
|
||||
PSA_CHECK(psa_aead_update(&op, part1, part1_len, p, end - p, &olen));
|
||||
p += olen;
|
||||
PSA_CHECK(psa_aead_update(&op, part2, part2_len, p, end - p, &olen));
|
||||
p += olen;
|
||||
PSA_CHECK(psa_aead_finish(&op, p, end - p, &olen,
|
||||
tag, sizeof(tag), &olen_tag));
|
||||
p += olen;
|
||||
memcpy(p, tag, olen_tag);
|
||||
p += olen_tag;
|
||||
|
||||
olen = p - out;
|
||||
print_buf("out", out, olen);
|
||||
|
||||
exit:
|
||||
psa_aead_abort(&op); // required on errors, harmless on success
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* AEAD demo: set up key/alg, print out info, encrypt messages.
|
||||
*/
|
||||
static psa_status_t aead_demo(const char *info)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
psa_key_id_t key;
|
||||
psa_algorithm_t alg;
|
||||
|
||||
PSA_CHECK(aead_prepare(info, &key, &alg));
|
||||
|
||||
aead_info(key, alg);
|
||||
|
||||
PSA_CHECK(aead_encrypt(key, alg,
|
||||
iv1, sizeof(iv1), add_data1, sizeof(add_data1),
|
||||
msg1_part1, sizeof(msg1_part1),
|
||||
msg1_part2, sizeof(msg1_part2)));
|
||||
PSA_CHECK(aead_encrypt(key, alg,
|
||||
iv2, sizeof(iv2), add_data2, sizeof(add_data2),
|
||||
msg2_part1, sizeof(msg2_part1),
|
||||
msg2_part2, sizeof(msg2_part2)));
|
||||
|
||||
exit:
|
||||
psa_destroy_key(key);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main function
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
|
||||
/* Check usage */
|
||||
if (argc != 2) {
|
||||
puts(usage);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Initialize the PSA crypto library. */
|
||||
PSA_CHECK(psa_crypto_init());
|
||||
|
||||
/* Run the demo */
|
||||
PSA_CHECK(aead_demo(argv[1]));
|
||||
|
||||
/* Deinitialize the PSA crypto library. */
|
||||
mbedtls_psa_crypto_free();
|
||||
|
||||
exit:
|
||||
return status == PSA_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
#endif
|
160
tests/psa-client-server/psasim/src/aut_psa_hash.c
Normal file
160
tests/psa-client-server/psasim/src/aut_psa_hash.c
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Example computing a SHA-256 hash using the PSA Crypto API
|
||||
*
|
||||
* The example computes the SHA-256 hash of a test string using the
|
||||
* one-shot API call psa_hash_compute() and the using multi-part
|
||||
* operation, which requires psa_hash_setup(), psa_hash_update() and
|
||||
* psa_hash_finish(). The multi-part operation is popular on embedded
|
||||
* devices where a rolling hash needs to be computed.
|
||||
*
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
/* Information about hashing with the PSA API can be
|
||||
* found here:
|
||||
* https://arm-software.github.io/psa-api/crypto/1.1/api/ops/hashes.html
|
||||
*
|
||||
* The algorithm used by this demo is SHA 256.
|
||||
* Please see include/psa/crypto_values.h to see the other
|
||||
* algorithms that are supported by Mbed TLS.
|
||||
* If you switch to a different algorithm you will need to update
|
||||
* the hash data in the EXAMPLE_HASH_VALUE macro below. */
|
||||
|
||||
#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
|
||||
(!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256))
|
||||
int main(void)
|
||||
{
|
||||
mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256"
|
||||
"not defined, and not MBEDTLS_PSA_CRYPTO_CLIENT.\r\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#else
|
||||
|
||||
#define HASH_ALG PSA_ALG_SHA_256
|
||||
|
||||
const uint8_t sample_message[] = "Hello World!";
|
||||
/* sample_message is terminated with a null byte which is not part of
|
||||
* the message itself so we make sure to subtract it in order to get
|
||||
* the message length. */
|
||||
const size_t sample_message_length = sizeof(sample_message) - 1;
|
||||
|
||||
#define EXPECTED_HASH_VALUE { \
|
||||
0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, \
|
||||
0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, \
|
||||
0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 \
|
||||
}
|
||||
|
||||
const uint8_t expected_hash[] = EXPECTED_HASH_VALUE;
|
||||
const size_t expected_hash_len = sizeof(expected_hash);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
uint8_t hash[PSA_HASH_LENGTH(HASH_ALG)];
|
||||
size_t hash_length;
|
||||
psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
|
||||
psa_hash_operation_t cloned_hash_operation = PSA_HASH_OPERATION_INIT;
|
||||
|
||||
mbedtls_printf("PSA Crypto API: SHA-256 example\n\n");
|
||||
|
||||
status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_crypto_init failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Compute hash using multi-part operation */
|
||||
status = psa_hash_setup(&hash_operation, HASH_ALG);
|
||||
if (status == PSA_ERROR_NOT_SUPPORTED) {
|
||||
mbedtls_printf("unknown hash algorithm supplied\n");
|
||||
return EXIT_FAILURE;
|
||||
} else if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_setup failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hash_operation, sample_message, sample_message_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_update failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_hash_clone(&hash_operation, &cloned_hash_operation);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("PSA hash clone failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_hash_finish(&hash_operation, hash, sizeof(hash), &hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_finish failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Check the result of the operation against the sample */
|
||||
if (hash_length != expected_hash_len ||
|
||||
(memcmp(hash, expected_hash, expected_hash_len) != 0)) {
|
||||
mbedtls_printf("Multi-part hash operation gave the wrong result!\n\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status =
|
||||
psa_hash_verify(&cloned_hash_operation, expected_hash,
|
||||
expected_hash_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_verify failed\n");
|
||||
goto cleanup;
|
||||
} else {
|
||||
mbedtls_printf("Multi-part hash operation successful!\n");
|
||||
}
|
||||
|
||||
/* Clear local variables prior to one-shot hash demo */
|
||||
memset(hash, 0, sizeof(hash));
|
||||
hash_length = 0;
|
||||
|
||||
/* Compute hash using one-shot function call */
|
||||
status = psa_hash_compute(HASH_ALG,
|
||||
sample_message, sample_message_length,
|
||||
hash, sizeof(hash),
|
||||
&hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
mbedtls_printf("psa_hash_compute failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (hash_length != expected_hash_len ||
|
||||
(memcmp(hash, expected_hash, expected_hash_len) != 0)) {
|
||||
mbedtls_printf("One-shot hash operation gave the wrong result!\n\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
mbedtls_printf("One-shot hash operation successful!\n\n");
|
||||
|
||||
/* Print out result */
|
||||
mbedtls_printf("The SHA-256( '%s' ) is: ", sample_message);
|
||||
|
||||
for (size_t j = 0; j < expected_hash_len; j++) {
|
||||
mbedtls_printf("%02x", hash[j]);
|
||||
}
|
||||
|
||||
mbedtls_printf("\n");
|
||||
|
||||
mbedtls_psa_crypto_free();
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
psa_hash_abort(&hash_operation);
|
||||
psa_hash_abort(&cloned_hash_operation);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif /* !MBEDTLS_PSA_CRYPTO_C || !PSA_WANT_ALG_SHA_256 */
|
@ -32,11 +32,12 @@
|
||||
* If you switch to a different algorithm you will need to update
|
||||
* the hash data in the EXAMPLE_HASH_VALUE macro below. */
|
||||
|
||||
#if !defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256)
|
||||
#if !defined(MBEDTLS_PSA_CRYPTO_CLIENT) && \
|
||||
(!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(PSA_WANT_ALG_SHA_256))
|
||||
int main(void)
|
||||
{
|
||||
mbedtls_printf("MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256"
|
||||
"not defined.\r\n");
|
||||
"not defined, and not MBEDTLS_PSA_CRYPTO_CLIENT.\r\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#else
|
||||
|
@ -12,6 +12,20 @@ enum {
|
||||
/* Start here to avoid overlap with PSA_IPC_CONNECT, PSA_IPC_DISCONNECT
|
||||
* and VERSION_REQUEST */
|
||||
PSA_CRYPTO_INIT = 100,
|
||||
PSA_AEAD_ABORT,
|
||||
PSA_AEAD_DECRYPT,
|
||||
PSA_AEAD_DECRYPT_SETUP,
|
||||
PSA_AEAD_ENCRYPT,
|
||||
PSA_AEAD_ENCRYPT_SETUP,
|
||||
PSA_AEAD_FINISH,
|
||||
PSA_AEAD_GENERATE_NONCE,
|
||||
PSA_AEAD_SET_LENGTHS,
|
||||
PSA_AEAD_SET_NONCE,
|
||||
PSA_AEAD_UPDATE,
|
||||
PSA_AEAD_UPDATE_AD,
|
||||
PSA_AEAD_VERIFY,
|
||||
PSA_DESTROY_KEY,
|
||||
PSA_GET_KEY_ATTRIBUTES,
|
||||
PSA_HASH_ABORT,
|
||||
PSA_HASH_CLONE,
|
||||
PSA_HASH_COMPARE,
|
||||
@ -20,6 +34,7 @@ enum {
|
||||
PSA_HASH_SETUP,
|
||||
PSA_HASH_UPDATE,
|
||||
PSA_HASH_VERIFY,
|
||||
PSA_IMPORT_KEY,
|
||||
};
|
||||
|
||||
#endif /* _PSA_FUNCTIONS_CODES_H_ */
|
||||
|
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
@ -51,6 +51,87 @@
|
||||
* don't contain pointers.
|
||||
*/
|
||||
|
||||
/* include/psa/crypto_platform.h:typedef uint32_t mbedtls_psa_client_handle_t;
|
||||
* but we don't get it on server builds, so redefine it here with a unique type name
|
||||
*/
|
||||
typedef uint32_t psasim_client_handle_t;
|
||||
|
||||
typedef struct psasim_operation_s {
|
||||
psasim_client_handle_t handle;
|
||||
} psasim_operation_t;
|
||||
|
||||
#define MAX_LIVE_HANDLES_PER_CLASS 100 /* this many slots */
|
||||
|
||||
static psa_hash_operation_t hash_operations[MAX_LIVE_HANDLES_PER_CLASS];
|
||||
static psasim_client_handle_t hash_operation_handles[MAX_LIVE_HANDLES_PER_CLASS];
|
||||
static psasim_client_handle_t next_hash_operation_handle = 1;
|
||||
|
||||
/* Get a free slot */
|
||||
static ssize_t allocate_hash_operation_slot(void)
|
||||
{
|
||||
psasim_client_handle_t handle = next_hash_operation_handle++;
|
||||
if (next_hash_operation_handle == 0) { /* wrapped around */
|
||||
fprintf(stderr, "MAX HASH HANDLES REACHED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) {
|
||||
if (hash_operation_handles[i] == 0) {
|
||||
hash_operation_handles[i] = handle;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* all in use */
|
||||
}
|
||||
|
||||
/* Find the slot given the handle */
|
||||
static ssize_t find_hash_slot_by_handle(psasim_client_handle_t handle)
|
||||
{
|
||||
for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) {
|
||||
if (hash_operation_handles[i] == handle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* all in use */
|
||||
}
|
||||
|
||||
static psa_aead_operation_t aead_operations[MAX_LIVE_HANDLES_PER_CLASS];
|
||||
static psasim_client_handle_t aead_operation_handles[MAX_LIVE_HANDLES_PER_CLASS];
|
||||
static psasim_client_handle_t next_aead_operation_handle = 1;
|
||||
|
||||
/* Get a free slot */
|
||||
static ssize_t allocate_aead_operation_slot(void)
|
||||
{
|
||||
psasim_client_handle_t handle = next_aead_operation_handle++;
|
||||
if (next_aead_operation_handle == 0) { /* wrapped around */
|
||||
fprintf(stderr, "MAX HASH HANDLES REACHED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) {
|
||||
if (aead_operation_handles[i] == 0) {
|
||||
aead_operation_handles[i] = handle;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* all in use */
|
||||
}
|
||||
|
||||
/* Find the slot given the handle */
|
||||
static ssize_t find_aead_slot_by_handle(psasim_client_handle_t handle)
|
||||
{
|
||||
for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) {
|
||||
if (aead_operation_handles[i] == handle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* all in use */
|
||||
}
|
||||
|
||||
size_t psasim_serialise_begin_needs(void)
|
||||
{
|
||||
/* The serialisation buffer will
|
||||
@ -404,3 +485,224 @@ int psasim_deserialise_psa_hash_operation_t(uint8_t **pos,
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *operation)
|
||||
{
|
||||
(void) operation;
|
||||
|
||||
/* We will actually return a handle */
|
||||
return sizeof(psasim_operation_t);
|
||||
}
|
||||
|
||||
int psasim_server_serialise_psa_hash_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_hash_operation_t *operation)
|
||||
{
|
||||
psasim_operation_t client_operation;
|
||||
|
||||
if (*remaining < sizeof(client_operation)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t slot = operation - hash_operations;
|
||||
|
||||
client_operation.handle = hash_operation_handles[slot];
|
||||
|
||||
memcpy(*pos, &client_operation, sizeof(client_operation));
|
||||
*pos += sizeof(client_operation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_hash_operation_t **operation)
|
||||
{
|
||||
psasim_operation_t client_operation;
|
||||
|
||||
if (*remaining < sizeof(psasim_operation_t)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&client_operation, *pos, sizeof(psasim_operation_t));
|
||||
*pos += sizeof(psasim_operation_t);
|
||||
*remaining -= sizeof(psasim_operation_t);
|
||||
|
||||
ssize_t slot;
|
||||
if (client_operation.handle == 0) { /* We need a new handle */
|
||||
slot = allocate_hash_operation_slot();
|
||||
} else {
|
||||
slot = find_hash_slot_by_handle(client_operation.handle);
|
||||
}
|
||||
|
||||
if (slot < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*operation = &hash_operations[slot];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_psa_aead_operation_t_needs(psa_aead_operation_t value)
|
||||
{
|
||||
return sizeof(value);
|
||||
}
|
||||
|
||||
int psasim_serialise_psa_aead_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_aead_operation_t value)
|
||||
{
|
||||
if (*remaining < sizeof(value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(*pos, &value, sizeof(value));
|
||||
*pos += sizeof(value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_deserialise_psa_aead_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_aead_operation_t *value)
|
||||
{
|
||||
if (*remaining < sizeof(*value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(value, *pos, sizeof(*value));
|
||||
|
||||
*pos += sizeof(*value);
|
||||
*remaining -= sizeof(*value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_server_serialise_psa_aead_operation_t_needs(psa_aead_operation_t *operation)
|
||||
{
|
||||
(void) operation;
|
||||
|
||||
/* We will actually return a handle */
|
||||
return sizeof(psasim_operation_t);
|
||||
}
|
||||
|
||||
int psasim_server_serialise_psa_aead_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_aead_operation_t *operation)
|
||||
{
|
||||
psasim_operation_t client_operation;
|
||||
|
||||
if (*remaining < sizeof(client_operation)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t slot = operation - aead_operations;
|
||||
|
||||
client_operation.handle = aead_operation_handles[slot];
|
||||
|
||||
memcpy(*pos, &client_operation, sizeof(client_operation));
|
||||
*pos += sizeof(client_operation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_server_deserialise_psa_aead_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_aead_operation_t **operation)
|
||||
{
|
||||
psasim_operation_t client_operation;
|
||||
|
||||
if (*remaining < sizeof(psasim_operation_t)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&client_operation, *pos, sizeof(psasim_operation_t));
|
||||
*pos += sizeof(psasim_operation_t);
|
||||
*remaining -= sizeof(psasim_operation_t);
|
||||
|
||||
ssize_t slot;
|
||||
if (client_operation.handle == 0) { /* We need a new handle */
|
||||
slot = allocate_aead_operation_slot();
|
||||
} else {
|
||||
slot = find_aead_slot_by_handle(client_operation.handle);
|
||||
}
|
||||
|
||||
if (slot < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*operation = &aead_operations[slot];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_psa_key_attributes_t_needs(psa_key_attributes_t value)
|
||||
{
|
||||
return sizeof(value);
|
||||
}
|
||||
|
||||
int psasim_serialise_psa_key_attributes_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_attributes_t value)
|
||||
{
|
||||
if (*remaining < sizeof(value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(*pos, &value, sizeof(value));
|
||||
*pos += sizeof(value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_deserialise_psa_key_attributes_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_attributes_t *value)
|
||||
{
|
||||
if (*remaining < sizeof(*value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(value, *pos, sizeof(*value));
|
||||
|
||||
*pos += sizeof(*value);
|
||||
*remaining -= sizeof(*value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value)
|
||||
{
|
||||
return sizeof(value);
|
||||
}
|
||||
|
||||
int psasim_serialise_mbedtls_svc_key_id_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
mbedtls_svc_key_id_t value)
|
||||
{
|
||||
if (*remaining < sizeof(value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(*pos, &value, sizeof(value));
|
||||
*pos += sizeof(value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
mbedtls_svc_key_id_t *value)
|
||||
{
|
||||
if (*remaining < sizeof(*value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(value, *pos, sizeof(*value));
|
||||
|
||||
*pos += sizeof(*value);
|
||||
*remaining -= sizeof(*value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -408,3 +408,213 @@ int psasim_serialise_psa_hash_operation_t(uint8_t **pos,
|
||||
int psasim_deserialise_psa_hash_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_hash_operation_t *value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_server_serialise_psa_hash_operation_t()
|
||||
* to serialise a `psa_hash_operation_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_psa_hash_operation_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_server_serialise_psa_hash_operation_t_needs(psa_hash_operation_t *value);
|
||||
|
||||
/** Serialise a `psa_hash_operation_t` into a buffer on the server side.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_server_serialise_psa_hash_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_hash_operation_t *value);
|
||||
|
||||
/** Deserialise a `psa_hash_operation_t` from a buffer on the server side.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to a `psa_hash_operation_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_server_deserialise_psa_hash_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_hash_operation_t **value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_psa_aead_operation_t()
|
||||
* to serialise a `psa_aead_operation_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_psa_aead_operation_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_serialise_psa_aead_operation_t_needs(psa_aead_operation_t value);
|
||||
|
||||
/** Serialise a `psa_aead_operation_t` into a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_psa_aead_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_aead_operation_t value);
|
||||
|
||||
/** Deserialise a `psa_aead_operation_t` from a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to a `psa_aead_operation_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_psa_aead_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_aead_operation_t *value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_server_serialise_psa_aead_operation_t()
|
||||
* to serialise a `psa_aead_operation_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_psa_aead_operation_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_server_serialise_psa_aead_operation_t_needs(psa_aead_operation_t *value);
|
||||
|
||||
/** Serialise a `psa_aead_operation_t` into a buffer on the server side.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_server_serialise_psa_aead_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_aead_operation_t *value);
|
||||
|
||||
/** Deserialise a `psa_aead_operation_t` from a buffer on the server side.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to a `psa_aead_operation_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_server_deserialise_psa_aead_operation_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_aead_operation_t **value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_psa_key_attributes_t()
|
||||
* to serialise a `psa_key_attributes_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_psa_key_attributes_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_serialise_psa_key_attributes_t_needs(psa_key_attributes_t value);
|
||||
|
||||
/** Serialise a `psa_key_attributes_t` into a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_psa_key_attributes_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_attributes_t value);
|
||||
|
||||
/** Deserialise a `psa_key_attributes_t` from a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to a `psa_key_attributes_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_psa_key_attributes_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
psa_key_attributes_t *value);
|
||||
|
||||
/** Return how much buffer space is needed by \c psasim_serialise_mbedtls_svc_key_id_t()
|
||||
* to serialise a `mbedtls_svc_key_id_t`.
|
||||
*
|
||||
* \param value The value that will be serialised into the buffer
|
||||
* (needed in case some serialisations are value-
|
||||
* dependent).
|
||||
*
|
||||
* \return The number of bytes needed in the buffer by
|
||||
* \c psasim_serialise_mbedtls_svc_key_id_t() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_serialise_mbedtls_svc_key_id_t_needs(mbedtls_svc_key_id_t value);
|
||||
|
||||
/** Serialise a `mbedtls_svc_key_id_t` into a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value The value to serialise into the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_mbedtls_svc_key_id_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
mbedtls_svc_key_id_t value);
|
||||
|
||||
/** Deserialise a `mbedtls_svc_key_id_t` from a buffer.
|
||||
*
|
||||
* \param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
* \param remaining[in,out] Pointer to a `size_t` holding number of bytes
|
||||
* remaining in the buffer.
|
||||
* \param value Pointer to a `mbedtls_svc_key_id_t` to receive the value
|
||||
* deserialised from the buffer.
|
||||
*
|
||||
* \return \c 1 on success ("okay"), \c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
mbedtls_svc_key_id_t *value);
|
||||
|
@ -38,7 +38,11 @@ die($usage) unless $which eq "c" || $which eq "h";
|
||||
my @types = qw(unsigned-int int size_t
|
||||
buffer
|
||||
psa_status_t psa_algorithm_t
|
||||
psa_hash_operation_t);
|
||||
psa_hash_operation_t
|
||||
psa_aead_operation_t
|
||||
psa_key_attributes_t
|
||||
mbedtls_svc_key_id_t);
|
||||
|
||||
grep(s/-/ /g, @types);
|
||||
|
||||
# IS-A: Some data types are typedef'd; we serialise them as the other type
|
||||
@ -55,15 +59,31 @@ if ($which eq "h") {
|
||||
if ($type eq "buffer") {
|
||||
print declare_buffer_functions();
|
||||
} else {
|
||||
print declare_needs($type);
|
||||
print declare_serialise($type);
|
||||
print declare_deserialise($type);
|
||||
print declare_needs($type, "");
|
||||
print declare_serialise($type, "");
|
||||
print declare_deserialise($type, "");
|
||||
|
||||
if ($type =~ /^psa_\w+_operation_t$/) {
|
||||
print declare_needs($type, "server_");
|
||||
print declare_serialise($type, "server_");
|
||||
print declare_deserialise($type, "server_");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elsif ($which eq "c") {
|
||||
|
||||
my $have_operation_types = (grep(/psa_\w+_operation_t/, @types)) ? 1 : 0;
|
||||
|
||||
print c_header();
|
||||
print c_define_types_for_operation_types() if $have_operation_types;
|
||||
|
||||
for my $type (@types) {
|
||||
next unless $type =~ /^psa_(\w+)_operation_t$/;
|
||||
print define_operation_type_data_and_functions($1);
|
||||
}
|
||||
|
||||
print c_define_begins();
|
||||
|
||||
for my $type (@types) {
|
||||
if ($type eq "buffer") {
|
||||
@ -76,6 +96,12 @@ if ($which eq "h") {
|
||||
print define_needs($type);
|
||||
print define_serialise($type);
|
||||
print define_deserialise($type);
|
||||
|
||||
if ($type =~ /^psa_\w+_operation_t$/) {
|
||||
print define_server_needs($type);
|
||||
print define_server_serialise($type);
|
||||
print define_server_deserialise($type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,15 +111,17 @@ if ($which eq "h") {
|
||||
|
||||
sub declare_needs
|
||||
{
|
||||
my ($type) = @_;
|
||||
my ($type, $server) = @_;
|
||||
|
||||
my $an = ($type =~ /^[ui]/) ? "an" : "a";
|
||||
my $type_d = $type;
|
||||
$type_d =~ s/ /_/g;
|
||||
|
||||
my $ptr = (length($server)) ? "*" : "";
|
||||
|
||||
return <<EOF;
|
||||
|
||||
/** Return how much buffer space is needed by \\c psasim_serialise_$type_d()
|
||||
/** Return how much buffer space is needed by \\c psasim_${server}serialise_$type_d()
|
||||
* to serialise $an `$type`.
|
||||
*
|
||||
* \\param value The value that will be serialised into the buffer
|
||||
@ -104,21 +132,25 @@ sub declare_needs
|
||||
* \\c psasim_serialise_$type_d() to serialise
|
||||
* the given value.
|
||||
*/
|
||||
size_t psasim_serialise_${type_d}_needs($type value);
|
||||
size_t psasim_${server}serialise_${type_d}_needs($type ${ptr}value);
|
||||
EOF
|
||||
}
|
||||
|
||||
sub declare_serialise
|
||||
{
|
||||
my ($type) = @_;
|
||||
my ($type, $server) = @_;
|
||||
|
||||
my $an = ($type =~ /^[ui]/) ? "an" : "a";
|
||||
my $type_d = $type;
|
||||
$type_d =~ s/ /_/g;
|
||||
|
||||
my $server_side = (length($server)) ? " on the server side" : "";
|
||||
|
||||
my $ptr = (length($server)) ? "*" : "";
|
||||
|
||||
return align_declaration(<<EOF);
|
||||
|
||||
/** Serialise $an `$type` into a buffer.
|
||||
/** Serialise $an `$type` into a buffer${server_side}.
|
||||
*
|
||||
* \\param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
@ -128,23 +160,27 @@ sub declare_serialise
|
||||
*
|
||||
* \\return \\c 1 on success ("okay"), \\c 0 on error.
|
||||
*/
|
||||
int psasim_serialise_$type_d(uint8_t **pos,
|
||||
int psasim_${server}serialise_$type_d(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
$type value);
|
||||
$type ${ptr}value);
|
||||
EOF
|
||||
}
|
||||
|
||||
sub declare_deserialise
|
||||
{
|
||||
my ($type) = @_;
|
||||
my ($type, $server) = @_;
|
||||
|
||||
my $an = ($type =~ /^[ui]/) ? "an" : "a";
|
||||
my $type_d = $type;
|
||||
$type_d =~ s/ /_/g;
|
||||
|
||||
my $server_side = (length($server)) ? " on the server side" : "";
|
||||
|
||||
my $ptr = (length($server)) ? "*" : "";
|
||||
|
||||
return align_declaration(<<EOF);
|
||||
|
||||
/** Deserialise $an `$type` from a buffer.
|
||||
/** Deserialise $an `$type` from a buffer${server_side}.
|
||||
*
|
||||
* \\param pos[in,out] Pointer to a `uint8_t *` holding current position
|
||||
* in the buffer.
|
||||
@ -155,9 +191,9 @@ sub declare_deserialise
|
||||
*
|
||||
* \\return \\c 1 on success ("okay"), \\c 0 on error.
|
||||
*/
|
||||
int psasim_deserialise_$type_d(uint8_t **pos,
|
||||
int psasim_${server}deserialise_$type_d(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
$type *value);
|
||||
$type ${ptr}*value);
|
||||
EOF
|
||||
}
|
||||
|
||||
@ -347,6 +383,25 @@ size_t psasim_serialise_${type_d}_needs($type value)
|
||||
EOF
|
||||
}
|
||||
|
||||
sub define_server_needs
|
||||
{
|
||||
my ($type) = @_;
|
||||
|
||||
my $type_d = $type;
|
||||
$type_d =~ s/ /_/g;
|
||||
|
||||
return <<EOF;
|
||||
|
||||
size_t psasim_server_serialise_${type_d}_needs($type *operation)
|
||||
{
|
||||
(void) operation;
|
||||
|
||||
/* We will actually return a handle */
|
||||
return sizeof(psasim_operation_t);
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
sub define_needs_isa
|
||||
{
|
||||
my ($type, $isa) = @_;
|
||||
@ -391,6 +446,44 @@ int psasim_serialise_$type_d(uint8_t **pos,
|
||||
EOF
|
||||
}
|
||||
|
||||
sub define_server_serialise
|
||||
{
|
||||
my ($type) = @_;
|
||||
|
||||
my $t;
|
||||
if ($type =~ /^psa_(\w+)_operation_t$/) {
|
||||
$t = $1;
|
||||
} else {
|
||||
die("$0: define_server_serialise: $type: not supported\n");
|
||||
}
|
||||
|
||||
my $type_d = $type;
|
||||
$type_d =~ s/ /_/g;
|
||||
|
||||
return align_signature(<<EOF);
|
||||
|
||||
int psasim_server_serialise_$type_d(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
$type *operation)
|
||||
{
|
||||
psasim_operation_t client_operation;
|
||||
|
||||
if (*remaining < sizeof(client_operation)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t slot = operation - ${t}_operations;
|
||||
|
||||
client_operation.handle = ${t}_operation_handles[slot];
|
||||
|
||||
memcpy(*pos, &client_operation, sizeof(client_operation));
|
||||
*pos += sizeof(client_operation);
|
||||
|
||||
return 1;
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
sub define_serialise_isa
|
||||
{
|
||||
my ($type, $isa) = @_;
|
||||
@ -439,6 +532,54 @@ int psasim_deserialise_$type_d(uint8_t **pos,
|
||||
EOF
|
||||
}
|
||||
|
||||
sub define_server_deserialise
|
||||
{
|
||||
my ($type) = @_;
|
||||
|
||||
my $t;
|
||||
if ($type =~ /^psa_(\w+)_operation_t$/) {
|
||||
$t = $1;
|
||||
} else {
|
||||
die("$0: define_server_serialise: $type: not supported\n");
|
||||
}
|
||||
|
||||
my $type_d = $type;
|
||||
$type_d =~ s/ /_/g;
|
||||
|
||||
return align_signature(<<EOF);
|
||||
|
||||
int psasim_server_deserialise_$type_d(uint8_t **pos,
|
||||
size_t *remaining,
|
||||
$type **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_${t}_operation_slot();
|
||||
} else {
|
||||
slot = find_${t}_slot_by_handle(client_operation.handle);
|
||||
}
|
||||
|
||||
if (slot < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*operation = &${t}_operations[slot];
|
||||
|
||||
return 1;
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
sub define_deserialise_isa
|
||||
{
|
||||
my ($type, $isa) = @_;
|
||||
@ -623,6 +764,72 @@ sub c_header
|
||||
* data types (e.g. int), types typedef'd to those, and even structures that
|
||||
* don't contain pointers.
|
||||
*/
|
||||
EOF
|
||||
}
|
||||
|
||||
sub c_define_types_for_operation_types
|
||||
{
|
||||
return <<'EOF';
|
||||
|
||||
/* include/psa/crypto_platform.h:typedef uint32_t mbedtls_psa_client_handle_t;
|
||||
* but we don't get it on server builds, so redefine it here with a unique type name
|
||||
*/
|
||||
typedef uint32_t psasim_client_handle_t;
|
||||
|
||||
typedef struct psasim_operation_s {
|
||||
psasim_client_handle_t handle;
|
||||
} psasim_operation_t;
|
||||
|
||||
#define MAX_LIVE_HANDLES_PER_CLASS 100 /* this many slots */
|
||||
EOF
|
||||
}
|
||||
|
||||
sub define_operation_type_data_and_functions
|
||||
{
|
||||
my ($type) = @_; # e.g. 'hash' rather than 'psa_hash_operation_t'
|
||||
|
||||
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 psasim_client_handle_t next_${type}_operation_handle = 1;
|
||||
|
||||
/* Get a free slot */
|
||||
static ssize_t allocate_${type}_operation_slot(void)
|
||||
{
|
||||
psasim_client_handle_t handle = next_${type}_operation_handle++;
|
||||
if (next_${type}_operation_handle == 0) { /* wrapped around */
|
||||
fprintf(stderr, "MAX HASH HANDLES REACHED\\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) {
|
||||
if (${type}_operation_handles[i] == 0) {
|
||||
${type}_operation_handles[i] = handle;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* all in use */
|
||||
}
|
||||
|
||||
/* Find the slot given the handle */
|
||||
static ssize_t find_${type}_slot_by_handle(psasim_client_handle_t handle)
|
||||
{
|
||||
for (ssize_t i = 0; i < MAX_LIVE_HANDLES_PER_CLASS; i++) {
|
||||
if (${type}_operation_handles[i] == handle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* all in use */
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
sub c_define_begins
|
||||
{
|
||||
return <<'EOF';
|
||||
|
||||
size_t psasim_serialise_begin_needs(void)
|
||||
{
|
||||
|
@ -33,5 +33,5 @@ clean_run
|
||||
./psa_partition -k &
|
||||
SERV_PID=$!
|
||||
wait_for_server_startup
|
||||
./psa_client
|
||||
./psa_client "$@"
|
||||
wait $SERV_PID
|
||||
|
@ -964,18 +964,17 @@ helper_crypto_client_build() {
|
||||
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
|
||||
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
|
||||
scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
|
||||
scripts/config.py unset MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
else
|
||||
scripts/config.py crypto_full
|
||||
scripts/config.py unset MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
|
||||
scripts/config.py set MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
# We need to match the client with MBEDTLS_PSA_CRYPTO_SE_C
|
||||
scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
|
||||
# Also ensure MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER not set (to match client)
|
||||
scripts/config.py unset MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
|
||||
fi
|
||||
|
||||
make -C tests/psa-client-server/psasim/ CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" $TARGET_LIB "$@"
|
||||
|
||||
# cleanup() will restore some backed-up files which include $CONFIG_H and
|
||||
# $CRYPTO_CONFIG_H. Built libraries were already copied to psasim at this
|
||||
# point.
|
||||
cleanup
|
||||
}
|
||||
|
||||
################################################################
|
||||
@ -6158,45 +6157,60 @@ component_check_test_helpers () {
|
||||
}
|
||||
|
||||
component_test_psasim() {
|
||||
msg "build library for client"
|
||||
|
||||
helper_crypto_client_build client
|
||||
|
||||
msg "build library for server"
|
||||
|
||||
scripts/config.py crypto
|
||||
|
||||
helper_crypto_client_build server
|
||||
|
||||
msg "build psasim"
|
||||
make -C tests/psa-client-server/psasim CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS"
|
||||
msg "build server"
|
||||
make -C tests/psa-client-server/psasim CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" test/psa_partition
|
||||
|
||||
# cleanup() will restore some backed-up files which include $CONFIG_H and
|
||||
# $CRYPTO_CONFIG_H. Built libraries were already copied to psasim at this
|
||||
# point.
|
||||
cleanup
|
||||
|
||||
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 "test psasim"
|
||||
tests/psa-client-server/psasim/test/run_test.sh
|
||||
|
||||
|
||||
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"
|
||||
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_*(). Just use the PSA hash example.
|
||||
aut_psa_hash="../../../programs/psa/psa_hash.c"
|
||||
if [ -f "tests/psa-client-server/psasim/$aut_psa_hash" ]; then
|
||||
|
||||
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="$aut_psa_hash"
|
||||
# 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
|
||||
else
|
||||
echo $aut_psa_hash NOT FOUND, so not running that test
|
||||
fi
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user