1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys/psa_crypto: add support for Ed25519 (EdDSA)

This commit is contained in:
Mikolai Gütschow 2023-09-25 17:19:32 +02:00
parent dd62f419d7
commit 963775bdd9
No known key found for this signature in database
GPG Key ID: 943E2F37AA659AD5
43 changed files with 1250 additions and 194 deletions

View File

@ -77,6 +77,7 @@ config CPU_MODEL_NRF52840XXAA
select HAS_PERIPH_CIPHER_AES_128_CBC select HAS_PERIPH_CIPHER_AES_128_CBC
select HAS_PERIPH_ECC_P192R1 select HAS_PERIPH_ECC_P192R1
select HAS_PERIPH_ECC_P256R1 select HAS_PERIPH_ECC_P256R1
select HAS_PERIPH_ECC_ED25519
select HAS_PERIPH_CRYPTOCELL_310 select HAS_PERIPH_CRYPTOCELL_310
## CPU common symbols ## CPU common symbols

View File

@ -20,6 +20,7 @@ ifneq (,$(filter nrf52840xxaa,$(CPU_MODEL)))
FEATURES_PROVIDED += periph_cipher_aes_128_cbc FEATURES_PROVIDED += periph_cipher_aes_128_cbc
FEATURES_PROVIDED += periph_ecc_p192r1 FEATURES_PROVIDED += periph_ecc_p192r1
FEATURES_PROVIDED += periph_ecc_p256r1 FEATURES_PROVIDED += periph_ecc_p256r1
FEATURES_PROVIDED += periph_ecc_ed25519
endif endif
ifeq (,$(filter nrf52832%,$(CPU_MODEL))) ifeq (,$(filter nrf52832%,$(CPU_MODEL)))

View File

@ -30,6 +30,12 @@ config MODULE_PERIPH_ECC_P256R1
select MODULE_PERIPH_CRYPTOCELL_310 select MODULE_PERIPH_CRYPTOCELL_310
select MODULE_PSA_CRYPTOCELL_310_ECC_P256 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 # Hash Related Symbols
config MODULE_PERIPH_HASH_SHA_1 config MODULE_PERIPH_HASH_SHA_1
bool bool

View File

@ -8,6 +8,11 @@ ifneq (,$(filter periph_ecc_p256r1,$(USEMODULE)))
USEMODULE += psa_cryptocell_310_ecc_p256 USEMODULE += psa_cryptocell_310_ecc_p256
endif 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))) ifneq (,$(filter periph_hash_sha_1,$(USEMODULE)))
USEPKG += driver_cryptocell_310 USEPKG += driver_cryptocell_310
USEMODULE += psa_cryptocell_310_hashes_sha1 USEMODULE += psa_cryptocell_310_hashes_sha1

View File

@ -63,7 +63,7 @@ else
USEMODULE += psa_secure_element_ateccx08a_ecc_p256 USEMODULE += psa_secure_element_ateccx08a_ecc_p256
else ifdef CUSTOM_BACKEND else ifdef CUSTOM_BACKEND
# Necessary configuration when using Make dependency resolution # 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. # a default backend is built depending on the platform capabilities.
USEMODULE += psa_cipher USEMODULE += psa_cipher
USEMODULE += psa_cipher_aes_128_cbc USEMODULE += psa_cipher_aes_128_cbc
@ -73,6 +73,7 @@ else
USEMODULE += psa_asymmetric USEMODULE += psa_asymmetric
USEMODULE += psa_asymmetric_ecc_p256r1 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. # If you want to use a custom backend, you need to do it this way.
USEMODULE += psa_cipher_aes_128_cbc_custom_backend 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_custom_backend
USEMODULE += psa_asymmetric_ecc_p256r1_backend_microecc # force 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 else
# Necessary configuration when using Make dependency resolution # Necessary configuration when using Make dependency resolution
# This part only chooses the operation. If nothing else es specified, # This part only chooses the operation. If nothing else es specified,
@ -98,11 +102,12 @@ else
USEMODULE += psa_asymmetric USEMODULE += psa_asymmetric
USEMODULE += psa_asymmetric_ecc_p256r1 USEMODULE += psa_asymmetric_ecc_p256r1
USEMODULE += psa_asymmetric_ecc_ed25519
endif endif
ifndef SECURE_ELEMENT ifndef SECURE_ELEMENT
CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1 CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=2
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=3 CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=4
endif endif
endif endif

