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_ECC_P192R1
select HAS_PERIPH_ECC_P256R1
select HAS_PERIPH_ECC_ED25519
select HAS_PERIPH_CRYPTOCELL_310
## CPU common symbols

View File

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

View File

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

View File

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

View File

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

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
## 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_<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_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

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

View File

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

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_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();

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

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_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);
}

View File

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

View File

@ -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,6 +118,19 @@ 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:
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";
}
}

View File

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

View File

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

View File

@ -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) \
#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)
bits == 384) : \
0))
/**
* @brief The maximum size of an asymmetric private key.
@ -866,17 +872,44 @@ extern "C" {
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE /* implementation-defined value */
/**
* @brief Maximum size of the export encoding of an ECC public key.
* @brief Get curve size from 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:
* - 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_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 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_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

View File

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

View File

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

View File

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

View File

@ -34,6 +34,18 @@ ifneq (,$(filter psa_asymmetric_ecc_p256r1,$(USEMODULE)))
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

View File

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

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_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()

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_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()

View File

@ -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)
/**

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

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)
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,16 +1838,51 @@ 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;
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,
psa_algorithm_t alg,
const uint8_t *hash,
@ -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;
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);
}

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

View File

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