diff --git a/tests/sys/psa_crypto_se/Makefile b/tests/sys/psa_crypto_se/Makefile index 9186bbff11425..b35e773db7d76 100644 --- a/tests/sys/psa_crypto_se/Makefile +++ b/tests/sys/psa_crypto_se/Makefile @@ -15,10 +15,8 @@ USEMODULE += psa_secure_element_ateccx08a_cipher_aes_128 USEMODULE += psa_secure_element_ateccx08a_hmac_sha256 USEMODULE += psa_secure_element_ateccx08a_ecc_p256 -ifneq (1, $(SHOULD_RUN_KCONFIG)) - CFLAGS += -DCONFIG_PSA_PROTECTED_KEY_COUNT=3 - CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=1 -endif +CFLAGS += -DCONFIG_PSA_PROTECTED_KEY_COUNT=4 +CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=1 CFLAGS += -DSECURE_ELEMENT CFLAGS += -DCUSTOM_ATCA_PARAMS diff --git a/tests/sys/psa_crypto_se/Makefile.ci b/tests/sys/psa_crypto_se/Makefile.ci index 04da97e287d48..6e784f7ec2acc 100644 --- a/tests/sys/psa_crypto_se/Makefile.ci +++ b/tests/sys/psa_crypto_se/Makefile.ci @@ -8,5 +8,4 @@ BOARD_INSUFFICIENT_MEMORY := \ atmega8 \ nucleo-l011k4 \ samd10-xmini \ - stm32f030f4-demo \ # diff --git a/tests/sys/psa_crypto_se/example_cipher_aes_128.c b/tests/sys/psa_crypto_se/example_cipher_aes_128.c deleted file mode 120000 index 3b052c133690a..0000000000000 --- a/tests/sys/psa_crypto_se/example_cipher_aes_128.c +++ /dev/null @@ -1 +0,0 @@ -../../../examples/psa_crypto/example_cipher_aes_128.c \ No newline at end of file diff --git a/tests/sys/psa_crypto_se/example_cipher_aes_128.c b/tests/sys/psa_crypto_se/example_cipher_aes_128.c new file mode 100644 index 0000000000000..2fbe0b7c8cef2 --- /dev/null +++ b/tests/sys/psa_crypto_se/example_cipher_aes_128.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @brief Example functions for AES CBC encryption with PSA Crypto + * + * @author Lena Boeckmann + * + * @} + */ + +#include +#include + +#include "psa/crypto.h" + +#define AES_128_KEY_SIZE (16) +#define AES_256_KEY_SIZE (32) + +static const uint8_t KEY_128[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c +}; + +static uint8_t PLAINTEXT[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 +}; +static uint8_t PLAINTEXT_LEN = 32; + +/** + * @brief Example function to perform an AES-128 CBC encryption and decryption + * with the PSA Crypto API. + * + * @return psa_status_t + */ +psa_status_t example_cipher_aes_128(void) +{ + psa_status_t status = PSA_ERROR_DOES_NOT_EXIST; + psa_key_id_t key_id = 0; + psa_key_attributes_t attr = psa_key_attributes_init(); + psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT; + + size_t encr_output_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES, + PSA_ALG_CBC_NO_PADDING, PLAINTEXT_LEN); + + uint8_t cipher_out[encr_output_size]; + uint8_t plain_out[sizeof(PLAINTEXT)]; + size_t output_len = 0; + + psa_set_key_algorithm(&attr, PSA_ALG_CBC_NO_PADDING); + psa_set_key_usage_flags(&attr, usage); + psa_set_key_bits(&attr, 128); + psa_set_key_type(&attr, PSA_KEY_TYPE_AES); + + psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION + (PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0); + psa_set_key_lifetime(&attr, lifetime); + + status = psa_import_key(&attr, KEY_128, AES_128_KEY_SIZE, &key_id); + if (status != PSA_SUCCESS) { + return status; + } + + status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, PLAINTEXT, + PLAINTEXT_LEN, cipher_out, encr_output_size, &output_len); + if (status != PSA_SUCCESS) { + return status; + } + + status = psa_cipher_decrypt(key_id, PSA_ALG_CBC_NO_PADDING, cipher_out, + sizeof(cipher_out), plain_out, sizeof(plain_out), &output_len); + if (status == PSA_SUCCESS) { + return (memcmp(PLAINTEXT, plain_out, sizeof(plain_out)) ? -1 : 0); + } + return status; +} diff --git a/tests/sys/psa_crypto_se/example_ecdsa_p256.c b/tests/sys/psa_crypto_se/example_ecdsa_p256.c deleted file mode 120000 index 45df4f9cec226..0000000000000 --- a/tests/sys/psa_crypto_se/example_ecdsa_p256.c +++ /dev/null @@ -1 +0,0 @@ -../../../examples/psa_crypto/example_ecdsa_p256.c \ No newline at end of file diff --git a/tests/sys/psa_crypto_se/example_ecdsa_p256.c b/tests/sys/psa_crypto_se/example_ecdsa_p256.c new file mode 100644 index 0000000000000..b9a0aa16aa855 --- /dev/null +++ b/tests/sys/psa_crypto_se/example_ecdsa_p256.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2022 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @brief Example functions for ECDSA with PSA Crypto + * + * @author Lena Boeckmann + * + * @} + */ + +#include +#include + +#include "psa/crypto.h" + +#define ECDSA_MESSAGE_SIZE (127) + +#define ECC_KEY_SIZE (256) +#define ECC_KEY_TYPE (PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) +#define ECC_ALG_HASH (PSA_ALG_SHA_256) +#define ECC_ALG (PSA_ALG_ECDSA(ECC_ALG_HASH)) + +/** + * @brief Example function to perform an ECDSA operation with a NIST P256 curve + * with the PSA Crypto API. + * + * @return psa_status_t + */ +psa_status_t example_ecdsa_p256(void) +{ + psa_key_id_t privkey_id; + psa_key_attributes_t privkey_attr = psa_key_attributes_init(); + psa_key_id_t pubkey_id; + psa_key_attributes_t pubkey_attr = psa_key_attributes_init(); + + psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH; + + uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(ECC_KEY_TYPE, ECC_KEY_SIZE)] = { 0 }; + size_t pubkey_length; + uint8_t signature[PSA_SIGN_OUTPUT_SIZE(ECC_KEY_TYPE, ECC_KEY_SIZE, ECC_ALG)]; + size_t sig_length; + uint8_t msg[ECDSA_MESSAGE_SIZE] = { 0x0b }; + uint8_t hash[PSA_HASH_LENGTH(ECC_ALG_HASH)]; + size_t hash_length; + + psa_set_key_algorithm(&privkey_attr, ECC_ALG); + psa_set_key_usage_flags(&privkey_attr, usage); + psa_set_key_type(&privkey_attr, ECC_KEY_TYPE); + psa_set_key_bits(&privkey_attr, ECC_KEY_SIZE); + + psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0); + psa_set_key_lifetime(&privkey_attr, lifetime); + + psa_status_t status = PSA_ERROR_DOES_NOT_EXIST; + + status = psa_generate_key(&privkey_attr, &privkey_id); + if (status != PSA_SUCCESS) { + return status; + } + + status = psa_export_public_key(privkey_id, public_key, sizeof(public_key), &pubkey_length); + if (status != PSA_SUCCESS) { + return status; + } + + status = psa_hash_compute(ECC_ALG_HASH, msg, sizeof(msg), hash, sizeof(hash), &hash_length); + if (status != PSA_SUCCESS) { + return status; + } + + /* Currently there is no support for message signature and verification on secure elements */ + psa_set_key_lifetime(&pubkey_attr, lifetime); + psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&pubkey_attr, ECC_ALG); + psa_set_key_bits(&pubkey_attr, PSA_BYTES_TO_BITS(pubkey_length)); + psa_set_key_type(&pubkey_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + + status = psa_import_key(&pubkey_attr, public_key, pubkey_length, &pubkey_id); + if (status != PSA_SUCCESS) { + return status; + } + + status = psa_sign_hash(privkey_id, ECC_ALG, hash, sizeof(hash), signature, sizeof(signature), + &sig_length); + if (status != PSA_SUCCESS) { + return status; + } + + /* Currently there is only support for hash signature and verification on secure elements, + so we can't verify the message, but only the hash */ + return psa_verify_hash(pubkey_id, ECC_ALG, hash, sizeof(hash), signature, sig_length); +} diff --git a/tests/sys/psa_crypto_se/example_hmac_sha256.c b/tests/sys/psa_crypto_se/example_hmac_sha256.c deleted file mode 120000 index 710efbeabcde1..0000000000000 --- a/tests/sys/psa_crypto_se/example_hmac_sha256.c +++ /dev/null @@ -1 +0,0 @@ -../../../examples/psa_crypto/example_hmac_sha256.c \ No newline at end of file diff --git a/tests/sys/psa_crypto_se/example_hmac_sha256.c b/tests/sys/psa_crypto_se/example_hmac_sha256.c new file mode 100644 index 0000000000000..b6a7c181abc4f --- /dev/null +++ b/tests/sys/psa_crypto_se/example_hmac_sha256.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2022 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @brief Example functions for HMAC SHA256 with PSA Crypto + * + * @author Lena Boeckmann + * + * @} + */ + +#include +#include + +#include "psa/crypto.h" + +static const uint8_t HMAC_KEY[] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b +}; +static size_t HMAC_KEY_LEN = 32; + +static const uint8_t HMAC_MSG[] = { + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x68, 0x6d, 0x61, 0x63, 0x32, 0x35, 0x36 +}; +static size_t HMAC_MSG_LEN = 32; + +/** + * @brief Example function to perform an HMAC SHA-256 computation + * with the PSA Crypto API. + * + * @return psa_status_t + */ +psa_status_t example_hmac_sha256(void) +{ + psa_key_attributes_t attr = psa_key_attributes_init(); + psa_key_id_t key_id = 0; + psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_MESSAGE; + + size_t digest_size = + PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, HMAC_KEY_LEN, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + uint8_t digest[digest_size]; + size_t output_len = 0; + + psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + psa_set_key_usage_flags(&attr, usage); + psa_set_key_bits(&attr, PSA_BYTES_TO_BITS(HMAC_KEY_LEN)); + psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC); + + psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0); + psa_set_key_lifetime(&attr, lifetime); + + psa_status_t status = PSA_ERROR_DOES_NOT_EXIST; + status = psa_import_key(&attr, HMAC_KEY, HMAC_KEY_LEN, &key_id); + if (status != PSA_SUCCESS) { + return status; + } + + return psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256), + HMAC_MSG, HMAC_MSG_LEN, digest, digest_size, + &output_len); +} diff --git a/tests/sys/psa_crypto_se/main.c b/tests/sys/psa_crypto_se/main.c deleted file mode 120000 index a9fd2e2825758..0000000000000 --- a/tests/sys/psa_crypto_se/main.c +++ /dev/null @@ -1 +0,0 @@ -../../../examples/psa_crypto/main.c \ No newline at end of file diff --git a/tests/sys/psa_crypto_se/main.c b/tests/sys/psa_crypto_se/main.c new file mode 100644 index 0000000000000..1cb8ac917d7f0 --- /dev/null +++ b/tests/sys/psa_crypto_se/main.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2022 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @brief Example application for PSA Crypto + * + * @author Lena Boeckmann + * + * @} + */ + +#include +#include "psa/crypto.h" +#include "ztimer.h" + +extern psa_status_t example_cipher_aes_128(void); +extern psa_status_t example_hmac_sha256(void); +extern psa_status_t example_ecdsa_p256(void); + +int main(void) +{ + bool failed = false; + psa_status_t status; + + psa_crypto_init(); + + ztimer_acquire(ZTIMER_USEC); + ztimer_now_t start = ztimer_now(ZTIMER_USEC); + + /* Needed in case only hashes are tested */ + (void)status; + (void)start; + + status = example_hmac_sha256(); + printf("HMAC SHA256 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start)); + if (status != PSA_SUCCESS) { + failed = true; + printf("HMAC SHA256 failed: %s\n", psa_status_to_humanly_readable(status)); + } + + start = ztimer_now(ZTIMER_USEC); + status = example_cipher_aes_128(); + printf("Cipher AES 128 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start)); + if (status != PSA_SUCCESS) { + failed = true; + printf("Cipher AES 128 failed: %s\n", psa_status_to_humanly_readable(status)); + } + + start = ztimer_now(ZTIMER_USEC); + status = example_ecdsa_p256(); + printf("ECDSA took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start)); + if (status != PSA_SUCCESS) { + failed = true; + printf("ECDSA failed: %s\n", psa_status_to_humanly_readable(status)); + } + + ztimer_release(ZTIMER_USEC); + + if (failed) { + puts("Tests failed..."); + } + else { + puts("All Done"); + } + return 0; +}