View File

@ -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 2. How to configure the implementation with Kconfig dependency resolution vs. Make dependency resolution
## Basic usage of PSA Crypto ## Basic usage of PSA Crypto
There are three example operations: There are four example operations:
- AES 128 CBC - AES 128 CBC
- HMAC SHA256 - HMAC SHA256
- ECDSA with a P256 curve - ECDSA with a P256 curve
- EdDSA with the Ed25519 curve
Each comes in its own sourcefile called `example_<operation>.c`. To see which functions to call to perform each operations, please read the code. Each comes in its own sourcefile called `example_<operation>.c`. To see which functions to call to perform each operations, please read the code.

View File

@ -6,6 +6,7 @@ CONFIG_MODULE_PSA_MAC_HMAC_SHA_256=y
CONFIG_MODULE_PSA_ASYMMETRIC=y CONFIG_MODULE_PSA_ASYMMETRIC=y
CONFIG_MODULE_PSA_ASYMMETRIC_ECC_P256R1=y CONFIG_MODULE_PSA_ASYMMETRIC_ECC_P256R1=y
CONFIG_MODULE_PSA_ASYMMETRIC_ECC_ED25519=y
CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1 CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=2
CONFIG_PSA_SINGLE_KEY_COUNT=3 CONFIG_PSA_SINGLE_KEY_COUNT=4

View File

@ -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_HASH_SHA_256_BACKEND_RIOT=y
CONFIG_MODULE_PSA_MAC_HMAC_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_P256R1_BACKEND_MICROECC=y
CONFIG_MODULE_PSA_ASYMMETRIC_ECC_ED25519_BACKEND_C25519=y
CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1 CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=2
CONFIG_PSA_SINGLE_KEY_COUNT=3 CONFIG_PSA_SINGLE_KEY_COUNT=4

View File

@ -23,7 +23,11 @@
#include "psa/crypto.h" #include "psa/crypto.h"
#define ECDSA_MESSAGE_SIZE (127) #define ECDSA_MESSAGE_SIZE (127)
#define ECC_KEY_SIZE (256) #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 * @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_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_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( uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(ECC_KEY_TYPE, ECC_KEY_SIZE)] = { 0 };
PSA_ECC_FAMILY_SECP_R1),
ECC_KEY_SIZE)] = { 0 };
size_t pubkey_length; 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; size_t sig_length;
uint8_t msg[ECDSA_MESSAGE_SIZE] = { 0x0b }; 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; 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_usage_flags(&privkey_attr, usage);
psa_set_key_type(&privkey_attr, type); psa_set_key_type(&privkey_attr, ECC_KEY_TYPE);
psa_set_key_bits(&privkey_attr, bits); psa_set_key_bits(&privkey_attr, ECC_KEY_SIZE);
#ifdef SECURE_ELEMENT #ifdef SECURE_ELEMENT
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( 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; 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) { if (status != PSA_SUCCESS) {
return status; return status;
} }
@ -86,9 +83,9 @@ psa_status_t example_ecdsa_p256(void)
#ifdef SECURE_ELEMENT #ifdef SECURE_ELEMENT
psa_set_key_lifetime(&pubkey_attr, lifetime); psa_set_key_lifetime(&pubkey_attr, lifetime);
#endif #endif
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_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
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)); 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); 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; 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); &sig_length);
if (status != PSA_SUCCESS) { if (status != PSA_SUCCESS) {
return status; 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 #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_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV1); 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_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( uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(ECC_KEY_TYPE, ECC_KEY_SIZE)] = { 0 };
PSA_ECC_FAMILY_SECP_R1), 256)] = { 0 };
size_t pubkey_length; 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; size_t sig_length;
uint8_t msg[ECDSA_MESSAGE_SIZE] = { 0x0b }; 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; size_t hash_length;
psa_set_key_lifetime(&privkey_attr, lifetime); 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_usage_flags(&privkey_attr, usage);
psa_set_key_type(&privkey_attr, type); psa_set_key_type(&privkey_attr, ECC_KEY_TYPE);
psa_set_key_bits(&privkey_attr, bits); psa_set_key_bits(&privkey_attr, ECC_KEY_SIZE);
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST; psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
@ -150,15 +142,15 @@ psa_status_t example_ecdsa_p256_sec_se(void)
return status; 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) { if (status != PSA_SUCCESS) {
return status; return status;
} }
psa_set_key_lifetime(&pubkey_attr, lifetime); 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_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)); 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); 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; 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); &sig_length);
if (status != PSA_SUCCESS) { if (status != PSA_SUCCESS) {
return status; 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 #endif

View File

@ -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 <mikolai.guetschow@tu-dresden.de>
*
* @}
*/
#include <stdio.h>
#include <stdint.h>
#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);
}

