Add API for exporting a SiLabs SE ECC key to a wolf ECC key (silabs_ecc_export_public). Add API for supporting export of a vault's public key. Add an ECC signature example for SiLabs.

This commit is contained in:
David Garske
2023-06-27 09:36:41 -07:00
parent 48dc288b83
commit 500b66eb36
3 changed files with 161 additions and 2 deletions

View File

@ -23,7 +23,11 @@
* SiLabs Simplicity Studio's CLI example */ * SiLabs Simplicity Studio's CLI example */
#include <wolfssl/wolfcrypt/settings.h> #include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/signature.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/logging.h> #include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/wc_port.h>
#include <wolfssl/wolfcrypt/error-crypt.h> #include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfcrypt/test/test.h> #include <wolfcrypt/test/test.h>
#include <wolfcrypt/benchmark/benchmark.h> #include <wolfcrypt/benchmark/benchmark.h>
@ -82,4 +86,91 @@ void wolf_bench(sl_cli_command_arg_t *arguments)
(void)ret; (void)ret;
} }
/* ecc key gen, sign and verify examples */
#define TEST_ECC_KEYSZ 32
#define TEST_DATA_SIZE 128
#define TEST_KEYGEN_TRIES 100
#define TEST_ECDSA_TRIES 100
void wolf_ecc_test(sl_cli_command_arg_t *arguments)
{
int ret = 0, i, j;
byte data[TEST_DATA_SIZE];
word32 dataLen = (word32)sizeof(data);
byte sig[ECC_MAX_SIG_SIZE];
word32 sigLen;
WC_RNG rng;
ecc_key eccKey;
memset(&rng, 0, sizeof(rng));
memset(&eccKey, 0, sizeof(eccKey));
wolfSSL_Debugging_ON();
wolfCrypt_Init();
/* test data */
for (i=0; i<(int)dataLen; i++) {
data[i] = (byte)i;
}
ret = wc_InitRng(&rng);
if (ret != 0) {
goto exit;
}
for (i=0; i<TEST_KEYGEN_TRIES; i++) {
ret = wc_ecc_init_ex(&eccKey, NULL, 0);
if (ret == 0) {
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
/* Load ecc_key with vault's public key.
* When only the public area of a key is loaded silabs_ecc.c
* (silabs_ecc_sign_hash) will use the vault key to sign */
ret = silabs_ecc_load_vault(&eccKey);
#else
ret = wc_ecc_make_key(&rng, TEST_ECC_KEYSZ, &eccKey);
#endif
}
for (j=0; j<TEST_ECDSA_TRIES; j++) {
if (ret == 0) {
/* generate signature using ecc key */
sigLen = (word32)sizeof(sig);
ret = wc_SignatureGenerate(
WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC,
data, dataLen,
sig, &sigLen,
&eccKey, (word32)sizeof(eccKey),
&rng);
}
if (ret == 0) {
ret = wc_SignatureVerify(
WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC,
data, dataLen,
sig, sigLen,
&eccKey, (word32)sizeof(eccKey));
}
if (ret == 0) {
fprintf(stderr, "Verification Passed %d %d\n", i, j);
}
else {
fprintf(stderr, "Verification failed!! (ret %d) %d %d\n",
ret, i, j);
break;
}
} /* sign/verify tries */
wc_ecc_free(&eccKey);
if (ret != 0)
break;
} /* key gen tries */
exit:
wc_FreeRng(&rng);
wolfCrypt_Cleanup();
(void)arguments;
}

View File

@ -52,7 +52,7 @@ static sl_se_key_descriptor_t private_device_key =
SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY
#endif #endif
static sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id) static sl_se_key_type_t silabs_map_key_type(ecc_curve_id curve_id)
{ {
sl_se_key_type_t res = SILABS_UNSUPPORTED_KEY_TYPE; sl_se_key_type_t res = SILABS_UNSUPPORTED_KEY_TYPE;
@ -286,7 +286,7 @@ int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key,
sl_stat = sl_se_ecdh_compute_shared_secret( sl_stat = sl_se_ecdh_compute_shared_secret(
&cmd, &cmd,
&(private_key->key), &private_key->key,
&pub_key, &pub_key,
&key_out); &key_out);
@ -298,4 +298,66 @@ int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key,
return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E; return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E;
} }
int silabs_ecc_export_public(ecc_key* key, sl_se_key_descriptor_t* seKey)
{
int ret;
sl_status_t sl_stat;
sl_se_command_context_t cmd;
if (key == NULL || seKey == NULL)
return BAD_FUNC_ARG;
if (seKey->type == SL_SE_KEY_TYPE_ECC_P192)
ret = wc_ecc_set_curve(key, 24, ECC_SECP192R1);
else if (seKey->type == SL_SE_KEY_TYPE_ECC_P256)
ret = wc_ecc_set_curve(key, 32, ECC_SECP256R1);
#ifdef SL_SE_KEY_TYPE_ECC_P384
else if (seKey->type == SL_SE_KEY_TYPE_ECC_P384)
ret = wc_ecc_set_curve(key, 48, ECC_SECP384R1);
#endif
#ifdef SL_SE_KEY_TYPE_ECC_P521
else if (seKey->type == SL_SE_KEY_TYPE_ECC_P521)
ret = wc_ecc_set_curve(key, 66, ECC_SECP521R1);
#endif
else
ret = ECC_CURVE_OID_E;
if (ret != 0)
return ret;
key->type = ECC_PUBLICKEY;
key->key.size = key->dp->size;
key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT;
key->key.flags = (SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY);
sl_stat = sl_se_get_storage_size(&key->key,
&key->key.storage.location.buffer.size);
key->key.storage.location.buffer.pointer = key->key_raw;
if (sl_stat == SL_STATUS_OK) {
sl_stat = sl_se_export_public_key(&cmd, seKey, &key->key);
}
if (sl_stat != SL_STATUS_OK) {
ret = WC_HW_E;
}
if (ret == 0) {
/* export public x and y */
ret = mp_read_unsigned_bin(key->pubkey.x,
key->key.storage.location.buffer.pointer,
key->key.size);
}
if (ret == 0) {
ret = mp_read_unsigned_bin(key->pubkey.y,
key->key.storage.location.buffer.pointer + key->key.size,
key->key.size);
}
return ret;
}
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
int silabs_ecc_load_vault(ecc_key* key)
{
return silabs_ecc_export_public(key, &private_device_key);
}
#endif
#endif /* WOLFSSL_SILABS_SE_ACCEL */ #endif /* WOLFSSL_SILABS_SE_ACCEL */

View File

@ -47,10 +47,16 @@ int silabs_ecc_verify_hash (const byte* sig, word32 siglen,
int silabs_ecc_make_key(ecc_key* key, int keysize); int silabs_ecc_make_key(ecc_key* key, int keysize);
int silabs_ecc_import(ecc_key* key, word32 keysize, int pub, int priv); int silabs_ecc_import(ecc_key* key, word32 keysize, int pub, int priv);
int silabs_ecc_export_public(ecc_key* key, sl_se_key_descriptor_t* seKey);
int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key,
byte* out, word32* outlen); byte* out, word32* outlen);
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
int silabs_ecc_load_vault(ecc_key* key);
#endif
#endif /* WOLFSSL_SILABS_SE_ACCEL */ #endif /* WOLFSSL_SILABS_SE_ACCEL */
#endif /* _SILABS_ECC_H_ */ #endif /* _SILABS_ECC_H_ */