Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions pkg/driver_cryptocell_310/include/psa_cryptocell_310_ecc_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@
uint32_t *pub_key_buffer_length,
CRYS_ECPKI_DomainID_t domain);

/**
* @brief Common ECC public key derivation function (not supported)
*
* @param priv_key_buffer Input buffer to read ECC private key
* @param pub_key_buffer Output buffer to write ECC public key
* @param priv_key_buffer_length Length of private key
* @param pub_key_buffer_length Output pointer to write public key length
* @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t
* @return psa_status_t
*/
psa_status_t cryptocell_310_common_ecc_derive_pub_key(const uint8_t *priv_key_buffer,
uint8_t *pub_key_buffer,
uint32_t priv_key_buffer_length,
uint32_t *pub_key_buffer_length,
CRYS_ECPKI_DomainID_t domain);

/**
* @brief Common ECC signature function
*
Expand Down Expand Up @@ -102,7 +118,7 @@
*
* @param pub_key Pointer to ECC public key
* @param pub_key_size Size of public key
* @param input Input to verify (hash or original message depending on @c hash_mode )

Check warning on line 121 in pkg/driver_cryptocell_310/include/psa_cryptocell_310_ecc_common.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
* @param input_length Length of the input
* @param signature Buffer containing the signature to be verified
* @param signature_length Actual length of the signature
Expand Down
15 changes: 15 additions & 0 deletions pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,20 @@
&TempECCKGBuff, &FipsBuff);
cryptocell_310_disable();
if (ret != CRYS_OK) {
DEBUG("CRYS_ECPKI_GenKeyPair failed with %s\n", cryptocell310_status_to_humanly_readable(ret));

Check warning on line 54 in pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
return CRYS_to_psa_error(ret);
}

ret = CRYS_ECPKI_ExportPrivKey(&priv_key, priv_key_buffer, priv_key_buffer_length);
if (ret != CRYS_OK) {
DEBUG("CRYS_ECPKI_ExportPrivKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));

Check warning on line 60 in pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
return CRYS_to_psa_error(ret);
}

ret = CRYS_ECPKI_ExportPublKey(&pub_key, CRYS_EC_PointUncompressed, pub_key_buffer,
pub_key_buffer_length);
if (ret != CRYS_OK) {
DEBUG("CRYS_ECPKI_ExportPubKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));

Check warning on line 67 in pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
return CRYS_to_psa_error(ret);
}

Expand All @@ -72,6 +72,21 @@
return PSA_SUCCESS;
}

psa_status_t cryptocell_310_common_ecc_derive_pub_key(const uint8_t *priv_key_buffer,
uint8_t *pub_key_buffer,
uint32_t priv_key_buffer_length,
uint32_t *pub_key_buffer_length,
CRYS_ECPKI_DomainID_t domain)
{
(void) priv_key_buffer;
(void) pub_key_buffer;
(void) priv_key_buffer_length;
(void) pub_key_buffer_length;
(void) domain;
DEBUG("cryptocell_310 does not support key derivation.\n");
return PSA_ERROR_NOT_SUPPORTED;
}

psa_status_t cryptocell_310_common_ecc_sign(const uint8_t *priv_key,
uint32_t priv_key_size,
const uint8_t *input,
Expand All @@ -96,13 +111,13 @@

ret = CRYS_ECPKI_BuildPrivKey(pDomain, priv_key, priv_key_size, &user_priv_key);
if (ret != CRYS_OK) {
DEBUG("CRYS_ECPKI_BuildPrivKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));

Check warning on line 114 in pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
goto done;
}

cryptocell_310_enable();
ret = CRYS_ECDSA_Sign(rndState_ptr, rndGenerateVectFunc,
&SignUserContext, &user_priv_key, hash_mode, (uint8_t *)input, input_length,

Check warning on line 120 in pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
signature, (uint32_t *)signature_length);
cryptocell_310_disable();
if (ret != CRYS_OK) {
Expand Down Expand Up @@ -143,7 +158,7 @@
* */
ret = CRYS_ECPKI_BuildPublKey(pDomain, (uint8_t *)pub_key, pub_key_size, &user_pub_key);
if (ret != CRYS_OK) {
DEBUG("CRYS_ECPKI_BuildPublKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));

Check warning on line 161 in pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
return CRYS_to_psa_error(ret);
}

Expand Down
10 changes: 10 additions & 0 deletions pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@
CRYS_ECPKI_DomainID_secp256r1);
}