View File

@ -24,6 +24,7 @@
extern psa_status_t example_cipher_aes_128(void); extern psa_status_t example_cipher_aes_128(void);
extern psa_status_t example_hmac_sha256(void); extern psa_status_t example_hmac_sha256(void);
extern psa_status_t example_ecdsa_p256(void); extern psa_status_t example_ecdsa_p256(void);
extern psa_status_t example_eddsa(void);
#ifdef MULTIPLE_SE #ifdef MULTIPLE_SE
extern psa_status_t example_cipher_aes_128_sec_se(void); 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)); 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 #ifdef MULTIPLE_SE
puts("Running Examples with secondary SE:"); puts("Running Examples with secondary SE:");
status = example_hmac_sha256_sec_se(); status = example_hmac_sha256_sec_se();

View File

@ -228,6 +228,11 @@ config HAS_PERIPH_ECC_P256R1
help help
Indicates that there is ECC P256R1 hardware acceleration peripheral present. 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 config HAS_PERIPH_EEPROM
bool bool
help help

View File

@ -15,3 +15,5 @@ config PACKAGE_C25519
enough that they could be reasonably considered for most enough that they could be reasonably considered for most
microcontroller applications. In particular, Curve25519 scalar microcontroller applications. In particular, Curve25519 scalar
multiplication uses less than half a kB of peak stack usage. multiplication uses less than half a kB of peak stack usage.
rsource "psa_c25519/Kconfig"

View File

@ -1 +1,7 @@
INCLUDES += -I$(PKGDIRBASE)/c25519/src 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

View File

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

View File

@ -0,0 +1,4 @@
BASE_MODULE := psa_c25519
SUBMODULES := 1
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1 @@
USEMODULE += random

View File

@ -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 <mikolai.guetschow@tu-dresden.de>
*
* @}
*/
#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;
}

View File

@ -16,6 +16,7 @@ PSEUDOMODULES += psa_cryptocell_310_aes_common
PSEUDOMODULES += psa_cryptocell_310_ecc_common PSEUDOMODULES += psa_cryptocell_310_ecc_common
PSEUDOMODULES += psa_cryptocell_310_ecc_p192 PSEUDOMODULES += psa_cryptocell_310_ecc_p192
PSEUDOMODULES += psa_cryptocell_310_ecc_p256 PSEUDOMODULES += psa_cryptocell_310_ecc_p256
PSEUDOMODULES += psa_cryptocell_310_ecc_ed25519
PSEUDOMODULES += psa_cryptocell_310_error_conversion PSEUDOMODULES += psa_cryptocell_310_error_conversion
PSEUDOMODULES += psa_cryptocell_310_hashes_common PSEUDOMODULES += psa_cryptocell_310_hashes_common
PSEUDOMODULES += psa_cryptocell_310_hashes_sha1 PSEUDOMODULES += psa_cryptocell_310_hashes_sha1

