mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-28 23:29:45 +01:00
sys/psa_crypto: add support for Ed25519 (EdDSA)
This commit is contained in:
parent
dd62f419d7
commit
963775bdd9
@ -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
|
||||
|
@ -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)))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
83
examples/psa_crypto/example_eddsa.c
Normal file
83
examples/psa_crypto/example_eddsa.c
Normal 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);
|
||||
}
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
15
pkg/c25519/psa_c25519/Kconfig
Normal file
15
pkg/c25519/psa_c25519/Kconfig
Normal 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
|
4
pkg/c25519/psa_c25519/Makefile
Normal file
4
pkg/c25519/psa_c25519/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
BASE_MODULE := psa_c25519
|
||||
SUBMODULES := 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
1
pkg/c25519/psa_c25519/Makefile.dep
Normal file
1
pkg/c25519/psa_c25519/Makefile.dep
Normal file
@ -0,0 +1 @@
|
||||
USEMODULE += random
|
81
pkg/c25519/psa_c25519/edsign.c
Normal file
81
pkg/c25519/psa_c25519/edsign.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
125
pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_ed25519.c
Normal file
125
pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_ed25519.c
Normal 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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ psa_status_t CRYS_to_psa_error(CRYSError_t error)
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
|
||||
case CRYS_ECEDW_SIGN_VERIFY_FAILED_ERROR:
|
||||
return PSA_ERROR_INVALID_SIGNATURE;
|
||||
case CRYS_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR:
|
||||
@ -115,7 +118,20 @@ psa_status_t CRYS_to_psa_error(CRYSError_t error)
|
||||
case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR:
|
||||
case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
|
||||
case CRYS_HASH_CTX_SIZES_ERROR:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
case CRYS_ECEDW_INVALID_INPUT_POINTER_ERROR:
|
||||
case CRYS_ECEDW_INVALID_INPUT_SIZE_ERROR:
|
||||
case CRYS_ECEDW_INVALID_SCALAR_SIZE_ERROR:
|
||||
case CRYS_ECEDW_INVALID_SCALAR_DATA_ERROR:
|
||||
case CRYS_ECEDW_RND_CONTEXT_PTR_INVALID_ERROR:
|
||||
case CRYS_ECEDW_RND_GEN_VECTOR_FUNC_ERROR:
|
||||
case CRYS_ECMONT_INVALID_INPUT_POINTER_ERROR:
|
||||
case CRYS_ECMONT_INVALID_INPUT_SIZE_ERROR:
|
||||
case CRYS_ECMONT_INVALID_DOMAIN_ID_ERROR:
|
||||
case CRYS_ECEDW_PKI_ERROR:
|
||||
case CRYS_ECMONT_PKI_ERROR:
|
||||
case CRYS_ECMONT_IS_NOT_SUPPORTED:
|
||||
case CRYS_ECEDW_IS_NOT_SUPPORTED:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
@ -407,7 +423,36 @@ const char *cryptocell310_status_to_humanly_readable(uint32_t status)
|
||||
return "SASI_AES_IS_NOT_SUPPORTED";
|
||||
case SASI_OUT_OF_RESOURCE_ERROR:
|
||||
return "SASI_OUT_OF_RESOURCE_ERROR";
|
||||
case CRYS_ECEDW_INVALID_INPUT_POINTER_ERROR:
|
||||
return "CRYS_ECEDW_INVALID_INPUT_POINTER_ERROR";
|
||||
case CRYS_ECEDW_INVALID_INPUT_SIZE_ERROR:
|
||||
return "CRYS_ECEDW_INVALID_INPUT_SIZE_ERROR";
|
||||
case CRYS_ECEDW_INVALID_SCALAR_SIZE_ERROR:
|
||||
return "CRYS_ECEDW_INVALID_SCALAR_SIZE_ERROR";
|
||||
case CRYS_ECEDW_INVALID_SCALAR_DATA_ERROR:
|
||||
return "CRYS_ECEDW_INVALID_SCALAR_DATA_ERROR";
|
||||
case CRYS_ECEDW_RND_CONTEXT_PTR_INVALID_ERROR:
|
||||
return "CRYS_ECEDW_RND_CONTEXT_PTR_INVALID_ERROR";
|
||||
case CRYS_ECEDW_RND_GEN_VECTOR_FUNC_ERROR:
|
||||
return "CRYS_ECEDW_RND_GEN_VECTOR_FUNC_ERROR";
|
||||
case CRYS_ECEDW_SIGN_VERIFY_FAILED_ERROR:
|
||||
return "CRYS_ECEDW_SIGN_VERIFY_FAILED_ERROR";
|
||||
case CRYS_ECMONT_INVALID_INPUT_POINTER_ERROR:
|
||||
return "CRYS_ECMONT_INVALID_INPUT_POINTER_ERROR";
|
||||
case CRYS_ECMONT_INVALID_INPUT_SIZE_ERROR:
|
||||
return "CRYS_ECMONT_INVALID_INPUT_SIZE_ERROR";
|
||||
case CRYS_ECMONT_INVALID_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECMONT_INVALID_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECEDW_PKI_ERROR:
|
||||
return "CRYS_ECEDW_PKI_ERROR";
|
||||
case CRYS_ECMONT_PKI_ERROR:
|
||||
return "CRYS_ECMONT_PKI_ERROR";
|
||||
case CRYS_ECMONT_IS_NOT_SUPPORTED:
|
||||
return "CRYS_ECMONT_IS_NOT_SUPPORTED";
|
||||
case CRYS_ECEDW_IS_NOT_SUPPORTED:
|
||||
return "CRYS_ECEDW_IS_NOT_SUPPORTED";
|
||||
default:
|
||||
return "Error value not recognized";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ extern "C" {
|
||||
*/
|
||||
#ifndef CONFIG_PSA_MAX_KEY_SIZE
|
||||
#if (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \
|
||||
IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) || \
|
||||
IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || \
|
||||
IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \
|
||||
IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256))
|
||||
@ -838,16 +839,21 @@ extern "C" {
|
||||
/* implementation-defined value */
|
||||
|
||||
/**
|
||||
* @brief Check whether the key size is a valid ECC size.
|
||||
* @brief Check whether the key size is a valid ECC size for key type.
|
||||
*
|
||||
* @param type key type of of type @ref psa_key_type_t
|
||||
* @param bits Key size of type @ref psa_key_bits_t
|
||||
*/
|
||||
#define PSA_ECC_KEY_SIZE_IS_VALID(bits) \
|
||||
(bits == 128 || \
|
||||
bits == 192 || \
|
||||
bits == 224 || \
|
||||
bits == 256 || \
|
||||
bits == 384)
|
||||
#define PSA_ECC_KEY_SIZE_IS_VALID(type, bits) \
|
||||
(PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? \
|
||||
(bits == 255) : \
|
||||
(PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_SECP_R1 ? \
|
||||
(bits == 128 || \
|
||||
bits == 192 || \
|
||||
bits == 224 || \
|
||||
bits == 256 || \
|
||||
bits == 384) : \
|
||||
0))
|
||||
|
||||
/**
|
||||
* @brief The maximum size of an asymmetric private key.
|
||||
@ -865,18 +871,45 @@ extern "C" {
|
||||
*/
|
||||
#define PSA_EXPORT_KEY_PAIR_MAX_SIZE /* implementation-defined value */
|
||||
|
||||
/**
|
||||
* @brief Get curve size from ECC public key
|
||||
*
|
||||
* @details The representation of an ECC public key is dependent on the family:
|
||||
* - for twisted Edwards curves: 32B
|
||||
* - for Weierstrass curves:
|
||||
* - The byte 0x04;
|
||||
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
|
||||
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
|
||||
* - where m is the bit size associated with the curve.
|
||||
* - 1 byte + 2 * point size.
|
||||
*/
|
||||
#define PSA_ECC_KEY_GET_CURVE_FROM_PUBLIC_KEY(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 255 : \
|
||||
((size_t)((key_bits - 8) / 2)))
|
||||
|
||||
/**
|
||||
* @brief Get curve size from ECC key (public or private)
|
||||
*/
|
||||
#define PSA_ECC_KEY_GET_CURVE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? \
|
||||
PSA_ECC_KEY_GET_CURVE_FROM_PUBLIC_KEY(key_type, key_bits) : \
|
||||
(size_t)key_bits)
|
||||
|
||||
/**
|
||||
* @brief Maximum size of the export encoding of an ECC public key.
|
||||
*
|
||||
* @details The representation of an ECC public key is:
|
||||
* - The byte 0x04;
|
||||
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
|
||||
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
|
||||
* - where m is the bit size associated with the curve.
|
||||
* - 1 byte + 2 * point size.
|
||||
* @details The representation of an ECC public key is dependent on the family:
|
||||
* - for twisted Edwards curves: 32B
|
||||
* - for Weierstrass curves:
|
||||
* - The byte 0x04;
|
||||
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
|
||||
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
|
||||
* - where m is the bit size associated with the curve.
|
||||
* - 1 byte + 2 * point size.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \
|
||||
((size_t)(2 * PSA_BITS_TO_BYTES(key_bits) + 1))
|
||||
#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 32 : \
|
||||
((size_t)(2 * PSA_BITS_TO_BYTES(key_bits) + 1)))
|
||||
|
||||
/**
|
||||
* @brief Sufficient output buffer size for @ref psa_export_public_key().
|
||||
@ -919,7 +952,7 @@ extern "C" {
|
||||
* @ref PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(@p key_type), @p key_bits).
|
||||
*/
|
||||
#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
(PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) : \
|
||||
0)
|
||||
|
||||
/**
|
||||
@ -932,8 +965,13 @@ extern "C" {
|
||||
*
|
||||
* See also @ref PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(@p key_type, @p key_bits).
|
||||
*/
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)
|
||||
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
|
||||
(PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_PRIV_KEY_SIZE))
|
||||
(PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_SECT_R1, PSA_MAX_PRIV_KEY_SIZE))
|
||||
#else
|
||||
#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
|
||||
(PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_TWISTED_EDWARDS, PSA_MAX_PRIV_KEY_SIZE))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The maximum size of an asymmetric private key buffer. If only a secure element driver is
|
||||
@ -993,7 +1031,7 @@ extern "C" {
|
||||
* If the parameters are not valid, the return value is unspecified.
|
||||
*/
|
||||
#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \
|
||||
(PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
|
||||
(PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(key_type, key_bits)) : \
|
||||
((void)alg, 0))
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -29,11 +29,23 @@ PSEUDOMODULES += psa_asymmetric_ecc_p256r1_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p256r1,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_asymmetric_ecc_p256r1))
|
||||
ifneq (1,$(call backends, psa_asymmetric_ecc_p256r1))
|
||||
$(error "One (and only one) backend should be selected for psa_asymmetric_ecc_p256r1")
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_ed25519
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_ed25519_backend_periph
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_ed25519_backend_c25519
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_ed25519_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_asymmetric_ecc_ed25519,$(USEMODULE)))
|
||||
ifneq (1,$(call backends, psa_asymmetric_ecc_ed25519))
|
||||
$(error "One (and only one) backend should be selected for psa_asymmetric_ecc_ed25519")
|
||||
endif
|
||||
endif
|
||||
|
||||
## Cipher
|
||||
PSEUDOMODULES += psa_cipher
|
||||
PSEUDOMODULES += psa_cipher_aes_128_ecb
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
||||
/**
|
||||
|
@ -80,7 +80,7 @@ typedef struct {
|
||||
/** Structure containing key data */
|
||||
struct key_data {
|
||||
uint8_t data[PSA_MAX_KEY_DATA_SIZE]; /**< Key data buffer */
|
||||
size_t data_len; /**< Size of actual key data in bytes */
|
||||
size_t data_len; /**< Size of actual key data in bytes */
|
||||
} key; /**< Key data structure */
|
||||
} psa_key_slot_t;
|
||||
|
||||
|
@ -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
|
||||
|
@ -992,7 +992,7 @@ static psa_status_t psa_validate_key_for_key_generation(psa_key_type_t type, siz
|
||||
}
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC) || IS_USED(MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC)
|
||||
else if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
|
||||
return PSA_ECC_KEY_SIZE_IS_VALID(bits) ? PSA_SUCCESS : PSA_ERROR_INVALID_ARGUMENT;
|
||||
return PSA_ECC_KEY_SIZE_IS_VALID(type, bits) ? PSA_SUCCESS : PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
#endif
|
||||
/* TODO: add validation for other key types */
|
||||
@ -1329,8 +1329,6 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
slot->key.data_len = PSA_MAX_KEY_DATA_SIZE;
|
||||
}
|
||||
|
||||
status = psa_location_dispatch_generate_key(attributes, slot);
|
||||
@ -1804,7 +1802,7 @@ psa_status_t psa_sign_hash(psa_key_id_t key,
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (hash_length != PSA_HASH_LENGTH(alg)) {
|
||||
if (!PSA_ALG_IS_SIGN_HASH(alg) || hash_length != PSA_HASH_LENGTH(alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@ -1814,7 +1812,7 @@ psa_status_t psa_sign_hash(psa_key_id_t key,
|
||||
return status;
|
||||
}
|
||||
|
||||
if (signature_size < PSA_SIGN_OUTPUT_SIZE(slot->attr.type, slot->attr.bits, alg)) {
|
||||
if (signature_size < PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
@ -1840,14 +1838,49 @@ psa_status_t psa_sign_message(psa_key_id_t key,
|
||||
size_t signature_size,
|
||||
size_t *signature_length)
|
||||
{
|
||||
(void)key;
|
||||
(void)alg;
|
||||
(void)input;
|
||||
(void)input_length;
|
||||
(void)signature;
|
||||
(void)signature_size;
|
||||
(void)signature_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_slot_t *slot;
|
||||
|
||||
if (!lib_initialized) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (!input || !signature || !signature_length) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!PSA_ALG_IS_ECDSA(alg)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = psa_get_and_lock_key_slot_with_policy(key, &slot, PSA_KEY_USAGE_SIGN_MESSAGE, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
unlock_status = psa_unlock_key_slot(slot);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (signature_size < PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) {
|
||||
unlock_status = psa_unlock_key_slot(slot);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
psa_key_attributes_t attributes = slot->attr;
|
||||
|
||||
status = psa_location_dispatch_sign_message(&attributes, alg, slot, input, input_length, signature,
|
||||
signature_size, signature_length);
|
||||
|
||||
unlock_status = psa_unlock_key_slot(slot);
|
||||
return ((status == PSA_SUCCESS) ? unlock_status : status);
|
||||
}
|
||||
|
||||
psa_status_t psa_verify_hash(psa_key_id_t key,
|
||||
@ -1873,7 +1906,7 @@ psa_status_t psa_verify_hash(psa_key_id_t key,
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (hash_length != PSA_HASH_LENGTH(alg)) {
|
||||
if (!PSA_ALG_IS_SIGN_HASH(alg) || hash_length != PSA_HASH_LENGTH(alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@ -1883,14 +1916,7 @@ psa_status_t psa_verify_hash(psa_key_id_t key,
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* An ECC public key has the size `curve_bytes * 2 + 1`.
|
||||
* So to get the curve size to determine the required signature
|
||||
* size, we need to revert that calculation.
|
||||
*/
|
||||
uint16_t curve_size = PSA_BYTES_TO_BITS(PSA_BITS_TO_BYTES(slot->attr.bits / 2) - 1);
|
||||
|
||||
if (signature_length != PSA_ECDSA_SIGNATURE_SIZE(curve_size)) {
|
||||
if (signature_length != PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@ -1921,11 +1947,52 @@ psa_status_t psa_verify_message(psa_key_id_t key,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
(void)key;
|
||||
(void)alg;
|
||||
(void)input;
|
||||
(void)input_length;
|
||||
(void)signature;
|
||||
(void)signature_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_slot_t *slot;
|
||||
|
||||
if (!lib_initialized) {
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
}
|
||||
|
||||
if (!input || !signature) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!PSA_ALG_IS_ECDSA(alg)) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!PSA_ALG_IS_SIGN_MESSAGE(alg)) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = psa_get_and_lock_key_slot_with_policy(key, &slot, PSA_KEY_USAGE_VERIFY_MESSAGE, alg);
|
||||
if (status != PSA_SUCCESS) {
|
||||
unlock_status = psa_unlock_key_slot(slot);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (signature_length != PSA_ECDSA_SIGNATURE_SIZE(PSA_ECC_KEY_GET_CURVE(slot->attr.type, slot->attr.bits))) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* When key location is a secure element, this implementation only supports
|
||||
* the use of public keys stored on the secure element, not key pairs in
|
||||
* which the public key is stored locally.
|
||||
*/
|
||||
if ((PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime) != PSA_KEY_LOCATION_LOCAL_STORAGE) &&
|
||||
PSA_KEY_TYPE_IS_ECC_KEY_PAIR(slot->attr.type)) {
|
||||
unlock_status = psa_unlock_key_slot(slot);
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_key_attributes_t attributes = slot->attr;
|
||||
|
||||
status = psa_location_dispatch_verify_message(&attributes, alg, slot, input, input_length, signature,
|
||||
signature_length);
|
||||
|
||||
unlock_status = psa_unlock_key_slot(slot);
|
||||
return ((status == PSA_SUCCESS) ? unlock_status : status);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user