Skip to content

Commit 0124fdc

Browse files
authored
Merge pull request #21461 from Lukas-Luger/pr/psa-ecc-pub-key-derivation
sys/psa_crypto: Adding ecc p256r1 pub key derivation
2 parents 5fa6340 + a932a4e commit 0124fdc

File tree

10 files changed

+95
-11
lines changed

10 files changed

+95
-11
lines changed

pkg/driver_cryptocell_310/include/psa_cryptocell_310_ecc_common.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ psa_status_t cryptocell_310_common_ecc_generate_key_pair(uint8_t *priv_key_buffe
7575
uint32_t *pub_key_buffer_length,
7676
CRYS_ECPKI_DomainID_t domain);
7777

78+
/**
79+
* @brief Common ECC public key derivation function (not supported)
80+
*
81+
* @param priv_key_buffer Input buffer to read ECC private key
82+
* @param pub_key_buffer Output buffer to write ECC public key
83+
* @param priv_key_buffer_length Length of private key
84+
* @param pub_key_buffer_length Output pointer to write public key length
85+
* @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t
86+
* @return psa_status_t
87+
*/
88+
psa_status_t cryptocell_310_common_ecc_derive_pub_key(const uint8_t *priv_key_buffer,
89+
uint8_t *pub_key_buffer,
90+
uint32_t priv_key_buffer_length,
91+
uint32_t *pub_key_buffer_length,
92+
CRYS_ECPKI_DomainID_t domain);
93+
7894
/**
7995
* @brief Common ECC signature function
8096
*

pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ psa_status_t cryptocell_310_common_ecc_generate_key_pair(uint8_t *priv_key_buffe
7272
return PSA_SUCCESS;
7373
}
7474

75+
psa_status_t cryptocell_310_common_ecc_derive_pub_key(const uint8_t *priv_key_buffer,
76+
uint8_t *pub_key_buffer,
77+
uint32_t priv_key_buffer_length,
78+
uint32_t *pub_key_buffer_length,
79+
CRYS_ECPKI_DomainID_t domain)
80+
{
81+
(void) priv_key_buffer;
82+
(void) pub_key_buffer;
83+
(void) priv_key_buffer_length;
84+
(void) pub_key_buffer_length;
85+
(void) domain;
86+
DEBUG("cryptocell_310 does not support key derivation.\n");
87+
return PSA_ERROR_NOT_SUPPORTED;
88+
}
89+
7590
psa_status_t cryptocell_310_common_ecc_sign(const uint8_t *priv_key,
7691
uint32_t priv_key_size,
7792
const uint8_t *input,

pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ psa_status_t psa_generate_ecc_p256r1_key_pair( const psa_key_attributes_t *attr
3535
CRYS_ECPKI_DomainID_secp256r1);
3636
}
3737

38+
psa_status_t psa_derive_ecc_p256r1_public_key( const uint8_t *priv_key_buffer, uint8_t *pub_key_buffer,
39+
size_t priv_key_buffer_length,
40+
size_t *pub_key_buffer_length)
41+
{
42+
return cryptocell_310_common_ecc_derive_pub_key(priv_key_buffer, pub_key_buffer,
43+
(uint32_t)priv_key_buffer_length,
44+
(uint32_t *)pub_key_buffer_length,
45+
CRYS_ECPKI_DomainID_secp256r1);
46+
}
47+
3848
psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes,
3949
psa_algorithm_t alg,
4050
const uint8_t *key_buffer,

pkg/micro-ecc/psa_uecc/p256.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,26 @@ psa_status_t psa_generate_ecc_p256r1_key_pair( const psa_key_attributes_t *attr
4848
return PSA_SUCCESS;
4949
}
5050

51+
psa_status_t psa_derive_ecc_p256r1_public_key(const uint8_t *priv_key_buffer, uint8_t *pub_key_buffer,
52+
size_t priv_key_buffer_length,
53+
size_t *pub_key_buffer_length)
54+
{
55+
int ret = 0;
56+
57+
const struct uECC_Curve_t *curve = uECC_secp256r1();
58+
59+
*pub_key_buffer_length = uECC_curve_public_key_size(curve) + 1;
60+
61+
pub_key_buffer[0] = 0x04;
62+
ret = uECC_compute_public_key(priv_key_buffer, pub_key_buffer+1, curve);
63+
if (!ret) {
64+
return PSA_ERROR_GENERIC_ERROR;
65+
}
66+
67+
(void)priv_key_buffer_length;
68+
return PSA_SUCCESS;
69+
}
70+
5171
psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes,
5272
psa_algorithm_t alg, const uint8_t *key_buffer,
5373
size_t key_buffer_size, const uint8_t *hash,

sys/psa_crypto/doc.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,12 @@ names in uppercase and add the prefix `CONFIG_MODULE_` to all of them.
257257
- psa_asymmetric_ecc_p192r1_custom_backend
258258
- psa_asymmetric_ecc_p192r1_backend_microecc
259259

260-
#### NIST ECC P192
260+
#### NIST ECC P256
261261
- psa_asymmetric_ecc_p256r1
262262
- psa_asymmetric_ecc_p256r1_backend_periph
263+
264+
@warning Cryptocell 310 does not support public key derivation from a private key.
265+
263266
- psa_asymmetric_ecc_p256r1_custom_backend
264267
- psa_asymmetric_ecc_p256r1_backend_microecc
265268

sys/psa_crypto/include/psa_ecc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ psa_status_t psa_generate_ecc_p256r1_key_pair( const psa_key_attributes_t *attr
9292
size_t *priv_key_buffer_length,
9393
size_t *pub_key_buffer_length);
9494

95+
/**
96+
* @brief Low level wrapper function to call a driver for deriving an P256R1 public key from the private key.
97+
*/
98+
psa_status_t psa_derive_ecc_p256r1_public_key( const uint8_t *priv_key_buffer, uint8_t *pub_key_buffer,
99+
size_t priv_key_buffer_length,
100+
size_t *pub_key_buffer_length);
101+
95102
/**
96103
* @brief Low level wrapper function to call a driver for an ECC hash signature
97104
* with a SECP 256 R1 key.

sys/psa_crypto/psa_crypto.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,8 +1306,9 @@ psa_status_t psa_export_key(psa_key_id_t key,
13061306
}
13071307

13081308
if (!PSA_KEY_TYPE_IS_ECC(slot->attr.type) ||
1309-
PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type) != PSA_ECC_FAMILY_TWISTED_EDWARDS) {
1310-
/* key export is currently only supported for ed25519 keys */
1309+
(PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type) != PSA_ECC_FAMILY_TWISTED_EDWARDS &&
1310+
PSA_KEY_TYPE_ECC_GET_FAMILY(slot->attr.type) != PSA_ECC_FAMILY_SECP_R1)) {
1311+
/* key export is currently only supported for ed25519 and secp_r1 keys */
13111312
status = PSA_ERROR_NOT_SUPPORTED;
13121313
unlock_status = psa_unlock_key_slot(slot);
13131314
if (unlock_status != PSA_SUCCESS) {
@@ -1925,7 +1926,7 @@ psa_status_t psa_sign_hash(psa_key_id_t key,
19251926
return PSA_ERROR_NOT_SUPPORTED;
19261927
}
19271928

1928-
if (!PSA_ALG_IS_SIGN_HASH(alg) || hash_length != PSA_HASH_LENGTH(alg)) {
1929+
if (!PSA_ALG_IS_SIGN_HASH(alg) || (hash_length != PSA_HASH_LENGTH(alg) && PSA_ALG_IS_HASH(alg))) {
19291930
return PSA_ERROR_INVALID_ARGUMENT;
19301931
}
19311932

@@ -2029,7 +2030,7 @@ psa_status_t psa_verify_hash(psa_key_id_t key,
20292030
return PSA_ERROR_NOT_SUPPORTED;
20302031
}
20312032

2032-
if (!PSA_ALG_IS_SIGN_HASH(alg) || hash_length != PSA_HASH_LENGTH(alg)) {
2033+
if (!PSA_ALG_IS_SIGN_HASH(alg) || (hash_length != PSA_HASH_LENGTH(alg) && PSA_ALG_IS_HASH(alg))) {
20332034
return PSA_ERROR_INVALID_ARGUMENT;
20342035
}
20352036

sys/psa_crypto/psa_crypto_algorithm_dispatch.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,7 @@ psa_status_t psa_algorithm_dispatch_import_key(const psa_key_attributes_t *attri
576576
#endif
577577
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1)
578578
case PSA_ECC_P256_R1:
579-
// todo: support for Weierstrass curves
580-
(void)slot;
581-
ret = PSA_ERROR_NOT_SUPPORTED;
579+
ret = psa_derive_ecc_p256r1_public_key(data, pubkey_data, data_length, pubkey_data_len);
582580
break;
583581
#endif
584582
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519)

tests/sys/psa_crypto_ecdsa/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ USEMODULE += psa_hash
99
USEMODULE += psa_hash_sha_256
1010
USEMODULE += psa_asymmetric
1111
USEMODULE += psa_asymmetric_ecc_p256r1
12+
USEMODULE += psa_asymmetric_ecc_p256r1_custom_backend
13+
USEMODULE += psa_asymmetric_ecc_p256r1_backend_microecc
1214

1315
CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
1416
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=1

tests/sys/psa_crypto_ecdsa/test_ecdsa_p256_vectors.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* [1] https://www.rfc-editor.org/rfc/rfc6979#appendix-A.2.5
3030
*/
3131
static const psa_algorithm_t algo = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
32-
static const psa_key_type_t type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
32+
static const psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
3333

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

63-
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
63+
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT);
6464
psa_set_key_algorithm(&key_attr, algo);
6565
psa_set_key_bits(&key_attr, PSA_BYTES_TO_BITS(sizeof(private_key)));
6666
psa_set_key_type(&key_attr, type);
6767

6868
psa_status_t status;
69-
status = psa_import_key(&key_attr, public_key, sizeof(public_key), &key_id);
69+
status = psa_import_key(&key_attr, private_key, sizeof(private_key), &key_id);
7070
if (status != PSA_SUCCESS) {
7171
return status;
7272
}
7373

74+
/* testing public key derivation */
75+
uint8_t exp_public_key[sizeof(public_key)];
76+
size_t length;
77+
status = psa_export_public_key(key_id, exp_public_key, sizeof(public_key), &length);
78+
if (status != PSA_SUCCESS) {
79+
return status;
80+
}
81+
82+
if (0 != memcmp(public_key, exp_public_key, sizeof(public_key))) {
83+
return -1;
84+
}
85+
7486
status = psa_verify_message(key_id, algo, message, sizeof(message), signature, sizeof(signature));
7587

7688
psa_destroy_key(key_id);

0 commit comments

Comments
 (0)