View File

@ -38,7 +38,7 @@ extern "C" {
* *
* @param hash psa_algorithm_t * @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_1) ? CRYS_ECPKI_AFTER_HASH_SHA1_mode : \
(hash == PSA_ALG_SHA_224) ? CRYS_ECPKI_AFTER_HASH_SHA224_mode : \ (hash == PSA_ALG_SHA_224) ? CRYS_ECPKI_AFTER_HASH_SHA224_mode : \
(hash == PSA_ALG_SHA_256) ? CRYS_ECPKI_AFTER_HASH_SHA256_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 : \ (hash == PSA_ALG_SHA_512) ? CRYS_ECPKI_AFTER_HASH_SHA512_mode : \
0) 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 * @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); 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 Pointer to ECC private key
* @param priv_key_size Size of private key * @param priv_key_size Size of private key
* @param hash Hash of the message to sign * @param input Input to sign (hash or original message depending on @c hash_mode )
* @param hash_length Length of the message hash * @param input_length Length of the input
* @param signature Output buffer to write the generated signature * @param signature Output buffer to write the generated signature
* @param signature_length Pointer to store the actual length of the 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 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 * @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t
* @return psa_status_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, uint32_t priv_key_size,
const uint8_t *hash, const uint8_t *input,
size_t hash_length, size_t input_length,
uint8_t *signature, uint8_t *signature,
size_t *signature_length, size_t *signature_length,
CRYS_ECPKI_HASH_OpMode_t hash_mode, CRYS_ECPKI_HASH_OpMode_t hash_mode,
CRYS_ECPKI_DomainID_t domain); 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 Pointer to ECC public key
* @param pub_key_size Size of public key * @param pub_key_size Size of public key
* @param hash Hash of the message to sign * @param input Input to verify (hash or original message depending on @c hash_mode )
* @param hash_length Length of the message hash * @param input_length Length of the input
* @param signature Buffer containing the signature to be verified * @param signature Buffer containing the signature to be verified
* @param signature_length Actual length of the signature * @param signature_length Actual length of the signature
* @param hash_mode Mode used to hash the message of type * @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 * @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t
* @return psa_status_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, size_t pub_key_size,
const uint8_t *hash, const uint8_t *input,
size_t hash_length, size_t input_length,
const uint8_t *signature, const uint8_t *signature,
size_t signature_length, size_t signature_length,
CRYS_ECPKI_HASH_OpMode_t hash_mode, CRYS_ECPKI_HASH_OpMode_t hash_mode,

View File

