Fix for signing with vault to only use if private key is not supplied. Refactor the silabs ECC key import code. Added checks for all silabs_ecc return codes.

This commit is contained in:
David Garske
2023-06-15 16:26:49 -07:00
parent fc153ff273
commit cde4e8e13d
3 changed files with 93 additions and 190 deletions

View File

@ -10357,7 +10357,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
}
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
if (err == MP_OKAY)
err = silabs_ecc_import(key, keysize);
err = silabs_ecc_import(key, keysize, 1, 0);
#elif defined(WOLFSSL_SE050)
if (err == MP_OKAY) {
/* reset key ID, in case used before */
@ -10604,18 +10604,6 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
ret = mp_read_unsigned_bin(key->k, priv, privSz);
}
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
if (ret == MP_OKAY)
ret = mp_read_unsigned_bin(key->k, priv, privSz);
if (ret == MP_OKAY) {
if (pub) {
ret = silabs_ecc_import(key, key->dp->size);
}
else {
ret = silabs_ecc_import_private(key, key->dp->size);
}
}
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
#ifdef WOLFSSL_CAAM_BLACK_KEY_SM
@ -10733,6 +10721,10 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
if (ret == 0) {
ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
}
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
if (ret == 0) {
ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
}
#endif
return ret;
@ -10962,11 +10954,6 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
&keySz, keySz, WC_TYPE_UNSIGNED_BIN);
}
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
keySz = key->dp->size;
if (err == MP_OKAY) {
err = silabs_ecc_sig_to_rs(key, keySz);
}
#elif defined(WOLFSSL_CRYPTOCELL)
if (err == MP_OKAY) {
keyRaw[0] = ECC_POINT_UNCOMP;
@ -11046,9 +11033,6 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
/* Hardware doesn't support loading private key */
err = NOT_COMPILED_IN;
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
err = silabs_ecc_import_private_raw(key, keySz, d, encType);
#elif defined(WOLFSSL_CRYPTOCELL)
key->type = ECC_PRIVATEKEY;
@ -11130,6 +11114,10 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
if (err == MP_OKAY) {
err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
}
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
if (err == MP_OKAY) {
err = silabs_ecc_import(key, keySz, 1, (d != NULL));
}
#endif
if (err != MP_OKAY) {

View File

@ -56,7 +56,7 @@ 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;
switch(curve_id) {
switch (curve_id) {
case ECC_SECP192R1:
res = SL_SE_KEY_TYPE_ECC_P192;
break;
@ -99,29 +99,38 @@ static sl_se_key_type_t silabs_map_key_type (ecc_curve_id curve_id)
int silabs_ecc_sign_hash(const byte* in, word32 inlen, byte* out,
word32 *outlen, ecc_key* key)
{
sl_status_t sl_stat = sl_se_init_command_context(&(key->cmd_ctx));
sl_status_t sl_stat;
sl_se_key_descriptor_t* slkey = &key->key;
word32 siglen = *outlen;
sl_stat = sl_se_validate_key(&(key->key));
if (key->dp->size * 2 <= (int)siglen) {
if ((int)siglen >= key->dp->size * 2) {
siglen = key->dp->size * 2;
}
sl_stat = sl_se_ecc_sign(
&(key->cmd_ctx),
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
&private_device_key,
#else
&(key->key),
#endif
0,
1,
in,
inlen,
out,
siglen
);
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
/* if signing and not private key provided then use vault key */
if (key->type != ECC_PRIVATEKEY ||
mp_unsigned_bin_size(wc_ecc_key_get_priv(key)) == 0) {
slkey = &private_device_key;
}
#endif
sl_stat = sl_se_init_command_context(&key->cmd_ctx);
if (sl_stat == SL_STATUS_OK) {
sl_stat = sl_se_validate_key(slkey);
}
if (sl_stat == SL_STATUS_OK) {
sl_stat = sl_se_ecc_sign(
&key->cmd_ctx,
slkey,
0,
1,
in,
inlen,
out,
siglen
);
}
return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E;
}
@ -131,18 +140,18 @@ int silabs_ecc_verify_hash(const byte* sig, word32 siglen,
const byte* hash, word32 hashlen,
int* stat, ecc_key* key)
{
sl_status_t sl_stat = sl_se_init_command_context(&(key->cmd_ctx));
sl_stat = sl_se_ecc_verify(
&(key->cmd_ctx),
&(key->key),
0,
1,
hash,
hashlen,
sig,
siglen);
sl_status_t sl_stat = sl_se_init_command_context(&key->cmd_ctx);
if (sl_stat == SL_STATUS_OK) {
sl_stat = sl_se_ecc_verify(
&key->cmd_ctx,
&key->key,
0,
1,
hash,
hashlen,
sig,
siglen);
}
if (sl_stat == SL_STATUS_OK) {
*stat = 1;
} else if (sl_stat == SL_STATUS_INVALID_SIGNATURE) {
@ -150,7 +159,6 @@ int silabs_ecc_verify_hash(const byte* sig, word32 siglen,
} else {
return WC_HW_E;
}
return 0;
}
#endif
@ -160,7 +168,7 @@ int silabs_ecc_make_key(ecc_key* key, int keysize)
sl_status_t sl_stat;
key->key.type = silabs_map_key_type(key->dp->id);
if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type)
if (key->key.type == SILABS_UNSUPPORTED_KEY_TYPE)
return WC_HW_E;
key->key.size = keysize;
@ -171,43 +179,42 @@ int silabs_ecc_make_key(ecc_key* key, int keysize)
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) {
key->key.storage.location.buffer.pointer = key->key_raw;
sl_stat = sl_se_generate_key(&key->cmd_ctx,
&key->key);
}
if (sl_stat == SL_STATUS_OK) {
key->type = ECC_PRIVATEKEY;
sl_stat = sl_se_generate_key(&(key->cmd_ctx),
&(key->key));
key->type = ECC_PRIVATEKEY;
/* copy key to mp components */
mp_read_unsigned_bin (key->pubkey.x,
key->key.storage.location.buffer.pointer,
keysize);
mp_read_unsigned_bin (key->pubkey.y,
key->key.storage.location.buffer.pointer + keysize,
keysize);
mp_read_unsigned_bin (wc_ecc_key_get_priv(key),
key->key.storage.location.buffer.pointer +
(2 * keysize),
keysize);
/* copy key to mp components */
mp_read_unsigned_bin(key->pubkey.x,
key->key.storage.location.buffer.pointer, keysize);
mp_read_unsigned_bin(key->pubkey.y,
key->key.storage.location.buffer.pointer + keysize, keysize);
mp_read_unsigned_bin(wc_ecc_key_get_priv(key),
key->key.storage.location.buffer.pointer + (2 * keysize), keysize);
}
return (sl_stat == SL_STATUS_OK) ? 0 : WC_HW_E;
}
int silabs_ecc_import(ecc_key* key, word32 keysize)
int silabs_ecc_import(ecc_key* key, word32 keysize, int pub, int priv)
{
sl_status_t sl_stat;
int err = MP_OKAY;
word32 used = keysize;
word32 used;
key->key.type = silabs_map_key_type(key->dp->id);
if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type)
if (key->key.type == SILABS_UNSUPPORTED_KEY_TYPE)
return WC_HW_E;
key->key.size = keysize;
key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT;
key->key.flags = (SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY |
SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY |
SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY);
key->key.flags = (
(pub ? SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY : 0) |
(priv ? SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY : 0) |
SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY);
sl_stat = sl_se_get_storage_size(&key->key,
&key->key.storage.location.buffer.size);
@ -215,117 +222,32 @@ int silabs_ecc_import(ecc_key* key, word32 keysize)
if (sl_stat != SL_STATUS_OK)
return WC_HW_E;
key->type = ECC_PRIVATEKEY;
if (priv && pub)
key->type = ECC_PRIVATEKEY;
else if (priv)
key->type = ECC_PRIVATEKEY_ONLY;
else
key->type = ECC_PUBLICKEY;
/* copy key from mp components */
if (err == MP_OKAY)
if (err == MP_OKAY && pub) {
used = keysize;
err = wc_export_int(key->pubkey.x,
key->key.storage.location.buffer.pointer,
&used, keysize,
WC_TYPE_UNSIGNED_BIN);
if (err == MP_OKAY)
key->key.storage.location.buffer.pointer,
&used, keysize, WC_TYPE_UNSIGNED_BIN);
}
if (err == MP_OKAY && pub) {
used = keysize;
err = wc_export_int(key->pubkey.y,
key->key.storage.location.buffer.pointer + keysize,
&used, keysize,
WC_TYPE_UNSIGNED_BIN);
if (err == MP_OKAY)
key->key.storage.location.buffer.pointer + keysize,
&used, keysize, WC_TYPE_UNSIGNED_BIN);
}
if (err == MP_OKAY && priv) {
used = keysize;
err = wc_export_int(wc_ecc_key_get_priv(key),
key->key.storage.location.buffer.pointer +
(2 * keysize),
&used, keysize, WC_TYPE_UNSIGNED_BIN);
return err;
}
int silabs_ecc_import_private(ecc_key* key, word32 keysize)
{
sl_status_t sl_stat;
int ret = 0;
word32 keySz = keysize;
key->key.type = silabs_map_key_type(key->dp->id);
if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type)
return WC_HW_E;
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_PRIVATE_KEY |
SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY);
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)
return WC_HW_E;
ret = wc_export_int(wc_ecc_key_get_priv(key),
key->key.storage.location.buffer.pointer, &keySz, keySz,
WC_TYPE_UNSIGNED_BIN);
if (keySz != keysize)
ret = WC_HW_E;
return ret;
}
int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz)
{
sl_status_t sl_stat;
int err = MP_OKAY;
key->key.type = silabs_map_key_type(key->dp->id);
if (SILABS_UNSUPPORTED_KEY_TYPE == key->key.type)
return WC_HW_E;
key->key.size = keySz;
key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT;
key->key.flags = (SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY |
SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY);
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)
return WC_HW_E;
keySz = key->dp->size;
if (err == MP_OKAY) {
err = wc_export_int(key->pubkey.x,
key->key.storage.location.buffer.pointer,
&keySz, keySz, WC_TYPE_UNSIGNED_BIN);
key->key.storage.location.buffer.pointer + (keysize * 2),
&used, keysize, WC_TYPE_UNSIGNED_BIN);
}
if (err == MP_OKAY) {
err = wc_export_int(key->pubkey.y,
key->key.storage.location.buffer.pointer + keySz,
&keySz, keySz, WC_TYPE_UNSIGNED_BIN);
}
return err;
}
int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, const char* d,
int encType)
{
sl_status_t sl_stat;
int err = MP_OKAY;
key->type = ECC_PRIVATEKEY;
key->key.flags |= SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY;
sl_stat = sl_se_get_storage_size(&key->key,
&key->key.storage.location.buffer.size);
if (sl_stat != SL_STATUS_OK)
return WC_HW_E;
if (encType == WC_TYPE_HEX_STR)
err = mp_read_radix(wc_ecc_key_get_priv(key), d, MP_RADIX_HEX);
else
err = mp_read_unsigned_bin(wc_ecc_key_get_priv(key), (const byte*)d,
key->dp->size);
if (err == MP_OKAY) {
err = wc_export_int(wc_ecc_key_get_priv(key),
key->key.storage.location.buffer.pointer + (2 * keySz), &keySz,
keySz, WC_TYPE_UNSIGNED_BIN);
}
return err;
}

View File

@ -44,16 +44,9 @@ int silabs_ecc_verify_hash (const byte* sig, word32 siglen,
int* stat, ecc_key* key);
int silabs_ecc_make_key(ecc_key* key, int keysize);
int silabs_ecc_import(ecc_key* key, word32 keysize);
int silabs_ecc_import_private(ecc_key* key, word32 keysize);
int silabs_ecc_sig_to_rs(ecc_key* key, word32 keySz);
int silabs_ecc_import_private_raw(ecc_key* key, word32 keySz, const char* d, int encType);
int silabs_ecc_import(ecc_key* key, word32 keysize, int pub, int priv);
int silabs_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key,
byte* out, word32* outlen);