psa_status_t psa_derive_ecc_p256r1_public_key( const uint8_t *priv_key_buffer, uint8_t *pub_key_buffer,

Check warning on line 38 in pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
size_t priv_key_buffer_length,
size_t *pub_key_buffer_length)
{
return cryptocell_310_common_ecc_derive_pub_key(priv_key_buffer, pub_key_buffer,
(uint32_t)priv_key_buffer_length,
(uint32_t *)pub_key_buffer_length,
CRYS_ECPKI_DomainID_secp256r1);
}

psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes,
psa_algorithm_t alg,
const uint8_t *key_buffer,
Expand Down
20 changes: 20 additions & 0 deletions pkg/micro-ecc/psa_uecc/p256.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@
return PSA_SUCCESS;
}

psa_status_t psa_derive_ecc_p256r1_public_key(const 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;

const struct uECC_Curve_t *curve = uECC_secp256r1();

*pub_key_buffer_length = uECC_curve_public_key_size(curve) + 1;

pub_key_buffer[0] = 0x04;
ret = uECC_compute_public_key(priv_key_buffer, pub_key_buffer+1, curve);
if (!ret) {
return PSA_ERROR_GENERIC_ERROR;
}

(void)priv_key_buffer_length;
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,
Expand Down Expand Up @@ -81,12 +101,12 @@
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);

Check warning on line 104 in pkg/micro-ecc/psa_uecc/p256.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
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);

Check warning on line 109 in pkg/micro-ecc/psa_uecc/p256.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
}

psa_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes,
Expand Down
5 changes: 4 additions & 1 deletion sys/psa_crypto/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,12 @@ names in uppercase and add the prefix `CONFIG_MODULE_` to all of them.
- psa_asymmetric_ecc_p192r1_custom_backend
- psa_asymmetric_ecc_p192r1_backend_microecc

#### NIST ECC P192
#### NIST ECC P256
- psa_asymmetric_ecc_p256r1
- psa_asymmetric_ecc_p256r1_backend_periph

@warning Cryptocell 310 does not support public key derivation from a private key.

- psa_asymmetric_ecc_p256r1_custom_backend
- psa_asymmetric_ecc_p256r1_backend_microecc