@ -25,6 +25,7 @@ extern "C" {
#include "psa/crypto.h" #include "psa/crypto.h"
#include "crys_ecpki_error.h" #include "crys_ecpki_error.h"
#include "crys_ec_mont_edw_error.h"
#include "crys_hash_error.h" #include "crys_hash_error.h"
#include "ssi_aes_error.h" #include "ssi_aes_error.h"

View File

@ -60,6 +60,11 @@ config MODULE_PSA_CRYPTOCELL_310_ECC_P256
select MODULE_PSA_CRYPTOCELL_310 select MODULE_PSA_CRYPTOCELL_310
select MODULE_PSA_CRYPTOCELL_310_ECC_COMMON 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 config MODULE_PSA_CRYPTOCELL_310
bool "PSA CryptoCell Wrapper" bool "PSA CryptoCell Wrapper"
select MODULE_PSA_CRYPTOCELL_310_ERROR_CONVERSION select MODULE_PSA_CRYPTOCELL_310_ERROR_CONVERSION

View File

@ -70,10 +70,10 @@ psa_status_t cryptocell_310_common_ecc_generate_key_pair(uint8_t *priv_key_buffe
return PSA_SUCCESS; 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, uint32_t priv_key_size,
const uint8_t *hash, const uint8_t *input,
size_t hash_length, size_t input_length,
uint8_t *signature, uint8_t *signature,
size_t *signature_length, size_t *signature_length,
CRYS_ECPKI_HASH_OpMode_t hash_mode, 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(); cryptocell_310_enable();
ret = CRYS_ECDSA_Sign(rndState_ptr, rndGenerateVectFunc, 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); signature, (uint32_t *)signature_length);
cryptocell_310_disable(); cryptocell_310_disable();
if (ret != CRYS_OK) { 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; 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, size_t pub_key_size,
const uint8_t *hash, const uint8_t *input,
size_t hash_length, size_t input_length,
const uint8_t *signature, const uint8_t *signature,
size_t signature_length, size_t signature_length,
CRYS_ECPKI_HASH_OpMode_t hash_mode, 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(); cryptocell_310_enable();
ret = CRYS_ECDSA_Verify(&VerifyUserContext, &user_pub_key, hash_mode, (uint8_t *)signature, 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(); cryptocell_310_disable();
if (ret != CRYS_OK) { if (ret != CRYS_OK) {

View File

@ -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 <mikolai.guetschow@tu-dresden.de>
*
* @}
*/
#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;
}

View File

@ -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_size,
size_t *signature_length) 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)signature_size;
(void)key_buffer_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), PSA_BITS_TO_BYTES(attributes->bits),
hash, hash_length, signature, hash, hash_length, signature,
signature_length, hash_mode, signature_length, hash_mode,
CRYS_ECPKI_DomainID_secp192r1); 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_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes,
psa_algorithm_t alg, psa_algorithm_t alg,
const uint8_t *key_buffer, 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, const uint8_t *signature,
size_t signature_length) 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; (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, hash, hash_length, signature,
signature_length, hash_mode, signature_length, hash_mode,
CRYS_ECPKI_DomainID_secp192r1); 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);
}

View File

@ -46,15 +46,35 @@ psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes,
size_t *signature_length) size_t *signature_length)
{ {
(void)key_buffer_size; (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; *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), PSA_BITS_TO_BYTES(attributes->bits),
hash, hash_length, signature, hash, hash_length, signature,
signature_length, hash_mode, signature_length, hash_mode,
CRYS_ECPKI_DomainID_secp256r1); 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_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes,
psa_algorithm_t alg, psa_algorithm_t alg,
const uint8_t *key_buffer, 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, const uint8_t *signature,
size_t signature_length) 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; (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, hash, hash_length, signature,
signature_length, hash_mode, signature_length, hash_mode,
CRYS_ECPKI_DomainID_secp256r1); 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);
}

View File

@ -28,6 +28,9 @@ psa_status_t CRYS_to_psa_error(CRYSError_t error)
return PSA_ERROR_NOT_SUPPORTED; return PSA_ERROR_NOT_SUPPORTED;
case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR: case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
return PSA_ERROR_CORRUPTION_DETECTED; 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_CONTEXT_VALIDATION_TAG_ERROR:
case CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR: case CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR:
case CRYS_ECDSA_VERIFY_USER_CONTEXT_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_INVALID_USER_CONTEXT_POINTER_ERROR:
case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR: case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
case CRYS_HASH_CTX_SIZES_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: default:
return PSA_ERROR_GENERIC_ERROR; 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"; return "SASI_AES_IS_NOT_SUPPORTED";
case SASI_OUT_OF_RESOURCE_ERROR: case SASI_OUT_OF_RESOURCE_ERROR:
return "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: default:
return "Error value not recognized"; return "Error value not recognized";
} }
} }

View File

@ -62,6 +62,25 @@ psa_status_t psa_ecc_p192r1_sign_hash( const psa_key_attributes_t *attributes,
return PSA_SUCCESS; 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_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes,
psa_algorithm_t alg, const uint8_t *key_buffer, psa_algorithm_t alg, const uint8_t *key_buffer,
size_t key_buffer_size, const uint8_t *hash, 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; (void)signature_length;
return PSA_SUCCESS; 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);
}

View File

@ -62,6 +62,25 @@ psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes,
return PSA_SUCCESS; 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_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes,
psa_algorithm_t alg, const uint8_t *key_buffer, psa_algorithm_t alg, const uint8_t *key_buffer,
size_t key_buffer_size, const uint8_t *hash, 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; (void)signature_length;
return PSA_SUCCESS; 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);
}

