diff --git a/cpu/nrf52/Kconfig b/cpu/nrf52/Kconfig index 06fc1501be..f76ad03b7c 100644 --- a/cpu/nrf52/Kconfig +++ b/cpu/nrf52/Kconfig @@ -77,6 +77,7 @@ config CPU_MODEL_NRF52840XXAA select HAS_PERIPH_CIPHER_AES_128_CBC select HAS_PERIPH_ECC_P192R1 select HAS_PERIPH_ECC_P256R1 + select HAS_PERIPH_ECC_ED25519 select HAS_PERIPH_CRYPTOCELL_310 ## CPU common symbols diff --git a/cpu/nrf52/Makefile.features b/cpu/nrf52/Makefile.features index 7b8a3755fc..a56403645e 100644 --- a/cpu/nrf52/Makefile.features +++ b/cpu/nrf52/Makefile.features @@ -20,6 +20,7 @@ ifneq (,$(filter nrf52840xxaa,$(CPU_MODEL))) FEATURES_PROVIDED += periph_cipher_aes_128_cbc FEATURES_PROVIDED += periph_ecc_p192r1 FEATURES_PROVIDED += periph_ecc_p256r1 + FEATURES_PROVIDED += periph_ecc_ed25519 endif ifeq (,$(filter nrf52832%,$(CPU_MODEL))) diff --git a/cpu/nrf52/periph/Kconfig b/cpu/nrf52/periph/Kconfig index ef2100bdf8..bdce106d53 100644 --- a/cpu/nrf52/periph/Kconfig +++ b/cpu/nrf52/periph/Kconfig @@ -30,6 +30,12 @@ config MODULE_PERIPH_ECC_P256R1 select MODULE_PERIPH_CRYPTOCELL_310 select MODULE_PSA_CRYPTOCELL_310_ECC_P256 +config MODULE_PERIPH_ECC_ED25519 + bool + depends on HAS_PERIPH_ECC_ED25519 + select MODULE_PERIPH_CRYPTOCELL_310 + select MODULE_PSA_CRYPTOCELL_310_ECC_ED25519 + # Hash Related Symbols config MODULE_PERIPH_HASH_SHA_1 bool diff --git a/cpu/nrf52/periph/Makefile.dep b/cpu/nrf52/periph/Makefile.dep index 28f2d30fb3..0eb51e479f 100644 --- a/cpu/nrf52/periph/Makefile.dep +++ b/cpu/nrf52/periph/Makefile.dep @@ -8,6 +8,11 @@ ifneq (,$(filter periph_ecc_p256r1,$(USEMODULE))) USEMODULE += psa_cryptocell_310_ecc_p256 endif +ifneq (,$(filter periph_ecc_ed25519,$(USEMODULE))) + USEPKG += driver_cryptocell_310 + USEMODULE += psa_cryptocell_310_ecc_ed25519 +endif + ifneq (,$(filter periph_hash_sha_1,$(USEMODULE))) USEPKG += driver_cryptocell_310 USEMODULE += psa_cryptocell_310_hashes_sha1 diff --git a/examples/psa_crypto/Makefile b/examples/psa_crypto/Makefile index 3ecba20ed3..d9780f4c30 100644 --- a/examples/psa_crypto/Makefile +++ b/examples/psa_crypto/Makefile @@ -63,7 +63,7 @@ else USEMODULE += psa_secure_element_ateccx08a_ecc_p256 else ifdef CUSTOM_BACKEND # Necessary configuration when using Make dependency resolution - # This first part chooses the operation. If nothing else es specified, + # This first part chooses the operation. If nothing else is specified, # a default backend is built depending on the platform capabilities. USEMODULE += psa_cipher USEMODULE += psa_cipher_aes_128_cbc @@ -73,6 +73,7 @@ else USEMODULE += psa_asymmetric USEMODULE += psa_asymmetric_ecc_p256r1 + USEMODULE += psa_asymmetric_ecc_ed25519 # If you want to use a custom backend, you need to do it this way. USEMODULE += psa_cipher_aes_128_cbc_custom_backend @@ -86,6 +87,9 @@ else USEMODULE += psa_asymmetric_ecc_p256r1_custom_backend USEMODULE += psa_asymmetric_ecc_p256r1_backend_microecc # force custom backend + + USEMODULE += psa_asymmetric_ecc_ed25519_custom_backend + USEMODULE += psa_asymmetric_ecc_ed25519_backend_c25519 # force custom backend else # Necessary configuration when using Make dependency resolution # This part only chooses the operation. If nothing else es specified, @@ -98,11 +102,12 @@ else USEMODULE += psa_asymmetric USEMODULE += psa_asymmetric_ecc_p256r1 + USEMODULE += psa_asymmetric_ecc_ed25519 endif ifndef SECURE_ELEMENT - CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1 - CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=3 + CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=2 + CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=4 endif endif diff --git a/examples/psa_crypto/README.md b/examples/psa_crypto/README.md index 5564fca302..28263ecbc6 100644 --- a/examples/psa_crypto/README.md +++ b/examples/psa_crypto/README.md @@ -4,10 +4,11 @@ This example application is supposed to show two things: 2. How to configure the implementation with Kconfig dependency resolution vs. Make dependency resolution ## Basic usage of PSA Crypto -There are three example operations: +There are four example operations: - AES 128 CBC - HMAC SHA256 - ECDSA with a P256 curve +- EdDSA with the Ed25519 curve Each comes in its own sourcefile called `example_.c`. To see which functions to call to perform each operations, please read the code. diff --git a/examples/psa_crypto/app.config.test.base b/examples/psa_crypto/app.config.test.base index fe97dea42c..e411aef79d 100644 --- a/examples/psa_crypto/app.config.test.base +++ b/examples/psa_crypto/app.config.test.base @@ -6,6 +6,7 @@ CONFIG_MODULE_PSA_MAC_HMAC_SHA_256=y CONFIG_MODULE_PSA_ASYMMETRIC=y CONFIG_MODULE_PSA_ASYMMETRIC_ECC_P256R1=y +CONFIG_MODULE_PSA_ASYMMETRIC_ECC_ED25519=y -CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1 -CONFIG_PSA_SINGLE_KEY_COUNT=3 +CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=2 +CONFIG_PSA_SINGLE_KEY_COUNT=4 diff --git a/examples/psa_crypto/app.config.test.custom b/examples/psa_crypto/app.config.test.custom index e05eb8c604..ae3bbb6510 100644 --- a/examples/psa_crypto/app.config.test.custom +++ b/examples/psa_crypto/app.config.test.custom @@ -3,6 +3,7 @@ CONFIG_MODULE_PSA_CIPHER_AES_128_CBC_BACKEND_RIOT=y CONFIG_MODULE_PSA_HASH_SHA_256_BACKEND_RIOT=y CONFIG_MODULE_PSA_MAC_HMAC_SHA_256_BACKEND_RIOT=y CONFIG_MODULE_PSA_ASYMMETRIC_ECC_P256R1_BACKEND_MICROECC=y +CONFIG_MODULE_PSA_ASYMMETRIC_ECC_ED25519_BACKEND_C25519=y -CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1 -CONFIG_PSA_SINGLE_KEY_COUNT=3 +CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=2 +CONFIG_PSA_SINGLE_KEY_COUNT=4 diff --git a/examples/psa_crypto/example_ecdsa_p256.c b/examples/psa_crypto/example_ecdsa_p256.c index 54ed87941d..4f60a4916d 100644 --- a/examples/psa_crypto/example_ecdsa_p256.c +++ b/examples/psa_crypto/example_ecdsa_p256.c @@ -23,7 +23,11 @@ #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 @@ -39,26 +43,19 @@ psa_status_t example_ecdsa_p256(void) 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; - psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); - psa_algorithm_t alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256); - psa_key_bits_t bits = ECC_KEY_SIZE; - uint8_t bytes = - PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), bits); - uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR( - PSA_ECC_FAMILY_SECP_R1), - ECC_KEY_SIZE)] = { 0 }; + 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(type, bits, alg)]; + 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(PSA_ALG_SHA_256)]; + uint8_t hash[PSA_HASH_LENGTH(ECC_ALG_HASH)]; size_t hash_length; - psa_set_key_algorithm(&privkey_attr, alg); + psa_set_key_algorithm(&privkey_attr, ECC_ALG); psa_set_key_usage_flags(&privkey_attr, usage); - psa_set_key_type(&privkey_attr, type); - psa_set_key_bits(&privkey_attr, bits); + psa_set_key_type(&privkey_attr, ECC_KEY_TYPE); + psa_set_key_bits(&privkey_attr, ECC_KEY_SIZE); #ifdef SECURE_ELEMENT psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( @@ -78,7 +75,7 @@ psa_status_t example_ecdsa_p256(void) return status; } - status = psa_hash_compute(PSA_ALG_SHA_256, msg, sizeof(msg), hash, sizeof(hash), &hash_length); + status = psa_hash_compute(ECC_ALG_HASH, msg, sizeof(msg), hash, sizeof(hash), &hash_length); if (status != PSA_SUCCESS) { return status; } @@ -86,9 +83,9 @@ psa_status_t example_ecdsa_p256(void) #ifdef SECURE_ELEMENT psa_set_key_lifetime(&pubkey_attr, lifetime); #endif - psa_set_key_algorithm(&pubkey_attr, alg); - psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_HASH); - psa_set_key_bits(&pubkey_attr, PSA_BYTES_TO_BITS(bytes)); + psa_set_key_algorithm(&pubkey_attr, ECC_ALG); + psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_MESSAGE); + 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); @@ -96,13 +93,14 @@ psa_status_t example_ecdsa_p256(void) return status; } - status = psa_sign_hash(privkey_id, alg, hash, sizeof(hash), signature, sizeof(signature), + status = psa_sign_hash(privkey_id, ECC_ALG, hash, sizeof(hash), signature, sizeof(signature), &sig_length); if (status != PSA_SUCCESS) { return status; } - return psa_verify_hash(pubkey_id, alg, hash, sizeof(hash), signature, sig_length); + /* verify on original message with internal hashing operation */ + return psa_verify_message(pubkey_id, ECC_ALG, msg, sizeof(msg), signature, sig_length); } #ifdef MULTIPLE_SE @@ -116,27 +114,21 @@ psa_status_t example_ecdsa_p256_sec_se(void) psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV1); psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH; - psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); - psa_algorithm_t alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256); - psa_key_bits_t bits = 256; - uint8_t bytes = - PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), bits); - uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR( - PSA_ECC_FAMILY_SECP_R1), 256)] = { 0 }; + 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(type, bits, alg)]; + 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(PSA_ALG_SHA_256)]; + uint8_t hash[PSA_HASH_LENGTH(ECC_ALG_HASH)]; size_t hash_length; psa_set_key_lifetime(&privkey_attr, lifetime); - psa_set_key_algorithm(&privkey_attr, alg); + psa_set_key_algorithm(&privkey_attr, ECC_ALG); psa_set_key_usage_flags(&privkey_attr, usage); - psa_set_key_type(&privkey_attr, type); - psa_set_key_bits(&privkey_attr, bits); + psa_set_key_type(&privkey_attr, ECC_KEY_TYPE); + psa_set_key_bits(&privkey_attr, ECC_KEY_SIZE); psa_status_t status = PSA_ERROR_DOES_NOT_EXIST; @@ -150,15 +142,15 @@ psa_status_t example_ecdsa_p256_sec_se(void) return status; } - status = psa_hash_compute(PSA_ALG_SHA_256, msg, sizeof(msg), hash, sizeof(hash), &hash_length); + status = psa_hash_compute(ECC_ALG_HASH, msg, sizeof(msg), hash, sizeof(hash), &hash_length); if (status != PSA_SUCCESS) { return status; } psa_set_key_lifetime(&pubkey_attr, lifetime); - psa_set_key_algorithm(&pubkey_attr, alg); + psa_set_key_algorithm(&pubkey_attr, ECC_ALG); psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_HASH); - psa_set_key_bits(&pubkey_attr, PSA_BYTES_TO_BITS(bytes)); + 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); @@ -166,12 +158,12 @@ psa_status_t example_ecdsa_p256_sec_se(void) return status; } - status = psa_sign_hash(privkey_id, alg, hash, sizeof(hash), signature, sizeof(signature), + status = psa_sign_hash(privkey_id, ECC_ALG, hash, sizeof(hash), signature, sizeof(signature), &sig_length); if (status != PSA_SUCCESS) { return status; } - return psa_verify_hash(pubkey_id, alg, hash, sizeof(hash), signature, sig_length); + return psa_verify_hash(pubkey_id, ECC_ALG, hash, sizeof(hash), signature, sig_length); } #endif diff --git a/examples/psa_crypto/example_eddsa.c b/examples/psa_crypto/example_eddsa.c new file mode 100644 index 0000000000..bee9bf0d0b --- /dev/null +++ b/examples/psa_crypto/example_eddsa.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * 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 EdDSA with PSA Crypto + * + * @author Mikolai Gütschow + * + * @} + */ +#include +#include + +#include "psa/crypto.h" + +#define EDDSA_MESSAGE_SIZE (127) + +#define ECC_KEY_SIZE (255) +#define ECC_KEY_TYPE (PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS)) +#define ECC_ALG (PSA_ALG_PURE_EDDSA) + +/** + * @brief Example function to perform an EdDSA operation with the twisted Edwards curve Edwards25519 + * with the PSA Crypto API. + */ +psa_status_t example_eddsa(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_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE; + + 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[EDDSA_MESSAGE_SIZE] = { 0x0b }; + + 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_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; + } + + psa_set_key_algorithm(&pubkey_attr, ECC_ALG); + psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_bits(&pubkey_attr, PSA_BYTES_TO_BITS(pubkey_length)); + psa_set_key_type(&pubkey_attr, PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(ECC_KEY_TYPE)); + + status = psa_import_key(&pubkey_attr, public_key, pubkey_length, &pubkey_id); + if (status != PSA_SUCCESS) { + return status; + } + + status = psa_sign_message(privkey_id, ECC_ALG, msg, sizeof(msg), signature, sizeof(signature), + &sig_length); + if (status != PSA_SUCCESS) { + return status; + } + + return psa_verify_message(pubkey_id, ECC_ALG, msg, sizeof(msg), signature, sig_length); +} diff --git a/examples/psa_crypto/main.c b/examples/psa_crypto/main.c index 9a1672ffec..b146d69335 100644 --- a/examples/psa_crypto/main.c +++ b/examples/psa_crypto/main.c @@ -24,6 +24,7 @@ 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); +extern psa_status_t example_eddsa(void); #ifdef MULTIPLE_SE extern psa_status_t example_cipher_aes_128_sec_se(void); @@ -60,6 +61,13 @@ int main(void) printf("ECDSA failed: %s\n", psa_status_to_humanly_readable(status)); } + start = ztimer_now(ZTIMER_USEC); + status = example_eddsa(); + printf("EdDSA took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start)); + if (status != PSA_SUCCESS) { + printf("EdDSA failed: %s\n", psa_status_to_humanly_readable(status)); + } + #ifdef MULTIPLE_SE puts("Running Examples with secondary SE:"); status = example_hmac_sha256_sec_se(); diff --git a/kconfigs/Kconfig.features b/kconfigs/Kconfig.features index c03af6cbd9..ab84f587a1 100644 --- a/kconfigs/Kconfig.features +++ b/kconfigs/Kconfig.features @@ -228,6 +228,11 @@ config HAS_PERIPH_ECC_P256R1 help Indicates that there is ECC P256R1 hardware acceleration peripheral present. +config HAS_PERIPH_ECC_ED25519 + bool + help + Indicates that there is ECC Edwards25519 hardware acceleration peripheral present. + config HAS_PERIPH_EEPROM bool help diff --git a/pkg/c25519/Kconfig b/pkg/c25519/Kconfig index 93f7582b02..3e4fe7cf4d 100644 --- a/pkg/c25519/Kconfig +++ b/pkg/c25519/Kconfig @@ -15,3 +15,5 @@ config PACKAGE_C25519 enough that they could be reasonably considered for most microcontroller applications. In particular, Curve25519 scalar multiplication uses less than half a kB of peak stack usage. + +rsource "psa_c25519/Kconfig" diff --git a/pkg/c25519/Makefile.include b/pkg/c25519/Makefile.include index ef74e6418c..873a40b58e 100644 --- a/pkg/c25519/Makefile.include +++ b/pkg/c25519/Makefile.include @@ -1 +1,7 @@ INCLUDES += -I$(PKGDIRBASE)/c25519/src + +ifneq (,$(filter psa_c25519_%, $(USEMODULE))) + PSEUDOMODULES += psa_c25519_edsign + DIRS += $(RIOTPKG)/c25519/psa_c25519 + INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include +endif diff --git a/pkg/c25519/psa_c25519/Kconfig b/pkg/c25519/psa_c25519/Kconfig new file mode 100644 index 0000000000..dc8b8dccf5 --- /dev/null +++ b/pkg/c25519/psa_c25519/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2023 TU Dresden +# +# 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. +# + +config MODULE_PSA_C25519_EDSIGN + bool + select MODULE_PSA_C25519 + +config MODULE_PSA_C25519 + bool + depends on MODULE_PSA_CRYPTO + depends on MODULE_RANDOM diff --git a/pkg/c25519/psa_c25519/Makefile b/pkg/c25519/psa_c25519/Makefile new file mode 100644 index 0000000000..98fb23ec5a --- /dev/null +++ b/pkg/c25519/psa_c25519/Makefile @@ -0,0 +1,4 @@ +BASE_MODULE := psa_c25519 +SUBMODULES := 1 + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/c25519/psa_c25519/Makefile.dep b/pkg/c25519/psa_c25519/Makefile.dep new file mode 100644 index 0000000000..3941d5a187 --- /dev/null +++ b/pkg/c25519/psa_c25519/Makefile.dep @@ -0,0 +1 @@ +USEMODULE += random diff --git a/pkg/c25519/psa_c25519/edsign.c b/pkg/c25519/psa_c25519/edsign.c new file mode 100644 index 0000000000..51b61c6b98 --- /dev/null +++ b/pkg/c25519/psa_c25519/edsign.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * 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 sys_psa_crypto pkg_c25519 + * @{ + * + * @brief Glue code translating between PSA Crypto and the C25519 APIs + * + * @author Mikolai Gütschow + * + * @} + */ + +#include "psa/crypto.h" +#include "ed25519.h" +#include "edsign.h" +#include "random.h" + +psa_status_t psa_generate_ecc_ed25519_key_pair( uint8_t *priv_key_buffer, uint8_t *pub_key_buffer, + size_t *priv_key_buffer_length, + size_t *pub_key_buffer_length) +{ + *priv_key_buffer_length = EDSIGN_SECRET_KEY_SIZE; + *pub_key_buffer_length = EDSIGN_PUBLIC_KEY_SIZE; + + random_bytes(priv_key_buffer, EDSIGN_SECRET_KEY_SIZE); + ed25519_prepare(priv_key_buffer); + edsign_sec_to_pub(pub_key_buffer, priv_key_buffer); + + return PSA_SUCCESS; +} + +psa_status_t psa_ecc_ed25519_sign_message( const uint8_t *priv_key_buffer, + size_t priv_key_buffer_size, + const uint8_t *pub_key_buffer, + size_t pub_key_buffer_size, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length) +{ + if (signature_size < EDSIGN_SIGNATURE_SIZE) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + *signature_length = EDSIGN_SIGNATURE_SIZE; + edsign_sign(signature, pub_key_buffer, priv_key_buffer, input, input_length); + + (void)priv_key_buffer_size; + (void)pub_key_buffer_size; + return PSA_SUCCESS; +} + +psa_status_t psa_ecc_ed25519_verify_message(const uint8_t *key_buffer, + size_t key_buffer_size, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length) +{ + uint8_t ret = 0; + + if (signature_length < EDSIGN_SIGNATURE_SIZE) { + return PSA_ERROR_INVALID_SIGNATURE; + } + + ret = edsign_verify(signature, key_buffer, input, input_length); + if (!ret) { + return PSA_ERROR_GENERIC_ERROR; + } + + (void)key_buffer_size; + return PSA_SUCCESS; +} diff --git a/pkg/driver_cryptocell_310/Makefile.include b/pkg/driver_cryptocell_310/Makefile.include index dfcc0d2767..2f32616198 100644 --- a/pkg/driver_cryptocell_310/Makefile.include +++ b/pkg/driver_cryptocell_310/Makefile.include @@ -16,6 +16,7 @@ PSEUDOMODULES += psa_cryptocell_310_aes_common PSEUDOMODULES += psa_cryptocell_310_ecc_common PSEUDOMODULES += psa_cryptocell_310_ecc_p192 PSEUDOMODULES += psa_cryptocell_310_ecc_p256 +PSEUDOMODULES += psa_cryptocell_310_ecc_ed25519 PSEUDOMODULES += psa_cryptocell_310_error_conversion PSEUDOMODULES += psa_cryptocell_310_hashes_common PSEUDOMODULES += psa_cryptocell_310_hashes_sha1 diff --git a/pkg/driver_cryptocell_310/include/psa_cryptocell_310_ecc_common.h b/pkg/driver_cryptocell_310/include/psa_cryptocell_310_ecc_common.h index d3e1cc6478..e309a0324f 100644 --- a/pkg/driver_cryptocell_310/include/psa_cryptocell_310_ecc_common.h +++ b/pkg/driver_cryptocell_310/include/psa_cryptocell_310_ecc_common.h @@ -38,7 +38,7 @@ extern "C" { * * @param hash psa_algorithm_t */ -#define MAP_PSA_HASH_TO_CRYS_HASH(hash) \ +#define MAP_PSA_HASH_TO_CRYS_HASH_AFTER(hash) \ ((hash == PSA_ALG_SHA_1) ? CRYS_ECPKI_AFTER_HASH_SHA1_mode : \ (hash == PSA_ALG_SHA_224) ? CRYS_ECPKI_AFTER_HASH_SHA224_mode : \ (hash == PSA_ALG_SHA_256) ? CRYS_ECPKI_AFTER_HASH_SHA256_mode : \ @@ -46,6 +46,19 @@ extern "C" { (hash == PSA_ALG_SHA_512) ? CRYS_ECPKI_AFTER_HASH_SHA512_mode : \ 0) +/** + * @brief Map PSA hash encodings to CryptoCell specific hash encodings + * + * @param hash psa_algorithm_t + */ +#define MAP_PSA_HASH_TO_CRYS_HASH_BEFORE(hash) \ + ((hash == PSA_ALG_SHA_1) ? CRYS_ECPKI_HASH_SHA1_mode : \ + (hash == PSA_ALG_SHA_224) ? CRYS_ECPKI_HASH_SHA224_mode : \ + (hash == PSA_ALG_SHA_256) ? CRYS_ECPKI_HASH_SHA256_mode : \ + (hash == PSA_ALG_SHA_384) ? CRYS_ECPKI_HASH_SHA384_mode : \ + (hash == PSA_ALG_SHA_512) ? CRYS_ECPKI_HASH_SHA512_mode : \ + 0) + /** * @brief Common ECC key generation function * @@ -63,34 +76,34 @@ psa_status_t cryptocell_310_common_ecc_generate_key_pair(uint8_t *priv_key_buffe CRYS_ECPKI_DomainID_t domain); /** - * @brief Common ECC hash signature function + * @brief Common ECC signature function * * @param priv_key Pointer to ECC private key * @param priv_key_size Size of private key - * @param hash Hash of the message to sign - * @param hash_length Length of the message hash + * @param input Input to sign (hash or original message depending on @c hash_mode ) + * @param input_length Length of the input * @param signature Output buffer to write the generated signature * @param signature_length Pointer to store the actual length of the signature * @param hash_mode Mode used to hash the message of type @c CRYS_ECPKI_HASH_OpMode_t * @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t * @return psa_status_t */ -psa_status_t cryptocell_310_common_ecc_sign_hash(const uint8_t *priv_key, +psa_status_t cryptocell_310_common_ecc_sign(const uint8_t *priv_key, uint32_t priv_key_size, - const uint8_t *hash, - size_t hash_length, + const uint8_t *input, + size_t input_length, uint8_t *signature, size_t *signature_length, CRYS_ECPKI_HASH_OpMode_t hash_mode, CRYS_ECPKI_DomainID_t domain); /** - * @brief Common ECC hash verification function + * @brief Common ECC verification function * * @param pub_key Pointer to ECC public key * @param pub_key_size Size of public key - * @param hash Hash of the message to sign - * @param hash_length Length of the message hash + * @param input Input to verify (hash or original message depending on @c hash_mode ) + * @param input_length Length of the input * @param signature Buffer containing the signature to be verified * @param signature_length Actual length of the signature * @param hash_mode Mode used to hash the message of type @@ -98,10 +111,10 @@ psa_status_t cryptocell_310_common_ecc_sign_hash(const uint8_t *priv_key, * @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t * @return psa_status_t */ -psa_status_t cryptocell_310_common_ecc_verify_hash(const uint8_t *pub_key, +psa_status_t cryptocell_310_common_ecc_verify(const uint8_t *pub_key, size_t pub_key_size, - const uint8_t *hash, - size_t hash_length, + const uint8_t *input, + size_t input_length, const uint8_t *signature, size_t signature_length, CRYS_ECPKI_HASH_OpMode_t hash_mode, diff --git a/pkg/driver_cryptocell_310/include/psa_error.h b/pkg/driver_cryptocell_310/include/psa_error.h index 31fa7e361d..343f31973c 100644 --- a/pkg/driver_cryptocell_310/include/psa_error.h +++ b/pkg/driver_cryptocell_310/include/psa_error.h @@ -25,6 +25,7 @@ extern "C" { #include "psa/crypto.h" #include "crys_ecpki_error.h" +#include "crys_ec_mont_edw_error.h" #include "crys_hash_error.h" #include "ssi_aes_error.h" diff --git a/pkg/driver_cryptocell_310/psa_cryptocell_310/Kconfig b/pkg/driver_cryptocell_310/psa_cryptocell_310/Kconfig index f3d167dca0..9971b66cd6 100644 --- a/pkg/driver_cryptocell_310/psa_cryptocell_310/Kconfig +++ b/pkg/driver_cryptocell_310/psa_cryptocell_310/Kconfig @@ -60,6 +60,11 @@ config MODULE_PSA_CRYPTOCELL_310_ECC_P256 select MODULE_PSA_CRYPTOCELL_310 select MODULE_PSA_CRYPTOCELL_310_ECC_COMMON +config MODULE_PSA_CRYPTOCELL_310_ECC_ED25519 + bool + depends on MODULE_PSA_CRYPTO + select MODULE_PSA_CRYPTOCELL_310 + config MODULE_PSA_CRYPTOCELL_310 bool "PSA CryptoCell Wrapper" select MODULE_PSA_CRYPTOCELL_310_ERROR_CONVERSION diff --git a/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c b/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c index 5ac6bd3c2f..235d9b599f 100644 --- a/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c +++ b/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c @@ -70,10 +70,10 @@ psa_status_t cryptocell_310_common_ecc_generate_key_pair(uint8_t *priv_key_buffe return PSA_SUCCESS; } -psa_status_t cryptocell_310_common_ecc_sign_hash(const uint8_t *priv_key, +psa_status_t cryptocell_310_common_ecc_sign(const uint8_t *priv_key, uint32_t priv_key_size, - const uint8_t *hash, - size_t hash_length, + const uint8_t *input, + size_t input_length, uint8_t *signature, size_t *signature_length, CRYS_ECPKI_HASH_OpMode_t hash_mode, @@ -94,7 +94,7 @@ psa_status_t cryptocell_310_common_ecc_sign_hash(const uint8_t *priv_key, cryptocell_310_enable(); ret = CRYS_ECDSA_Sign(rndState_ptr, rndGenerateVectFunc, - &SignUserContext, &user_priv_key, hash_mode, (uint8_t *)hash, hash_length, + &SignUserContext, &user_priv_key, hash_mode, (uint8_t *)input, input_length, signature, (uint32_t *)signature_length); cryptocell_310_disable(); if (ret != CRYS_OK) { @@ -105,10 +105,10 @@ psa_status_t cryptocell_310_common_ecc_sign_hash(const uint8_t *priv_key, return PSA_SUCCESS; } -psa_status_t cryptocell_310_common_ecc_verify_hash(const uint8_t *pub_key, +psa_status_t cryptocell_310_common_ecc_verify(const uint8_t *pub_key, size_t pub_key_size, - const uint8_t *hash, - size_t hash_length, + const uint8_t *input, + size_t input_length, const uint8_t *signature, size_t signature_length, CRYS_ECPKI_HASH_OpMode_t hash_mode, @@ -132,7 +132,7 @@ psa_status_t cryptocell_310_common_ecc_verify_hash(const uint8_t *pub_key, cryptocell_310_enable(); ret = CRYS_ECDSA_Verify(&VerifyUserContext, &user_pub_key, hash_mode, (uint8_t *)signature, - signature_length, (uint8_t *)hash, hash_length); + signature_length, (uint8_t *)input, input_length); cryptocell_310_disable(); if (ret != CRYS_OK) { diff --git a/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_ed25519.c b/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_ed25519.c new file mode 100644 index 0000000000..946356f266 --- /dev/null +++ b/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_ed25519.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * 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 pkg_driver_cryptocell_310 + * @{ + * + * @file + * @brief Glue code translating between PSA Crypto and the CryptoCell 310 EC 25519 curve APIs + * + * @author Mikolai Gütschow + * + * @} + */ + +#include "crys_ec_edw_api.h" +#include "psa_error.h" +#include "cryptocell_310_util.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +extern CRYS_RND_State_t *rndState_ptr; + +psa_status_t psa_generate_ecc_ed25519_key_pair( uint8_t *priv_key_buffer, + uint8_t *pub_key_buffer, + size_t *priv_key_buffer_length, + size_t *pub_key_buffer_length) +{ + CRYS_ECEDW_TempBuff_t tmp; + CRYSError_t ret; + + /* contains seed (private key), concatenated with public key */ + uint8_t secret_key[CRYS_ECEDW_ORD_SIZE_IN_BYTES + CRYS_ECEDW_MOD_SIZE_IN_BYTES] = { 0x0 }; + size_t secret_key_size = sizeof(secret_key); + + *priv_key_buffer_length = CRYS_ECEDW_ORD_SIZE_IN_BYTES; + *pub_key_buffer_length = CRYS_ECEDW_MOD_SIZE_IN_BYTES; + + cryptocell_310_enable(); + ret = CRYS_ECEDW_KeyPair(secret_key, &secret_key_size, + pub_key_buffer, pub_key_buffer_length, + rndState_ptr, CRYS_RND_GenerateVector, &tmp); + cryptocell_310_disable(); + if (ret != CRYS_OK) { + DEBUG("CRYS_ECEDW_KeyPair failed with %s\n", cryptocell310_status_to_humanly_readable(ret)); + return CRYS_to_psa_error(ret); + } + + memcpy(priv_key_buffer, secret_key, CRYS_ECEDW_ORD_SIZE_IN_BYTES); + memcpy(pub_key_buffer, &secret_key[CRYS_ECEDW_ORD_SIZE_IN_BYTES], CRYS_ECEDW_MOD_SIZE_IN_BYTES); + + return PSA_SUCCESS; +} + +psa_status_t psa_ecc_ed25519_sign_message(const uint8_t *priv_key_buffer, + size_t priv_key_buffer_size, + const uint8_t *pub_key_buffer, + size_t pub_key_buffer_size, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length) +{ + CRYS_ECEDW_TempBuff_t tmp; + CRYSError_t ret; + + if (input_length > (CRYS_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES - CRYS_ECEDW_SIGNATURE_BYTES)) { + return PSA_ERROR_NOT_SUPPORTED; + } + + /* contains seed (private key), concatenated with public key */ + uint8_t secret_key[CRYS_ECEDW_ORD_SIZE_IN_BYTES + CRYS_ECEDW_MOD_SIZE_IN_BYTES] = { 0x0 }; + + if (priv_key_buffer_size != CRYS_ECEDW_ORD_SIZE_IN_BYTES || pub_key_buffer_size != CRYS_ECEDW_MOD_SIZE_IN_BYTES) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + memcpy(secret_key, priv_key_buffer, CRYS_ECEDW_ORD_SIZE_IN_BYTES); + memcpy(&secret_key[CRYS_ECEDW_ORD_SIZE_IN_BYTES], pub_key_buffer, CRYS_ECEDW_MOD_SIZE_IN_BYTES); + *signature_length = signature_size; + + cryptocell_310_enable(); + ret = CRYS_ECEDW_Sign(signature, signature_length, input, input_length, secret_key, sizeof(secret_key), &tmp); + cryptocell_310_disable(); + if (ret != CRYS_OK) { + DEBUG("CRYS_ECEDW_Sign failed with %s\n", cryptocell310_status_to_humanly_readable(ret)); + return CRYS_to_psa_error(ret); + } + + return PSA_SUCCESS; + + (void)signature_size; +} + +psa_status_t psa_ecc_ed25519_verify_message(const uint8_t *key_buffer, + size_t key_buffer_size, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length) +{ + CRYS_ECEDW_TempBuff_t tmp; + CRYSError_t ret; + + if (input_length > (CRYS_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES - CRYS_ECEDW_SIGNATURE_BYTES)) { + return PSA_ERROR_NOT_SUPPORTED; + } + + cryptocell_310_enable(); + ret = CRYS_ECEDW_Verify(signature, signature_length, key_buffer, key_buffer_size, (uint8_t *)input, input_length, &tmp); + cryptocell_310_disable(); + if (ret != CRYS_OK) { + DEBUG("CRYS_ECEDW_Verify failed with %s\n", cryptocell310_status_to_humanly_readable(ret)); + return CRYS_to_psa_error(ret); + } + + return PSA_SUCCESS; +} diff --git a/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p192.c b/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p192.c index 955e38a46c..f2923885c4 100644 --- a/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p192.c +++ b/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p192.c @@ -45,18 +45,40 @@ psa_status_t psa_ecc_p192r1_sign_hash( const psa_key_attributes_t *attributes, size_t signature_size, size_t *signature_length) { - CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH(PSA_ALG_GET_HASH(alg)); + CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH_AFTER(PSA_ALG_GET_HASH(alg)); (void)signature_size; (void)key_buffer_size; - return cryptocell_310_common_ecc_sign_hash(key_buffer, + return cryptocell_310_common_ecc_sign(key_buffer, PSA_BITS_TO_BYTES(attributes->bits), hash, hash_length, signature, signature_length, hash_mode, CRYS_ECPKI_DomainID_secp192r1); } +psa_status_t psa_ecc_p192r1_sign_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const uint8_t *key_buffer, + size_t key_buffer_size, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length) +{ + CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH_BEFORE(PSA_ALG_GET_HASH(alg)); + + (void)signature_size; + (void)key_buffer_size; + + return cryptocell_310_common_ecc_sign(key_buffer, + PSA_BITS_TO_BYTES(attributes->bits), + input, input_length, signature, + signature_length, hash_mode, + CRYS_ECPKI_DomainID_secp192r1); +} + psa_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes, psa_algorithm_t alg, const uint8_t *key_buffer, @@ -66,11 +88,29 @@ psa_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes, const uint8_t *signature, size_t signature_length) { - CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH(PSA_ALG_GET_HASH(alg)); + CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH_AFTER(PSA_ALG_GET_HASH(alg)); (void)attributes; - return cryptocell_310_common_ecc_verify_hash(key_buffer, key_buffer_size, + return cryptocell_310_common_ecc_verify(key_buffer, key_buffer_size, hash, hash_length, signature, signature_length, hash_mode, CRYS_ECPKI_DomainID_secp192r1); } + +psa_status_t psa_ecc_p192r1_verify_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const uint8_t *key_buffer, + size_t key_buffer_size, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length) +{ + CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH_BEFORE(PSA_ALG_GET_HASH(alg)); + + (void)attributes; + return cryptocell_310_common_ecc_verify(key_buffer, key_buffer_size, + input, input_length, signature, + signature_length, hash_mode, + CRYS_ECPKI_DomainID_secp192r1); +} diff --git a/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c b/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c index 41d5296425..a8875df26b 100644 --- a/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c +++ b/pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c @@ -46,15 +46,35 @@ psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes, size_t *signature_length) { (void)key_buffer_size; - CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH(PSA_ALG_GET_HASH(alg)); + CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH_AFTER(PSA_ALG_GET_HASH(alg)); *signature_length = signature_size; - return cryptocell_310_common_ecc_sign_hash(key_buffer, + return cryptocell_310_common_ecc_sign(key_buffer, PSA_BITS_TO_BYTES(attributes->bits), hash, hash_length, signature, signature_length, hash_mode, CRYS_ECPKI_DomainID_secp256r1); } +psa_status_t psa_ecc_p256r1_sign_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const uint8_t *key_buffer, + size_t key_buffer_size, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length) +{ + (void)key_buffer_size; + CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH_BEFORE(PSA_ALG_GET_HASH(alg)); + *signature_length = signature_size; + return cryptocell_310_common_ecc_sign(key_buffer, + PSA_BITS_TO_BYTES(attributes->bits), + input, input_length, signature, + signature_length, hash_mode, + CRYS_ECPKI_DomainID_secp256r1); +} + psa_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes, psa_algorithm_t alg, const uint8_t *key_buffer, @@ -64,11 +84,29 @@ psa_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes, const uint8_t *signature, size_t signature_length) { - CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH(PSA_ALG_GET_HASH(alg)); + CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH_AFTER(PSA_ALG_GET_HASH(alg)); (void)attributes; - return cryptocell_310_common_ecc_verify_hash(key_buffer, key_buffer_size, + return cryptocell_310_common_ecc_verify(key_buffer, key_buffer_size, hash, hash_length, signature, signature_length, hash_mode, CRYS_ECPKI_DomainID_secp256r1); } + +psa_status_t psa_ecc_p256r1_verify_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const uint8_t *key_buffer, + size_t key_buffer_size, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length) +{ + CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH_BEFORE(PSA_ALG_GET_HASH(alg)); + + (void)attributes; + return cryptocell_310_common_ecc_verify(key_buffer, key_buffer_size, + input, input_length, signature, + signature_length, hash_mode, + CRYS_ECPKI_DomainID_secp256r1); +} diff --git a/pkg/driver_cryptocell_310/psa_cryptocell_310/error_conversion.c b/pkg/driver_cryptocell_310/psa_cryptocell_310/error_conversion.c index 437f2cd997..4b8b596b55 100644 --- a/pkg/driver_cryptocell_310/psa_cryptocell_310/error_conversion.c +++ b/pkg/driver_cryptocell_310/psa_cryptocell_310/error_conversion.c @@ -28,6 +28,9 @@ psa_status_t CRYS_to_psa_error(CRYSError_t error) return PSA_ERROR_NOT_SUPPORTED; case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR: return PSA_ERROR_CORRUPTION_DETECTED; + case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR: + case CRYS_ECEDW_SIGN_VERIFY_FAILED_ERROR: + return PSA_ERROR_INVALID_SIGNATURE; case CRYS_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR: case CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR: case CRYS_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR: @@ -115,7 +118,20 @@ psa_status_t CRYS_to_psa_error(CRYSError_t error) case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR: case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR: case CRYS_HASH_CTX_SIZES_ERROR: - return PSA_ERROR_INVALID_ARGUMENT; + case CRYS_ECEDW_INVALID_INPUT_POINTER_ERROR: + case CRYS_ECEDW_INVALID_INPUT_SIZE_ERROR: + case CRYS_ECEDW_INVALID_SCALAR_SIZE_ERROR: + case CRYS_ECEDW_INVALID_SCALAR_DATA_ERROR: + case CRYS_ECEDW_RND_CONTEXT_PTR_INVALID_ERROR: + case CRYS_ECEDW_RND_GEN_VECTOR_FUNC_ERROR: + case CRYS_ECMONT_INVALID_INPUT_POINTER_ERROR: + case CRYS_ECMONT_INVALID_INPUT_SIZE_ERROR: + case CRYS_ECMONT_INVALID_DOMAIN_ID_ERROR: + case CRYS_ECEDW_PKI_ERROR: + case CRYS_ECMONT_PKI_ERROR: + case CRYS_ECMONT_IS_NOT_SUPPORTED: + case CRYS_ECEDW_IS_NOT_SUPPORTED: + return PSA_ERROR_INVALID_ARGUMENT; default: return PSA_ERROR_GENERIC_ERROR; } @@ -407,7 +423,36 @@ const char *cryptocell310_status_to_humanly_readable(uint32_t status) return "SASI_AES_IS_NOT_SUPPORTED"; case SASI_OUT_OF_RESOURCE_ERROR: return "SASI_OUT_OF_RESOURCE_ERROR"; + case CRYS_ECEDW_INVALID_INPUT_POINTER_ERROR: + return "CRYS_ECEDW_INVALID_INPUT_POINTER_ERROR"; + case CRYS_ECEDW_INVALID_INPUT_SIZE_ERROR: + return "CRYS_ECEDW_INVALID_INPUT_SIZE_ERROR"; + case CRYS_ECEDW_INVALID_SCALAR_SIZE_ERROR: + return "CRYS_ECEDW_INVALID_SCALAR_SIZE_ERROR"; + case CRYS_ECEDW_INVALID_SCALAR_DATA_ERROR: + return "CRYS_ECEDW_INVALID_SCALAR_DATA_ERROR"; + case CRYS_ECEDW_RND_CONTEXT_PTR_INVALID_ERROR: + return "CRYS_ECEDW_RND_CONTEXT_PTR_INVALID_ERROR"; + case CRYS_ECEDW_RND_GEN_VECTOR_FUNC_ERROR: + return "CRYS_ECEDW_RND_GEN_VECTOR_FUNC_ERROR"; + case CRYS_ECEDW_SIGN_VERIFY_FAILED_ERROR: + return "CRYS_ECEDW_SIGN_VERIFY_FAILED_ERROR"; + case CRYS_ECMONT_INVALID_INPUT_POINTER_ERROR: + return "CRYS_ECMONT_INVALID_INPUT_POINTER_ERROR"; + case CRYS_ECMONT_INVALID_INPUT_SIZE_ERROR: + return "CRYS_ECMONT_INVALID_INPUT_SIZE_ERROR"; + case CRYS_ECMONT_INVALID_DOMAIN_ID_ERROR: + return "CRYS_ECMONT_INVALID_DOMAIN_ID_ERROR"; + case CRYS_ECEDW_PKI_ERROR: + return "CRYS_ECEDW_PKI_ERROR"; + case CRYS_ECMONT_PKI_ERROR: + return "CRYS_ECMONT_PKI_ERROR"; + case CRYS_ECMONT_IS_NOT_SUPPORTED: + return "CRYS_ECMONT_IS_NOT_SUPPORTED"; + case CRYS_ECEDW_IS_NOT_SUPPORTED: + return "CRYS_ECEDW_IS_NOT_SUPPORTED"; default: return "Error value not recognized"; } + } diff --git a/pkg/micro-ecc/psa_uecc/p192.c b/pkg/micro-ecc/psa_uecc/p192.c index 901efa0a5a..751f714647 100644 --- a/pkg/micro-ecc/psa_uecc/p192.c +++ b/pkg/micro-ecc/psa_uecc/p192.c @@ -62,6 +62,25 @@ psa_status_t psa_ecc_p192r1_sign_hash( const psa_key_attributes_t *attributes, return PSA_SUCCESS; } +psa_status_t psa_ecc_p192r1_sign_message( const psa_key_attributes_t *attributes, + psa_algorithm_t alg, const uint8_t *key_buffer, + size_t key_buffer_size, const uint8_t *input, + size_t input_length, uint8_t *signature, + size_t signature_size, size_t *signature_length) +{ + psa_status_t status; + + uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_GET_HASH(alg))]; + size_t hash_length; + + status = psa_hash_compute(PSA_ALG_GET_HASH(alg), input, input_length, hash, sizeof(hash), &hash_length); + if (status != PSA_SUCCESS) { + return status; + } + + return psa_ecc_p192r1_sign_hash(attributes, alg, key_buffer, key_buffer_size, hash, hash_length, signature, signature_size, signature_length); +} + psa_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes, psa_algorithm_t alg, const uint8_t *key_buffer, size_t key_buffer_size, const uint8_t *hash, @@ -82,3 +101,22 @@ psa_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes, (void)signature_length; return PSA_SUCCESS; } + +psa_status_t psa_ecc_p192r1_verify_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, const uint8_t *key_buffer, + size_t key_buffer_size, const uint8_t *input, + size_t input_length, const uint8_t *signature, + size_t signature_length) +{ + psa_status_t status; + + uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_GET_HASH(alg))]; + size_t hash_length; + + status = psa_hash_compute(PSA_ALG_GET_HASH(alg), input, input_length, hash, sizeof(hash), &hash_length); + if (status != PSA_SUCCESS) { + return status; + } + + return psa_ecc_p192r1_verify_hash(attributes, alg, key_buffer, key_buffer_size, hash, hash_length, signature, signature_length); +} diff --git a/pkg/micro-ecc/psa_uecc/p256.c b/pkg/micro-ecc/psa_uecc/p256.c index 397454d23b..f07357aa28 100644 --- a/pkg/micro-ecc/psa_uecc/p256.c +++ b/pkg/micro-ecc/psa_uecc/p256.c @@ -62,6 +62,25 @@ psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes, return PSA_SUCCESS; } +psa_status_t psa_ecc_p256r1_sign_message( const psa_key_attributes_t *attributes, + psa_algorithm_t alg, const uint8_t *key_buffer, + size_t key_buffer_size, const uint8_t *input, + size_t input_length, uint8_t *signature, + size_t signature_size, size_t *signature_length) +{ + psa_status_t status; + + uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_GET_HASH(alg))]; + size_t hash_length; + + status = psa_hash_compute(PSA_ALG_GET_HASH(alg), input, input_length, hash, sizeof(hash), &hash_length); + if (status != PSA_SUCCESS) { + return status; + } + + return psa_ecc_p256r1_sign_hash(attributes, alg, key_buffer, key_buffer_size, hash, hash_length, signature, signature_size, signature_length); +} + psa_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes, psa_algorithm_t alg, const uint8_t *key_buffer, size_t key_buffer_size, const uint8_t *hash, @@ -82,3 +101,22 @@ psa_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes, (void)signature_length; return PSA_SUCCESS; } + +psa_status_t psa_ecc_p256r1_verify_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, const uint8_t *key_buffer, + size_t key_buffer_size, const uint8_t *input, + size_t input_length, const uint8_t *signature, + size_t signature_length) +{ + psa_status_t status; + + uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_GET_HASH(alg))]; + size_t hash_length; + + status = psa_hash_compute(PSA_ALG_GET_HASH(alg), input, input_length, hash, sizeof(hash), &hash_length); + if (status != PSA_SUCCESS) { + return status; + } + + return psa_ecc_p256r1_verify_hash(attributes, alg, key_buffer, key_buffer_size, hash, hash_length, signature, signature_length); +} diff --git a/sys/include/psa_crypto/psa/crypto_sizes.h b/sys/include/psa_crypto/psa/crypto_sizes.h index 701aec16f2..6fac20d386 100644 --- a/sys/include/psa_crypto/psa/crypto_sizes.h +++ b/sys/include/psa_crypto/psa/crypto_sizes.h @@ -59,6 +59,7 @@ extern "C" { */ #ifndef CONFIG_PSA_MAX_KEY_SIZE #if (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \ + IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) || \ IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || \ IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \ IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256)) @@ -838,16 +839,21 @@ extern "C" { /* implementation-defined value */ /** - * @brief Check whether the key size is a valid ECC size. + * @brief Check whether the key size is a valid ECC size for key type. * + * @param type key type of of type @ref psa_key_type_t * @param bits Key size of type @ref psa_key_bits_t */ -#define PSA_ECC_KEY_SIZE_IS_VALID(bits) \ - (bits == 128 || \ - bits == 192 || \ - bits == 224 || \ - bits == 256 || \ - bits == 384) +#define PSA_ECC_KEY_SIZE_IS_VALID(type, bits) \ + (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? \ + (bits == 255) : \ + (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_SECP_R1 ? \ + (bits == 128 || \ + bits == 192 || \ + bits == 224 || \ + bits == 256 || \ + bits == 384) : \ + 0)) /** * @brief The maximum size of an asymmetric private key. @@ -865,18 +871,45 @@ extern "C" { */ #define PSA_EXPORT_KEY_PAIR_MAX_SIZE /* implementation-defined value */ +/** + * @brief Get curve size from ECC public key + * + * @details The representation of an ECC public key is dependent on the family: + * - for twisted Edwards curves: 32B + * - for Weierstrass curves: + * - The byte 0x04; + * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; + * - `y_P` as a `ceiling(m/8)`-byte string, big-endian; + * - where m is the bit size associated with the curve. + * - 1 byte + 2 * point size. + */ +#define PSA_ECC_KEY_GET_CURVE_FROM_PUBLIC_KEY(key_type, key_bits) \ + (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 255 : \ + ((size_t)((key_bits - 8) / 2))) + +/** + * @brief Get curve size from ECC key (public or private) + */ +#define PSA_ECC_KEY_GET_CURVE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? \ + PSA_ECC_KEY_GET_CURVE_FROM_PUBLIC_KEY(key_type, key_bits) : \ + (size_t)key_bits) + /** * @brief Maximum size of the export encoding of an ECC public key. * - * @details The representation of an ECC public key is: - * - The byte 0x04; - * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; - * - `y_P` as a `ceiling(m/8)`-byte string, big-endian; - * - where m is the bit size associated with the curve. - * - 1 byte + 2 * point size. + * @details The representation of an ECC public key is dependent on the family: + * - for twisted Edwards curves: 32B + * - for Weierstrass curves: + * - The byte 0x04; + * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; + * - `y_P` as a `ceiling(m/8)`-byte string, big-endian; + * - where m is the bit size associated with the curve. + * - 1 byte + 2 * point size. */ -#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \ - ((size_t)(2 * PSA_BITS_TO_BYTES(key_bits) + 1)) +#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 32 : \ + ((size_t)(2 * PSA_BITS_TO_BYTES(key_bits) + 1))) /** * @brief Sufficient output buffer size for @ref psa_export_public_key(). @@ -919,7 +952,7 @@ extern "C" { * @ref PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(@p key_type), @p key_bits). */ #define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \ - (PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + (PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) : \ 0) /** @@ -932,8 +965,13 @@ extern "C" { * * See also @ref PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(@p key_type, @p key_bits). */ +#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1) #define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ - (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_PRIV_KEY_SIZE)) + (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_SECT_R1, PSA_MAX_PRIV_KEY_SIZE)) +#else +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ + (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_TWISTED_EDWARDS, PSA_MAX_PRIV_KEY_SIZE)) +#endif /** * @brief The maximum size of an asymmetric private key buffer. If only a secure element driver is @@ -993,7 +1031,7 @@ extern "C" { * If the parameters are not valid, the return value is unspecified. */ #define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \ - (PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \ + (PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(key_type, key_bits)) : \ ((void)alg, 0)) #ifdef __cplusplus diff --git a/sys/include/psa_crypto/psa/crypto_values.h b/sys/include/psa_crypto/psa/crypto_values.h index 8a35b8a9d7..3723d17ebe 100644 --- a/sys/include/psa_crypto/psa/crypto_values.h +++ b/sys/include/psa_crypto/psa/crypto_values.h @@ -2815,18 +2815,6 @@ extern "C" { #define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \ (PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve)) -/** - * @brief Extract group family of an elliptic curve key pair - * - * @param type A an ECC key pair type: a value of type @ref psa_key_type_t such that - * @ref PSA_KEY_TYPE_IS_ECC(@p type) is true. - * - * @return The elliptic curve family id, if type is a supported elliptic curve key. - * Unspecified if type is not a supported elliptic curve key. - */ -#define PSA_KEY_TYPE_ECC_GET_CURVE(type) \ - (type & ~PSA_KEY_TYPE_ECC_KEY_PAIR_BASE) - /** * @brief Elliptic curve public key. * diff --git a/sys/psa_crypto/Kconfig.asymmetric b/sys/psa_crypto/Kconfig.asymmetric index 6361041e23..358ba6af4e 100644 --- a/sys/psa_crypto/Kconfig.asymmetric +++ b/sys/psa_crypto/Kconfig.asymmetric @@ -58,4 +58,27 @@ endchoice endif # MODULE_PSA_ASYMMETRIC_ECC_P256R1 +menuconfig MODULE_PSA_ASYMMETRIC_ECC_ED25519 + bool "ECC Edwards25519" + select PSA_KEY_SIZE_256 + +if MODULE_PSA_ASYMMETRIC_ECC_ED25519 + +choice MODULE_PSA_ASYMMETRIC_ECC_ED25519_BACKEND + bool "ECC Edwards25519 Implementation" + +config MODULE_PSA_ASYMMETRIC_ECC_ED25519_BACKEND_PERIPH + bool "Hardware Accelerated" + depends on HAS_PERIPH_ECC_ED25519 + select MODULE_PERIPH_ECC_ED25519 + +config MODULE_PSA_ASYMMETRIC_ECC_ED25519_BACKEND_C25519 + bool "C25519 Package" + select PACKAGE_C25519 + select MODULE_PSA_C25519_EDSIGN + +endchoice + +endif # MODULE_PSA_ASYMMETRIC_ECC_ED25519 + endif # MODULE_PSA_ASYMMETRIC diff --git a/sys/psa_crypto/Makefile.dep b/sys/psa_crypto/Makefile.dep index 14e3f34ad4..be403cae6a 100644 --- a/sys/psa_crypto/Makefile.dep +++ b/sys/psa_crypto/Makefile.dep @@ -56,6 +56,30 @@ ifneq (,$(filter psa_asymmetric_ecc_p256r1_backend_periph,$(USEMODULE))) FEATURES_REQUIRED += periph_ecc_p256r1 endif +## ECC_ED25519 backend +ifneq (,$(filter psa_asymmetric_ecc_ed25519,$(USEMODULE))) + ifeq (,$(filter psa_asymmetric_ecc_ed25519_custom_backend,$(USEMODULE))) + FEATURES_OPTIONAL += periph_ecc_ed25519 + include $(RIOTMAKE)/features_check.inc.mk + # HACK: Due to kconfig migration, may cause problems + ifneq (,$(filter periph_ecc_ed25519,$(FEATURES_USED))) + USEMODULE += psa_asymmetric_ecc_ed25519_backend_periph + else + USEMODULE += psa_asymmetric_ecc_ed25519_backend_c25519 + endif + endif +endif + +ifneq (,$(filter psa_asymmetric_ecc_ed25519_backend_c25519,$(USEMODULE))) + USEPKG += c25519 + USEMODULE += psa_c25519 + USEMODULE += psa_c25519_edsign +endif + +ifneq (,$(filter psa_asymmetric_ecc_ed25519_backend_periph,$(USEMODULE))) + FEATURES_REQUIRED += periph_ecc_ed25519 +endif + # Cipher ifneq (,$(filter psa_cipher,$(USEMODULE))) USEMODULE += psa_key_slot_mgmt diff --git a/sys/psa_crypto/Makefile.include b/sys/psa_crypto/Makefile.include index 2d23d8665c..9c64f712fd 100644 --- a/sys/psa_crypto/Makefile.include +++ b/sys/psa_crypto/Makefile.include @@ -29,11 +29,23 @@ PSEUDOMODULES += psa_asymmetric_ecc_p256r1_custom_backend # check that one and only one backend has been selected ifneq (,$(filter psa_asymmetric_ecc_p256r1,$(USEMODULE))) - ifneq (1,$(call backends,psa_asymmetric_ecc_p256r1)) + ifneq (1,$(call backends, psa_asymmetric_ecc_p256r1)) $(error "One (and only one) backend should be selected for psa_asymmetric_ecc_p256r1") endif endif +PSEUDOMODULES += psa_asymmetric_ecc_ed25519 +PSEUDOMODULES += psa_asymmetric_ecc_ed25519_backend_periph +PSEUDOMODULES += psa_asymmetric_ecc_ed25519_backend_c25519 +PSEUDOMODULES += psa_asymmetric_ecc_ed25519_custom_backend + +# check that one and only one backend has been selected +ifneq (,$(filter psa_asymmetric_ecc_ed25519,$(USEMODULE))) + ifneq (1,$(call backends, psa_asymmetric_ecc_ed25519)) + $(error "One (and only one) backend should be selected for psa_asymmetric_ecc_ed25519") + endif +endif + ## Cipher PSEUDOMODULES += psa_cipher PSEUDOMODULES += psa_cipher_aes_128_ecb diff --git a/sys/psa_crypto/doc.txt b/sys/psa_crypto/doc.txt index 64ce3b4ab4..181e4fb1f9 100644 --- a/sys/psa_crypto/doc.txt +++ b/sys/psa_crypto/doc.txt @@ -248,6 +248,12 @@ * - psa_asymmetric_ecc_p256r1_custom_backend * - psa_asymmetric_ecc_p256r1_backend_microecc * + * #### Ed25519 + * - psa_asymmetric_ecc_ed25519 + * - psa_asymmetric_ecc_ed25519_backend_periph + * - psa_asymmetric_ecc_ed25519_custom_backend + * - psa_asymmetric_ecc_ed25519_backend_c25519 + * * ### Ciphers * - Base: psa_cipher * diff --git a/sys/psa_crypto/include/psa_crypto_algorithm_dispatch.h b/sys/psa_crypto/include/psa_crypto_algorithm_dispatch.h index 3e70dd5335..e17be73419 100644 --- a/sys/psa_crypto/include/psa_crypto_algorithm_dispatch.h +++ b/sys/psa_crypto/include/psa_crypto_algorithm_dispatch.h @@ -92,6 +92,29 @@ psa_status_t psa_algorithm_dispatch_sign_hash( const psa_key_attributes_t *attr size_t signature_size, size_t *signature_length); +/** + * @brief Dispatch a message signature function to a specific backend. + * See @ref psa_sign_message() + * + * @param attributes + * @param alg + * @param slot + * @param input + * @param input_length + * @param signature + * @param signature_size + * @param signature_length + * @return @ref psa_status_t + */ +psa_status_t psa_algorithm_dispatch_sign_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const psa_key_slot_t *slot, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length); + /** * @brief Dispatch a hash verification function to a specific backend. * See @ref psa_verify_hash() @@ -113,6 +136,27 @@ psa_status_t psa_algorithm_dispatch_verify_hash( const psa_key_attributes_t *at const uint8_t *signature, size_t signature_length); +/** + * @brief Dispatch a message verification function to a specific backend. + * See @ref psa_verify_message() + * + * @param attributes + * @param alg + * @param slot + * @param input + * @param input_length + * @param signature + * @param signature_length + * @return @ref psa_status_t + */ +psa_status_t psa_algorithm_dispatch_verify_message( const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const psa_key_slot_t *slot, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length); + /** * @brief Dispatch the key generation function to a specific backend. * See @ref psa_generate_key() diff --git a/sys/psa_crypto/include/psa_crypto_location_dispatch.h b/sys/psa_crypto/include/psa_crypto_location_dispatch.h index a6ff3c7099..4ec493fd01 100644 --- a/sys/psa_crypto/include/psa_crypto_location_dispatch.h +++ b/sys/psa_crypto/include/psa_crypto_location_dispatch.h @@ -52,6 +52,29 @@ psa_status_t psa_location_dispatch_sign_hash( const psa_key_attributes_t *attri size_t signature_size, size_t *signature_length); +/** + * @brief Dispatch call of a message signature function to a location specific backend. + * See psa_sign_message() + * + * @param attributes + * @param alg + * @param slot + * @param input + * @param input_length + * @param signature + * @param signature_size + * @param signature_length + * @return psa_status_t + */ +psa_status_t psa_location_dispatch_sign_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const psa_key_slot_t *slot, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length); + /** * @brief Dispatch call of a hash verification function to a location specific backend. * See psa_verify_hash() @@ -73,6 +96,27 @@ psa_status_t psa_location_dispatch_verify_hash( const psa_key_attributes_t *att const uint8_t *signature, size_t signature_length); +/** + * @brief Dispatch call of a message verification function to a location specific backend. + * See psa_verify_message() + * + * @param attributes + * @param alg + * @param slot + * @param input + * @param input_length + * @param signature + * @param signature_length + * @return psa_status_t + */ +psa_status_t psa_location_dispatch_verify_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const psa_key_slot_t *slot, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length); + /** * @brief Dispatch call of a mac computation function to a location specific backend. * See psa_mac_compute() diff --git a/sys/psa_crypto/include/psa_crypto_operation_encoder.h b/sys/psa_crypto/include/psa_crypto_operation_encoder.h index bcac6c80fa..6ddd7b042e 100644 --- a/sys/psa_crypto/include/psa_crypto_operation_encoder.h +++ b/sys/psa_crypto/include/psa_crypto_operation_encoder.h @@ -11,7 +11,7 @@ * @{ * * @file psa_crypto_operation_encoder.h - * @brief Macros used to map PSA akgorithms, key types and key sizes to specific key types + * @brief Macros used to map PSA algorithms, key types and key sizes to specific key types * and operations to call the corresponding driver functions. * * @note Currently this only supports a small number of operations. It should be expanded as @@ -66,36 +66,36 @@ typedef enum { PSA_ECC_P384_R1, PSA_ECC_P521_R1, PSA_ECC_FRP, - PSA_ECMONT_255, - PSA_ECMONT_448 + PSA_ECC_ED25519, } psa_asym_key_t; /** - * @brief Combine an ECC 192 key type with a given curve. + * @brief Combine a SECP_R1 key type with a given key size (private or public key). * - * @param curve Must be a curve of type @ref psa_ecc_family_t + * @param bits Key size of type @ref psa_key_bits_t * * @return @ref psa_asym_key_t - * @return @ref PSA_INVALID_OPERATION @c curve is not compatible with key size + * @return @ref PSA_INVALID_OPERATION @c bits is not compatible with SECP_R1 curves */ -#define GET_ECC_KEY_TYPE_192(curve) \ - ((curve == PSA_ECC_FAMILY_SECP_R1) ? PSA_ECC_P192_R1 : \ +#define PSA_ENCODE_ECC_KEY_TYPE_SECPR1(bits) \ + ((bits == 256) || (bits == 520) ? PSA_ECC_P256_R1 : \ + (bits == 192) || (bits == 392) ? PSA_ECC_P192_R1 : \ PSA_INVALID_OPERATION) /** - * @brief Combine an ECC 265 key type with a given curve. + * @brief Combine a Twisted Edwards key type with a given key size (private or public key). * - * @param curve Must be a curve of type @ref psa_ecc_family_t + * @param bits Key size of type @ref psa_key_bits_t * * @return @ref psa_asym_key_t - * @return @ref PSA_INVALID_OPERATION @c curve is not compatible with key size + * @return @ref PSA_INVALID_OPERATION @c bits is not compatible with Twisted Edwards curves */ -#define GET_ECC_KEY_TYPE_256(curve) \ - ((curve == PSA_ECC_FAMILY_SECP_R1) ? PSA_ECC_P256_R1 : \ +#define PSA_ENCODE_ECC_KEY_TYPE_EDWARDS(bits) \ + ((bits == 255) || (bits == 256) ? PSA_ECC_ED25519 : \ PSA_INVALID_OPERATION) /** - * @brief Map an ECC 192 key to a given curve according to its type and size. + * @brief Map an ECC key to a given curve according to its type and size. * * @param bits Key size of type @ref psa_key_bits_t * @param curve Must be a curve of type @ref psa_ecc_family_t @@ -104,8 +104,8 @@ typedef enum { * @return @ref PSA_INVALID_OPERATION @c curve and @c bits are incompatible */ #define PSA_ENCODE_ECC_KEY_TYPE(bits, curve) \ - ((bits == 256) || (bits == 520) ? GET_ECC_KEY_TYPE_256(curve) : \ - (bits == 192) || (bits == 392) ? GET_ECC_KEY_TYPE_192(curve) : \ + ((curve == PSA_ECC_FAMILY_SECP_R1) ? PSA_ENCODE_ECC_KEY_TYPE_SECPR1(bits) : \ + (curve == PSA_ECC_FAMILY_TWISTED_EDWARDS) ? PSA_ENCODE_ECC_KEY_TYPE_EDWARDS(bits) : \ PSA_INVALID_OPERATION) /** diff --git a/sys/psa_crypto/include/psa_crypto_slot_management.h b/sys/psa_crypto/include/psa_crypto_slot_management.h index 27febefcfb..169faf2d6f 100644 --- a/sys/psa_crypto/include/psa_crypto_slot_management.h +++ b/sys/psa_crypto/include/psa_crypto_slot_management.h @@ -80,7 +80,7 @@ typedef struct { /** Structure containing key data */ struct key_data { uint8_t data[PSA_MAX_KEY_DATA_SIZE]; /**< Key data buffer */ - size_t data_len; /**< Size of actual key data in bytes */ + size_t data_len; /**< Size of actual key data in bytes */ } key; /**< Key data structure */ } psa_key_slot_t; diff --git a/sys/psa_crypto/include/psa_ecc.h b/sys/psa_crypto/include/psa_ecc.h index d995b821cb..70639a45c0 100644 --- a/sys/psa_crypto/include/psa_ecc.h +++ b/sys/psa_crypto/include/psa_ecc.h @@ -45,26 +45,6 @@ psa_status_t psa_generate_ecc_p192r1_key_pair( const psa_key_attributes_t *attr size_t *priv_key_buffer_length, size_t *pub_key_buffer_length); -/** - * @brief Low level wrapper function to call a driver for an ECC public key export - * of a SECP 192 R1 key. - * See @ref psa_export_public_key() - * - * @param attributes - * @param key_buffer - * @param key_buffer_size - * @param data - * @param data_size - * @param data_length - * @return psa_status_t - */ -psa_status_t psa_ecc_p192r1_export_public_key( const psa_key_attributes_t *attributes, - uint8_t *key_buffer, - size_t key_buffer_size, - uint8_t *data, - size_t data_size, - size_t *data_length); - /** * @brief Low level wrapper function to call a driver for an ECC hash signature * with a SECP 192 R1 key. @@ -88,6 +68,29 @@ psa_status_t psa_ecc_p192r1_sign_hash( const psa_key_attributes_t *attributes, uint8_t *signature, size_t signature_size, size_t *signature_length); +/** + * @brief Low level wrapper function to call a driver for an ECC hash signature + * with a SECP 192 R1 key. + * See @ref psa_sign_message() + * + * @param attributes + * @param alg + * @param key_buffer + * @param key_buffer_size + * @param input + * @param input_length + * @param signature + * @param signature_size + * @param signature_length + * @return psa_status_t + */ +psa_status_t psa_ecc_p192r1_sign_message( const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const uint8_t *key_buffer, size_t key_buffer_size, + const uint8_t *input, size_t input_length, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + /** * @brief Low level wrapper function to call a driver for an ECC hash verification * with a SECP 192 R1 key. @@ -109,6 +112,27 @@ psa_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes, const uint8_t *hash, size_t hash_length, const uint8_t *signature, size_t signature_length); +/** + * @brief Low level wrapper function to call a driver for an ECC hash verification + * with a SECP 192 R1 key. + * See @ref psa_verify_message() + * + * @param attributes + * @param alg + * @param key_buffer + * @param key_buffer_size + * @param input + * @param input_length + * @param signature + * @param signature_length + * @return psa_status_t + */ +psa_status_t psa_ecc_p192r1_verify_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const uint8_t *key_buffer, size_t key_buffer_size, + const uint8_t *input, size_t input_length, + const uint8_t *signature, size_t signature_length); + /** * @brief Low level wrapper function to call a driver for an ECC key generation * with a SECP 192 R1 key. @@ -126,26 +150,6 @@ psa_status_t psa_generate_ecc_p256r1_key_pair( const psa_key_attributes_t *attr size_t *priv_key_buffer_length, size_t *pub_key_buffer_length); -/** - * @brief Low level wrapper function to call a driver for an ECC public key export - * of a SECP 256 R1 key. - * See @ref psa_export_public_key() - * - * @param attributes - * @param key_buffer - * @param key_buffer_size - * @param data - * @param data_size - * @param data_length - * @return psa_status_t - */ -psa_status_t psa_ecc_p256r1_export_public_key( const psa_key_attributes_t *attributes, - uint8_t *key_buffer, - size_t key_buffer_size, - uint8_t *data, - size_t data_size, - size_t *data_length); - /** * @brief Low level wrapper function to call a driver for an ECC hash signature * with a SECP 256 R1 key. @@ -169,6 +173,29 @@ psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes, uint8_t *signature, size_t signature_size, size_t *signature_length); +/** + * @brief Low level wrapper function to call a driver for an ECC hash signature + * with a SECP 256 R1 key. + * See @ref psa_sign_message() + * + * @param attributes + * @param alg + * @param key_buffer + * @param key_buffer_size + * @param input + * @param input_length + * @param signature + * @param signature_size + * @param signature_length + * @return psa_status_t + */ +psa_status_t psa_ecc_p256r1_sign_message( const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const uint8_t *key_buffer, size_t key_buffer_size, + const uint8_t *input, size_t input_length, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + /** * @brief Low level wrapper function to call a driver for an ECC hash verification * with a SECP 256 R1 key. @@ -190,6 +217,83 @@ psa_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes, const uint8_t *hash, size_t hash_length, const uint8_t *signature, size_t signature_length); +/** + * @brief Low level wrapper function to call a driver for an ECC hash verification + * with a SECP 256 R1 key. + * See @ref psa_verify_message() + * + * @param attributes + * @param alg + * @param key_buffer + * @param key_buffer_size + * @param input + * @param input_length + * @param signature + * @param signature_length + * @return psa_status_t + */ +psa_status_t psa_ecc_p256r1_verify_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const uint8_t *key_buffer, size_t key_buffer_size, + const uint8_t *input, size_t input_length, + const uint8_t *signature, size_t signature_length); + +/** + * @brief Low level wrapper function to call a driver for an ECC key generation + * with an ed25519 key. + * See @ref psa_generate_key() + * + * @param priv_key_buffer + * @param pub_key_buffer + * @param priv_key_buffer_length + * @param pub_key_buffer_length + * @return @ref psa_status_t + */ +psa_status_t psa_generate_ecc_ed25519_key_pair( uint8_t *priv_key_buffer, uint8_t *pub_key_buffer, + size_t *priv_key_buffer_length, + size_t *pub_key_buffer_length); + +/** + * @brief Low level wrapper function to call a driver for an ECC hash signature + * with an ed25519 key. + * See @ref psa_sign_message() + * + * @param priv_key_buffer + * @param priv_key_buffer_size + * @param pub_key_buffer + * @param pub_key_buffer_size + * @param input + * @param input_length + * @param signature + * @param signature_size + * @param signature_length + * @return psa_status_t + */ +psa_status_t psa_ecc_ed25519_sign_message(const uint8_t *priv_key_buffer, + size_t priv_key_buffer_size, + const uint8_t *pub_key_buffer, + size_t pub_key_buffer_size, + const uint8_t *input, size_t input_length, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + +/** + * @brief Low level wrapper function to call a driver for an ECC hash verification + * with a ed25519 key. + * See @ref psa_verify_message() + * + * @param key_buffer + * @param key_buffer_size + * @param input + * @param input_length + * @param signature + * @param signature_length + * @return psa_status_t + */ +psa_status_t psa_ecc_ed25519_verify_message(const uint8_t *key_buffer, size_t key_buffer_size, + const uint8_t *input, size_t input_length, + const uint8_t *signature, size_t signature_length); + #ifdef __cplusplus } #endif diff --git a/sys/psa_crypto/psa_crypto.c b/sys/psa_crypto/psa_crypto.c index ef7158b7b3..af0a9dab4c 100644 --- a/sys/psa_crypto/psa_crypto.c +++ b/sys/psa_crypto/psa_crypto.c @@ -992,7 +992,7 @@ static psa_status_t psa_validate_key_for_key_generation(psa_key_type_t type, siz } #if IS_USED(MODULE_PSA_ASYMMETRIC) || IS_USED(MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC) else if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { - return PSA_ECC_KEY_SIZE_IS_VALID(bits) ? PSA_SUCCESS : PSA_ERROR_INVALID_ARGUMENT; + return PSA_ECC_KEY_SIZE_IS_VALID(type, bits) ? PSA_SUCCESS : PSA_ERROR_INVALID_ARGUMENT; } #endif /* TODO: add validation for other key types */ @@ -1329,8 +1329,6 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, if (status != PSA_SUCCESS) { return status; } - - slot->key.data_len = PSA_MAX_KEY_DATA_SIZE; } status = psa_location_dispatch_generate_key(attributes, slot); @@ -1804,7 +1802,7 @@ psa_status_t psa_sign_hash(psa_key_id_t key, return PSA_ERROR_NOT_SUPPORTED; } - if (hash_length != PSA_HASH_LENGTH(alg)) { + if (!PSA_ALG_IS_SIGN_HASH(alg) || hash_length != PSA_HASH_LENGTH(alg)) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -1814,7 +1812,7 @@ psa_status_t psa_sign_hash(psa_key_id_t key, return status; } - if (signature_size < PSA_SIGN_OUTPUT_SIZE(slot->attr.type, slot->attr.bits, alg)) { + if (signature_size < PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) { return PSA_ERROR_BUFFER_TOO_SMALL; } @@ -1840,14 +1838,49 @@ psa_status_t psa_sign_message(psa_key_id_t key, size_t signature_size, size_t *signature_length) { - (void)key; - (void)alg; - (void)input; - (void)input_length; - (void)signature; - (void)signature_size; - (void)signature_length; - return PSA_ERROR_NOT_SUPPORTED; + + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; + + if (!lib_initialized) { + return PSA_ERROR_BAD_STATE; + } + + if (!input || !signature || !signature_length) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (!PSA_ALG_IS_ECDSA(alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } + + if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + status = psa_get_and_lock_key_slot_with_policy(key, &slot, PSA_KEY_USAGE_SIGN_MESSAGE, alg); + if (status != PSA_SUCCESS) { + unlock_status = psa_unlock_key_slot(slot); + return status; + } + + if (signature_size < PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) { + unlock_status = psa_unlock_key_slot(slot); + return PSA_ERROR_INVALID_ARGUMENT; + } + + psa_key_attributes_t attributes = slot->attr; + + status = psa_location_dispatch_sign_message(&attributes, alg, slot, input, input_length, signature, + signature_size, signature_length); + + unlock_status = psa_unlock_key_slot(slot); + return ((status == PSA_SUCCESS) ? unlock_status : status); } psa_status_t psa_verify_hash(psa_key_id_t key, @@ -1873,7 +1906,7 @@ psa_status_t psa_verify_hash(psa_key_id_t key, return PSA_ERROR_NOT_SUPPORTED; } - if (hash_length != PSA_HASH_LENGTH(alg)) { + if (!PSA_ALG_IS_SIGN_HASH(alg) || hash_length != PSA_HASH_LENGTH(alg)) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -1883,14 +1916,7 @@ psa_status_t psa_verify_hash(psa_key_id_t key, return status; } - /** - * An ECC public key has the size `curve_bytes * 2 + 1`. - * So to get the curve size to determine the required signature - * size, we need to revert that calculation. - */ - uint16_t curve_size = PSA_BYTES_TO_BITS(PSA_BITS_TO_BYTES(slot->attr.bits / 2) - 1); - - if (signature_length != PSA_ECDSA_SIGNATURE_SIZE(curve_size)) { + if (signature_length != PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -1921,11 +1947,52 @@ psa_status_t psa_verify_message(psa_key_id_t key, const uint8_t *signature, size_t signature_length) { - (void)key; - (void)alg; - (void)input; - (void)input_length; - (void)signature; - (void)signature_length; - return PSA_ERROR_NOT_SUPPORTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; + + if (!lib_initialized) { + return PSA_ERROR_BAD_STATE; + } + + if (!input || !signature) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (!PSA_ALG_IS_ECDSA(alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } + + if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + status = psa_get_and_lock_key_slot_with_policy(key, &slot, PSA_KEY_USAGE_VERIFY_MESSAGE, alg); + if (status != PSA_SUCCESS) { + unlock_status = psa_unlock_key_slot(slot); + return status; + } + + if (signature_length != PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + /** + * When key location is a secure element, this implementation only supports + * the use of public keys stored on the secure element, not key pairs in + * which the public key is stored locally. + */ + if ((PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime) != PSA_KEY_LOCATION_LOCAL_STORAGE) && + PSA_KEY_TYPE_IS_ECC_KEY_PAIR(slot->attr.type)) { + unlock_status = psa_unlock_key_slot(slot); + return PSA_ERROR_NOT_SUPPORTED; + } + + psa_key_attributes_t attributes = slot->attr; + + status = psa_location_dispatch_verify_message(&attributes, alg, slot, input, input_length, signature, + signature_length); + + unlock_status = psa_unlock_key_slot(slot); + return ((status == PSA_SUCCESS) ? unlock_status : status); } diff --git a/sys/psa_crypto/psa_crypto_algorithm_dispatch.c b/sys/psa_crypto/psa_crypto_algorithm_dispatch.c index caf5cda7d7..44c2f0532d 100644 --- a/sys/psa_crypto/psa_crypto_algorithm_dispatch.c +++ b/sys/psa_crypto/psa_crypto_algorithm_dispatch.c @@ -163,10 +163,12 @@ psa_status_t psa_algorithm_dispatch_sign_hash( const psa_key_attributes_t *attr psa_asym_key_t asym_key = PSA_INVALID_OPERATION; uint8_t *key_data = NULL; size_t *key_bytes = NULL; + uint8_t *pub_key_data = NULL; + size_t *pub_key_bytes = NULL; if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) { asym_key = - PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, PSA_KEY_TYPE_ECC_GET_CURVE(attributes->type)); + PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)); if (asym_key == PSA_INVALID_OPERATION) { return PSA_ERROR_INVALID_ARGUMENT; @@ -194,6 +196,65 @@ psa_status_t psa_algorithm_dispatch_sign_hash( const psa_key_attributes_t *attr (void)signature; (void)signature_size; (void)signature_length; + (void)pub_key_data; + (void)pub_key_bytes; + return PSA_ERROR_NOT_SUPPORTED; + } +} + +psa_status_t psa_algorithm_dispatch_sign_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const psa_key_slot_t *slot, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length) +{ + psa_asym_key_t asym_key = PSA_INVALID_OPERATION; + uint8_t *key_data = NULL; + size_t *key_bytes = NULL; + uint8_t *pub_key_data = NULL; + size_t *pub_key_bytes = NULL; + + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) { + asym_key = + PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)); + + if (asym_key == PSA_INVALID_OPERATION) { + return PSA_ERROR_INVALID_ARGUMENT; + } + } + + psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes); + + switch (asym_key) { +#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1) + case PSA_ECC_P192_R1: + return psa_ecc_p192r1_sign_message(attributes, alg, key_data, *key_bytes, input, input_length, + signature, signature_size, signature_length); +#endif +#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) + case PSA_ECC_P256_R1: + return psa_ecc_p256r1_sign_message(attributes, alg, key_data, *key_bytes, input, input_length, + signature, signature_size, signature_length); +#endif +#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) + case PSA_ECC_ED25519: + psa_get_public_key_data_from_key_slot(slot, &pub_key_data, &pub_key_bytes); + return psa_ecc_ed25519_sign_message(key_data, *key_bytes, pub_key_data, *pub_key_bytes, input, input_length, + signature, signature_size, signature_length); +#endif + default: + (void)alg; + (void)slot; + (void)input; + (void)input_length; + (void)signature; + (void)signature_size; + (void)signature_length; + (void)pub_key_data; + (void)pub_key_bytes; return PSA_ERROR_NOT_SUPPORTED; } } @@ -212,7 +273,7 @@ psa_status_t psa_algorithm_dispatch_verify_hash( const psa_key_attributes_t *at if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { asym_key = - PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, PSA_KEY_TYPE_ECC_GET_CURVE(attributes->type)); + PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)); if (asym_key == PSA_INVALID_OPERATION) { return PSA_ERROR_INVALID_ARGUMENT; @@ -243,6 +304,56 @@ psa_status_t psa_algorithm_dispatch_verify_hash( const psa_key_attributes_t *at } } +psa_status_t psa_algorithm_dispatch_verify_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const psa_key_slot_t *slot, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length) +{ + psa_asym_key_t asym_key = PSA_INVALID_OPERATION; + uint8_t *pubkey_data = NULL; + size_t *pubkey_data_len = NULL; + + if (PSA_KEY_TYPE_IS_ECC(attributes->type)) { + asym_key = + PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)); + + if (asym_key == PSA_INVALID_OPERATION) { + return PSA_ERROR_INVALID_ARGUMENT; + } + } + + psa_get_public_key_data_from_key_slot(slot, &pubkey_data, &pubkey_data_len); + + switch (asym_key) { +#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1) + case PSA_ECC_P192_R1: + return psa_ecc_p192r1_verify_message(attributes, alg, pubkey_data, *pubkey_data_len, input, + input_length, signature, signature_length); +#endif +#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) + case PSA_ECC_P256_R1: + return psa_ecc_p256r1_verify_message(attributes, alg, pubkey_data, *pubkey_data_len, input, + input_length, signature, signature_length); +#endif +#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) + case PSA_ECC_ED25519: + return psa_ecc_ed25519_verify_message(pubkey_data, *pubkey_data_len, input, + input_length, signature, signature_length); +#endif + default: + (void)alg; + (void)slot; + (void)input; + (void)input_length; + (void)signature; + (void)signature_length; + return PSA_ERROR_NOT_SUPPORTED; + } +} + psa_status_t psa_algorithm_dispatch_generate_key( const psa_key_attributes_t *attributes, psa_key_slot_t *slot) { @@ -265,7 +376,7 @@ psa_status_t psa_algorithm_dispatch_generate_key( const psa_key_attributes_t * if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) { asym_key = PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, - PSA_KEY_TYPE_ECC_GET_CURVE(attributes->type)); + PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)); if (asym_key == PSA_INVALID_OPERATION) { return PSA_ERROR_INVALID_ARGUMENT; @@ -282,6 +393,10 @@ psa_status_t psa_algorithm_dispatch_generate_key( const psa_key_attributes_t * case PSA_ECC_P256_R1: return psa_generate_ecc_p256r1_key_pair(attributes, key_data, pubkey_data, key_bytes, pubkey_data_len); +#endif +#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) + case PSA_ECC_ED25519: + return psa_generate_ecc_ed25519_key_pair(key_data, pubkey_data, key_bytes, pubkey_data_len); #endif default: (void)status; diff --git a/sys/psa_crypto/psa_crypto_location_dispatch.c b/sys/psa_crypto/psa_crypto_location_dispatch.c index c5d03c55c6..367de7afe0 100644 --- a/sys/psa_crypto/psa_crypto_location_dispatch.c +++ b/sys/psa_crypto/psa_crypto_location_dispatch.c @@ -368,6 +368,21 @@ psa_status_t psa_location_dispatch_sign_hash( const psa_key_attributes_t *attri signature_size, signature_length); } +psa_status_t psa_location_dispatch_sign_message(const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const psa_key_slot_t *slot, + const uint8_t *input, + size_t input_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length) +{ + /* TODO: implement MODULE_PSA_SECURE_ELEMENT support */ + + return psa_algorithm_dispatch_sign_message(attributes, alg, slot, input, input_length, signature, + signature_size, signature_length); +} + psa_status_t psa_location_dispatch_verify_hash(const psa_key_attributes_t *attributes, psa_algorithm_t alg, const psa_key_slot_t *slot, @@ -400,6 +415,20 @@ psa_status_t psa_location_dispatch_verify_hash(const psa_key_attributes_t *attri signature_length); } +psa_status_t psa_location_dispatch_verify_message( const psa_key_attributes_t *attributes, + psa_algorithm_t alg, + const psa_key_slot_t *slot, + const uint8_t *input, + size_t input_length, + const uint8_t *signature, + size_t signature_length) +{ + /* TODO: implement MODULE_PSA_SECURE_ELEMENT support */ + + return psa_algorithm_dispatch_verify_message(attributes, alg, slot, input, input_length, signature, + signature_length); +} + psa_status_t psa_location_dispatch_mac_compute(const psa_key_attributes_t *attributes, psa_algorithm_t alg, const psa_key_slot_t *slot,