Expand Down
7 changes: 7 additions & 0 deletions sys/psa_crypto/include/psa_ecc.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ 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 deriving an P256R1 public key from the private key.
*/
psa_status_t psa_derive_ecc_p256r1_public_key( const 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 a SECP 256 R1 key.
Expand Down
9 changes: 5 additions & 4 deletions sys/psa_crypto/psa_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -1306,8 +1306,9 @@ psa_status_t psa_export_key(psa_key_id_t key,
}

if (!PSA_KEY_TYPE_IS_ECC(slot->attr.type) ||
PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type) != PSA_ECC_FAMILY_TWISTED_EDWARDS) {
/* key export is currently only supported for ed25519 keys */
(PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type) != PSA_ECC_FAMILY_TWISTED_EDWARDS &&
PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type) != PSA_ECC_FAMILY_SECP_R1)) {
/* key export is currently only supported for ed25519 and secp_r1 keys */
status = PSA_ERROR_NOT_SUPPORTED;
unlock_status = psa_unlock_key_slot(slot);
if (unlock_status != PSA_SUCCESS) {
Expand Down Expand Up @@ -1925,7 +1926,7 @@ psa_status_t psa_sign_hash(psa_key_id_t key,
return PSA_ERROR_NOT_SUPPORTED;
}

if (!PSA_ALG_IS_SIGN_HASH(alg) || hash_length != PSA_HASH_LENGTH(alg)) {
if (!PSA_ALG_IS_SIGN_HASH(alg) || (hash_length != PSA_HASH_LENGTH(alg) && PSA_ALG_IS_HASH(alg))) {
return PSA_ERROR_INVALID_ARGUMENT;
}

Expand Down Expand Up @@ -2029,7 +2030,7 @@ psa_status_t psa_verify_hash(psa_key_id_t key,
return PSA_ERROR_NOT_SUPPORTED;
}

if (!PSA_ALG_IS_SIGN_HASH(alg) || hash_length != PSA_HASH_LENGTH(alg)) {
if (!PSA_ALG_IS_SIGN_HASH(alg) || (hash_length != PSA_HASH_LENGTH(alg) && PSA_ALG_IS_HASH(alg))) {
return PSA_ERROR_INVALID_ARGUMENT;
}

Expand Down
4 changes: 1 addition & 3 deletions sys/psa_crypto/psa_crypto_algorithm_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,9 +576,7 @@ psa_status_t psa_algorithm_dispatch_import_key(const psa_key_attributes_t *attri
#endif
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1)
case PSA_ECC_P256_R1:
// todo: support for Weierstrass curves
(void)slot;
ret = PSA_ERROR_NOT_SUPPORTED;
ret = psa_derive_ecc_p256r1_public_key(data, pubkey_data, data_length, pubkey_data_len);
break;
#endif
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519)
Expand Down
2 changes: 2 additions & 0 deletions tests/sys/psa_crypto_ecdsa/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ USEMODULE += psa_hash
USEMODULE += psa_hash_sha_256
USEMODULE += psa_asymmetric
USEMODULE += psa_asymmetric_ecc_p256r1
USEMODULE += psa_asymmetric_ecc_p256r1_custom_backend
USEMODULE += psa_asymmetric_ecc_p256r1_backend_microecc

CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=1
Expand Down
18 changes: 15 additions & 3 deletions tests/sys/psa_crypto_ecdsa/test_ecdsa_p256_vectors.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* [1] https://www.rfc-editor.org/rfc/rfc6979#appendix-A.2.5
*/
static const psa_algorithm_t algo = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
static const psa_key_type_t type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
static const psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);

static const uint8_t private_key[] = {0xC9, 0xAF, 0xA9, 0xD8, 0x45, 0xBA, 0x75, 0x16, 0x6B, 0x5C,
0x21, 0x57, 0x67, 0xB1, 0xD6, 0x93, 0x4E, 0x50, 0xC3, 0xDB, 0x36, 0xE8, 0x9B, 0x12, 0x7B, 0x8A,
Expand Down Expand Up @@ -60,17 +60,29 @@ psa_status_t test_ecdsa_p256_vectors(void) {
psa_key_attributes_t key_attr = psa_key_attributes_init();
psa_key_id_t key_id;

psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT);
psa_set_key_algorithm(&key_attr, algo);
psa_set_key_bits(&key_attr, PSA_BYTES_TO_BITS(sizeof(private_key)));
psa_set_key_type(&key_attr, type);

psa_status_t status;
status = psa_import_key(&key_attr, public_key, sizeof(public_key), &key_id);
status = psa_import_key(&key_attr, private_key, sizeof(private_key), &key_id);
if (status != PSA_SUCCESS) {
return status;
}

/* testing public key derivation */
uint8_t exp_public_key[sizeof(public_key)];
size_t length;
status = psa_export_public_key(key_id, exp_public_key, sizeof(public_key), &length);
if (status != PSA_SUCCESS) {
return status;
}

if (0 != memcmp(public_key, exp_public_key, sizeof(public_key))) {
return -1;
}

status = psa_verify_message(key_id, algo, message, sizeof(message), signature, sizeof(signature));

psa_destroy_key(key_id);
Expand Down
Loading