View File

@ -59,6 +59,7 @@ extern "C" {
*/ */
#ifndef CONFIG_PSA_MAX_KEY_SIZE #ifndef CONFIG_PSA_MAX_KEY_SIZE
#if (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \ #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_CIPHER_AES_256_CBC) || \
IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \ IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \
IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256)) IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256))
@ -838,16 +839,21 @@ extern "C" {
/* implementation-defined value */ /* 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 * @param bits Key size of type @ref psa_key_bits_t
*/ */
#define PSA_ECC_KEY_SIZE_IS_VALID(bits) \ #define PSA_ECC_KEY_SIZE_IS_VALID(type, bits) \
(bits == 128 || \ (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? \
bits == 192 || \ (bits == 255) : \
bits == 224 || \ (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_SECP_R1 ? \
bits == 256 || \ (bits == 128 || \
bits == 384) bits == 192 || \
bits == 224 || \
bits == 256 || \
bits == 384) : \
0))
/** /**
* @brief The maximum size of an asymmetric private key. * @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 */ #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. * @brief Maximum size of the export encoding of an ECC public key.
* *
* @details The representation of an ECC public key is: * @details The representation of an ECC public key is dependent on the family:
* - The byte 0x04; * - for twisted Edwards curves: 32B
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian; * - for Weierstrass curves:
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian; * - The byte 0x04;
* - where m is the bit size associated with the curve. * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
* - 1 byte + 2 * point size. * - `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) \ #define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) \
((size_t)(2 * PSA_BITS_TO_BYTES(key_bits) + 1)) (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(). * @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). * @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) \ #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) 0)
/** /**
@ -932,8 +965,13 @@ extern "C" {
* *
* See also @ref PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(@p key_type, @p key_bits). * 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 \ #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 * @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. * If the parameters are not valid, the return value is unspecified.
*/ */
#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \ #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)) ((void)alg, 0))
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -2815,18 +2815,6 @@ extern "C" {
#define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \ #define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \
(PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (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. * @brief Elliptic curve public key.
* *

View File

@ -58,4 +58,27 @@ endchoice
endif # MODULE_PSA_ASYMMETRIC_ECC_P256R1 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 endif # MODULE_PSA_ASYMMETRIC

View File

@ -56,6 +56,30 @@ ifneq (,$(filter psa_asymmetric_ecc_p256r1_backend_periph,$(USEMODULE)))
FEATURES_REQUIRED += periph_ecc_p256r1 FEATURES_REQUIRED += periph_ecc_p256r1
endif 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 # Cipher
ifneq (,$(filter psa_cipher,$(USEMODULE))) ifneq (,$(filter psa_cipher,$(USEMODULE)))
USEMODULE += psa_key_slot_mgmt USEMODULE += psa_key_slot_mgmt

View File

@ -29,11 +29,23 @@ PSEUDOMODULES += psa_asymmetric_ecc_p256r1_custom_backend
# check that one and only one backend has been selected # check that one and only one backend has been selected
ifneq (,$(filter psa_asymmetric_ecc_p256r1,$(USEMODULE))) 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") $(error "One (and only one) backend should be selected for psa_asymmetric_ecc_p256r1")
endif endif
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 ## Cipher
PSEUDOMODULES += psa_cipher PSEUDOMODULES += psa_cipher
PSEUDOMODULES += psa_cipher_aes_128_ecb PSEUDOMODULES += psa_cipher_aes_128_ecb

View File

@ -248,6 +248,12 @@
* - psa_asymmetric_ecc_p256r1_custom_backend * - psa_asymmetric_ecc_p256r1_custom_backend
* - psa_asymmetric_ecc_p256r1_backend_microecc * - 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 * ### Ciphers
* - Base: psa_cipher * - Base: psa_cipher
* *

View File

@ -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_size,
size_t *signature_length); 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. * @brief Dispatch a hash verification function to a specific backend.
* See @ref psa_verify_hash() * 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, const uint8_t *signature,
size_t signature_length); 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. * @brief Dispatch the key generation function to a specific backend.
* See @ref psa_generate_key() * See @ref psa_generate_key()

View File

@ -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_size,
size_t *signature_length); 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. * @brief Dispatch call of a hash verification function to a location specific backend.
* See psa_verify_hash() * 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, const uint8_t *signature,
size_t signature_length); 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. * @brief Dispatch call of a mac computation function to a location specific backend.
* See psa_mac_compute() * See psa_mac_compute()

View File

@ -11,7 +11,7 @@
* @{ * @{
* *
* @file psa_crypto_operation_encoder.h * @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. * and operations to call the corresponding driver functions.
* *
* @note Currently this only supports a small number of operations. It should be expanded as * @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_P384_R1,
PSA_ECC_P521_R1, PSA_ECC_P521_R1,
PSA_ECC_FRP, PSA_ECC_FRP,
PSA_ECMONT_255, PSA_ECC_ED25519,
PSA_ECMONT_448
} psa_asym_key_t; } 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_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) \ #define PSA_ENCODE_ECC_KEY_TYPE_SECPR1(bits) \
((curve == PSA_ECC_FAMILY_SECP_R1) ? PSA_ECC_P192_R1 : \ ((bits == 256) || (bits == 520) ? PSA_ECC_P256_R1 : \
(bits == 192) || (bits == 392) ? PSA_ECC_P192_R1 : \
PSA_INVALID_OPERATION) 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_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) \ #define PSA_ENCODE_ECC_KEY_TYPE_EDWARDS(bits) \
((curve == PSA_ECC_FAMILY_SECP_R1) ? PSA_ECC_P256_R1 : \ ((bits == 255) || (bits == 256) ? PSA_ECC_ED25519 : \
PSA_INVALID_OPERATION) 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 bits Key size of type @ref psa_key_bits_t
* @param curve Must be a curve of type @ref psa_ecc_family_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 * @return @ref PSA_INVALID_OPERATION @c curve and @c bits are incompatible
*/ */
#define PSA_ENCODE_ECC_KEY_TYPE(bits, curve) \ #define PSA_ENCODE_ECC_KEY_TYPE(bits, curve) \
((bits == 256) || (bits == 520) ? GET_ECC_KEY_TYPE_256(curve) : \ ((curve == PSA_ECC_FAMILY_SECP_R1) ? PSA_ENCODE_ECC_KEY_TYPE_SECPR1(bits) : \
(bits == 192) || (bits == 392) ? GET_ECC_KEY_TYPE_192(curve) : \ (curve == PSA_ECC_FAMILY_TWISTED_EDWARDS) ? PSA_ENCODE_ECC_KEY_TYPE_EDWARDS(bits) : \
PSA_INVALID_OPERATION) PSA_INVALID_OPERATION)
/** /**

View File

@ -80,7 +80,7 @@ typedef struct {
/** Structure containing key data */ /** Structure containing key data */
struct key_data { struct key_data {
uint8_t data[PSA_MAX_KEY_DATA_SIZE]; /**< Key data buffer */ 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 */ } key; /**< Key data structure */
} psa_key_slot_t; } psa_key_slot_t;

View File

@ -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 *priv_key_buffer_length,
size_t *pub_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 * @brief Low level wrapper function to call a driver for an ECC hash signature
* with a SECP 192 R1 key. * 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, uint8_t *signature, size_t signature_size,
size_t *signature_length); 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 * @brief Low level wrapper function to call a driver for an ECC hash verification
* with a SECP 192 R1 key. * 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 *hash, size_t hash_length,
const uint8_t *signature, size_t signature_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 * @brief Low level wrapper function to call a driver for an ECC key generation
* with a SECP 192 R1 key. * 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 *priv_key_buffer_length,
size_t *pub_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 * @brief Low level wrapper function to call a driver for an ECC hash signature
* with a SECP 256 R1 key. * 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, uint8_t *signature, size_t signature_size,
size_t *signature_length); 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 * @brief Low level wrapper function to call a driver for an ECC hash verification
* with a SECP 256 R1 key. * 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 *hash, size_t hash_length,
const uint8_t *signature, size_t signature_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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -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) #if IS_USED(MODULE_PSA_ASYMMETRIC) || IS_USED(MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC)
else if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) { 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 #endif
/* TODO: add validation for other key types */ /* 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) { if (status != PSA_SUCCESS) {
return status; return status;
} }
slot->key.data_len = PSA_MAX_KEY_DATA_SIZE;
} }
status = psa_location_dispatch_generate_key(attributes, slot); 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; 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; return PSA_ERROR_INVALID_ARGUMENT;
} }
@ -1814,7 +1812,7 @@ psa_status_t psa_sign_hash(psa_key_id_t key,
return status; 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; 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_size,
size_t *signature_length) size_t *signature_length)
{ {
(void)key;
(void)alg; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
(void)input; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
(void)input_length; psa_key_slot_t *slot;
(void)signature;
(void)signature_size; if (!lib_initialized) {
(void)signature_length; return PSA_ERROR_BAD_STATE;
return PSA_ERROR_NOT_SUPPORTED; }
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, 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; 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; return PSA_ERROR_INVALID_ARGUMENT;
} }
@ -1883,14 +1916,7 @@ psa_status_t psa_verify_hash(psa_key_id_t key,
return status; return status;
} }
/** if (signature_length != PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) {
* 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)) {
return PSA_ERROR_INVALID_ARGUMENT; return PSA_ERROR_INVALID_ARGUMENT;
} }
@ -1921,11 +1947,52 @@ psa_status_t psa_verify_message(psa_key_id_t key,
const uint8_t *signature, const uint8_t *signature,
size_t signature_length) size_t signature_length)
{ {
(void)key; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
(void)alg; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
(void)input; psa_key_slot_t *slot;
(void)input_length;
(void)signature; if (!lib_initialized) {
(void)signature_length; return PSA_ERROR_BAD_STATE;
return PSA_ERROR_NOT_SUPPORTED; }
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);
} }

View File

@ -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; psa_asym_key_t asym_key = PSA_INVALID_OPERATION;
uint8_t *key_data = NULL; uint8_t *key_data = NULL;
size_t *key_bytes = 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)) { if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) {
asym_key = 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) { if (asym_key == PSA_INVALID_OPERATION) {
return PSA_ERROR_INVALID_ARGUMENT; 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;
(void)signature_size; (void)signature_size;
(void)signature_length; (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; 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)) { if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
asym_key = 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) { if (asym_key == PSA_INVALID_OPERATION) {
return PSA_ERROR_INVALID_ARGUMENT; 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_status_t psa_algorithm_dispatch_generate_key( const psa_key_attributes_t *attributes,
psa_key_slot_t *slot) 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)) { if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) {
asym_key = asym_key =
PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, 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) { if (asym_key == PSA_INVALID_OPERATION) {
return PSA_ERROR_INVALID_ARGUMENT; 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: case PSA_ECC_P256_R1:
return psa_generate_ecc_p256r1_key_pair(attributes, key_data, pubkey_data, key_bytes, return psa_generate_ecc_p256r1_key_pair(attributes, key_data, pubkey_data, key_bytes,
pubkey_data_len); 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 #endif
default: default:
(void)status; (void)status;

View File

@ -368,6 +368,21 @@ psa_status_t psa_location_dispatch_sign_hash( const psa_key_attributes_t *attri
signature_size, signature_length); 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_status_t psa_location_dispatch_verify_hash(const psa_key_attributes_t *attributes,
psa_algorithm_t alg, psa_algorithm_t alg,
const psa_key_slot_t *slot, 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); 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_status_t psa_location_dispatch_mac_compute(const psa_key_attributes_t *attributes,
psa_algorithm_t alg, psa_algorithm_t alg,
const psa_key_slot_t *slot, const psa_key_slot_t *slot,