Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg/micro-ecc: Add PSA Crypto Wrappers #18581

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions makefiles/pseudomodules.inc.mk
Expand Up @@ -191,6 +191,8 @@ PSEUDOMODULES += posix_headers
PSEUDOMODULES += printf_float
PSEUDOMODULES += prng
PSEUDOMODULES += prng_%
PSEUDOMODULES += psa_uecc_P192
PSEUDOMODULES += psa_uecc_P256
PSEUDOMODULES += fortuna_reseed
PSEUDOMODULES += random_cmd
PSEUDOMODULES += riotboot_%
Expand Down
2 changes: 2 additions & 0 deletions pkg/micro-ecc/Kconfig
Expand Up @@ -15,3 +15,5 @@ config PACKAGE_MICRO-ECC
https://github.com/kmackay/micro-ecc and adds `hwrng_read` as
the default RNG function if it is available on the target
platform.

rsource "psa_uecc/Kconfig"
5 changes: 5 additions & 0 deletions pkg/micro-ecc/Makefile.include
Expand Up @@ -9,3 +9,8 @@ ifneq (,$(filter cortex-m0%,$(CPU_CORE)))
# package
TOOLCHAINS_BLACKLIST += llvm
endif

ifneq (,$(filter psa_uecc_%, $(USEMODULE)))
DIRS += $(RIOTPKG)/micro-ecc/psa_uecc
INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
endif
19 changes: 19 additions & 0 deletions pkg/micro-ecc/psa_uecc/Kconfig
@@ -0,0 +1,19 @@
# Copyright (c) 2021 HAW Hamburg
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#

config MODULE_PSA_UECC_P192
bool
depends on MODULE_PSA_CRYPTO
select MODULE_PSA_UECC

config MODULE_PSA_UECC_P256
bool
depends on MODULE_PSA_CRYPTO
select MODULE_PSA_UECC

config MODULE_PSA_UECC
bool
4 changes: 4 additions & 0 deletions pkg/micro-ecc/psa_uecc/Makefile
@@ -0,0 +1,4 @@
BASE_MODULE := psa_uecc
SUBMODULES := 1

include $(RIOTBASE)/Makefile.base
84 changes: 84 additions & 0 deletions pkg/micro-ecc/psa_uecc/p192.c
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2021 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup sys_psa_crypto pkg_micro-ecc
* @{
*
* @brief Glue code translating between PSA Crypto and the Micro-ECC APIs
*
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
*
* @}
*/

#include "psa/crypto.h"
#include "uECC.h"

psa_status_t psa_generate_ecc_p192r1_key_pair( const psa_key_attributes_t *attributes,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a given guarantee from the upper layer that all these pointers will always be valid? Otherwise I'd keep my defensive approach 🛡️ and check them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The attributes are checked first thing in psa_crypto.c and all key buffers come from inside the implementation, not from the user or application. So they'll be valid here =)

uint8_t *priv_key_buffer, uint8_t *pub_key_buffer,
size_t *priv_key_buffer_length,
size_t *pub_key_buffer_length)
{
int ret = 0;

*priv_key_buffer_length = PSA_BITS_TO_BYTES(attributes->bits);
*pub_key_buffer_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits);

struct uECC_Curve_t *curve = uECC_secp192r1();

ret = uECC_make_key(pub_key_buffer, priv_key_buffer, curve);
if (!ret) {
return PSA_ERROR_GENERIC_ERROR;
}

return PSA_SUCCESS;
}

psa_status_t psa_ecc_p192r1_sign_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,
size_t hash_length, uint8_t *signature,
size_t signature_size, size_t *signature_length)
{
int ret = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check that signature has enough space

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to check all the input buffer sizes at a higher level (psa_crypto.c), to abort operations before involving the key management and the driver?
Also that would provide some general protection in case future glue code contains mistakes.
In this case I forgot to write the check in psa_crypto.c, but I'll go through the code again to make sure all user inputs are validated.

struct uECC_Curve_t *curve = uECC_secp192r1();

ret = uECC_sign(key_buffer, hash, hash_length, signature, curve);
if (!ret) {
return PSA_ERROR_GENERIC_ERROR;
}

*signature_length = signature_size;

(void)alg;
(void)attributes;
(void)key_buffer_size;
return PSA_SUCCESS;
}

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,
size_t hash_length, const uint8_t *signature,
size_t signature_length)
{
int ret = 0;
struct uECC_Curve_t *curve = uECC_secp192r1();

ret = uECC_verify(key_buffer, hash, hash_length, signature, curve);
if (!ret) {
return PSA_ERROR_GENERIC_ERROR;
}

(void)alg;
(void)attributes;
(void)key_buffer_size;
(void)signature_length;
return PSA_SUCCESS;
}
84 changes: 84 additions & 0 deletions pkg/micro-ecc/psa_uecc/p256.c
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2021 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup sys_psa_crypto pkg_micro-ecc
* @{
*
* @brief Glue code translating between PSA Crypto and the Micro-ECC APIs
*
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
*
* @}
*/

#include "psa/crypto.h"
#include "uECC.h"

psa_status_t psa_generate_ecc_p256r1_key_pair( const psa_key_attributes_t *attributes,
uint8_t *priv_key_buffer, uint8_t *pub_key_buffer,
size_t *priv_key_buffer_length,
size_t *pub_key_buffer_length)
{
int ret = 0;

*priv_key_buffer_length = PSA_BITS_TO_BYTES(attributes->bits);
*pub_key_buffer_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits);

struct uECC_Curve_t *curve = uECC_secp256r1();

ret = uECC_make_key(pub_key_buffer, priv_key_buffer, curve);
if (!ret) {
return PSA_ERROR_GENERIC_ERROR;
}

return PSA_SUCCESS;
}

psa_status_t psa_ecc_p256r1_sign_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,
size_t hash_length, uint8_t *signature,
size_t signature_size, size_t *signature_length)
{
int ret = 0;
struct uECC_Curve_t *curve = uECC_secp256r1();

ret = uECC_sign(key_buffer, hash, hash_length, signature, curve);
if (!ret) {
return PSA_ERROR_GENERIC_ERROR;
}

*signature_length = signature_size;

(void)alg;
(void)attributes;
(void)key_buffer_size;
return PSA_SUCCESS;
}

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,
size_t hash_length, const uint8_t *signature,
size_t signature_length)
{
int ret = 0;
struct uECC_Curve_t *curve = uECC_secp256r1();

ret = uECC_verify(key_buffer, hash, hash_length, signature, curve);
if (!ret) {
return PSA_ERROR_GENERIC_ERROR;
}

(void)alg;
(void)attributes;
(void)key_buffer_size;
(void)signature_length;
return PSA_SUCCESS;
}