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) #elif defined(WOLFSSL_SILABS_SE_ACCEL)
if (err == MP_OKAY) if (err == MP_OKAY)
err = silabs_ecc_import(key, keysize); err = silabs_ecc_import(key, keysize, 1, 0);
#elif defined(WOLFSSL_SE050) #elif defined(WOLFSSL_SE050)
if (err == MP_OKAY) { if (err == MP_OKAY) {
/* reset key ID, in case used before */ /* 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); 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) #elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) { if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
#ifdef WOLFSSL_CAAM_BLACK_KEY_SM #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) { if (ret == 0) {
ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size); 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 #endif
return ret; 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], err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
&keySz, keySz, WC_TYPE_UNSIGNED_BIN); &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) #elif defined(WOLFSSL_CRYPTOCELL)
if (err == MP_OKAY) { if (err == MP_OKAY) {
keyRaw[0] = ECC_POINT_UNCOMP; 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 */ /* Hardware doesn't support loading private key */
err = NOT_COMPILED_IN; err = NOT_COMPILED_IN;
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
err = silabs_ecc_import_private_raw(key, keySz, d, encType);
#elif defined(WOLFSSL_CRYPTOCELL) #elif defined(WOLFSSL_CRYPTOCELL)
key->type = ECC_PRIVATEKEY; 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) { if (err == MP_OKAY) {
err = wc_MAXQ10XX_EccSetKey(key, key->dp->size); 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 #endif
if (err != MP_OKAY) { 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; sl_se_key_type_t res = SILABS_UNSUPPORTED_KEY_TYPE;
switch(curve_id) { switch (curve_id) {
case ECC_SECP192R1: case ECC_SECP192R1:
res = SL_SE_KEY_TYPE_ECC_P192; res = SL_SE_KEY_TYPE_ECC_P192;
break; 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, int silabs_ecc_sign_hash(const byte* in, word32 inlen, byte* out,
word32 *outlen, ecc_key* key) 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; word32 siglen = *outlen;
sl_stat = sl_se_validate_key(&(key->key)); if ((int)siglen >= key->dp->size * 2) {
if (key->dp->size * 2 <= (int)siglen) {
siglen = key->dp->size * 2; siglen = key->dp->size * 2;
} }
sl_stat = sl_se_ecc_sign( #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
&(key->cmd_ctx), /* if signing and not private key provided then use vault key */
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) if (key->type != ECC_PRIVATEKEY ||
&private_device_key, mp_unsigned_bin_size(wc_ecc_key_get_priv(key)) == 0) {
#else slkey = &private_device_key;
&(key->key), }
#endif #endif
0,
1, sl_stat = sl_se_init_command_context(&key->cmd_ctx);
in, if (sl_stat == SL_STATUS_OK) {
inlen, sl_stat = sl_se_validate_key(slkey);
out, }
siglen 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; 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, const byte* hash, word32 hashlen,
int* stat, ecc_key* key) int* stat, ecc_key* key)
{ {
sl_status_t sl_stat = sl_se_init_command_context(&(key->cmd_ctx)); 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( sl_stat = sl_se_ecc_verify(
&(key->cmd_ctx), &key->cmd_ctx,
&(key->key), &key->key,
0, 0,
1, 1,
hash, hash,
hashlen, hashlen,
sig, sig,
siglen); siglen);
}
if (sl_stat == SL_STATUS_OK) { if (sl_stat == SL_STATUS_OK) {
*stat = 1; *stat = 1;
} else if (sl_stat == SL_STATUS_INVALID_SIGNATURE) { } else if (sl_stat == SL_STATUS_INVALID_SIGNATURE) {
@ -150,7 +159,6 @@ int silabs_ecc_verify_hash(const byte* sig, word32 siglen,
} else { } else {
return WC_HW_E; return WC_HW_E;
} }
return 0; return 0;
} }
#endif #endif
@ -160,7 +168,7 @@ int silabs_ecc_make_key(ecc_key* key, int keysize)
sl_status_t sl_stat; sl_status_t sl_stat;
key->key.type = silabs_map_key_type(key->dp->id); 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; return WC_HW_E;
key->key.size = keysize; 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, sl_stat = sl_se_get_storage_size(&key->key,
&key->key.storage.location.buffer.size); &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), /* copy key to mp components */
&(key->key)); mp_read_unsigned_bin(key->pubkey.x,
key->key.storage.location.buffer.pointer, keysize);
key->type = ECC_PRIVATEKEY; mp_read_unsigned_bin(key->pubkey.y,
key->key.storage.location.buffer.pointer + keysize, keysize);
/* copy key to mp components */ mp_read_unsigned_bin(wc_ecc_key_get_priv(key),
mp_read_unsigned_bin (key->pubkey.x, key->key.storage.location.buffer.pointer + (2 * keysize), keysize);
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; 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; sl_status_t sl_stat;
int err = MP_OKAY; int err = MP_OKAY;
word32 used = keysize; word32 used;
key->key.type = silabs_map_key_type(key->dp->id); 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; return WC_HW_E;
key->key.size = keysize; key->key.size = keysize;
key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT; key->key.storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT;
key->key.flags = (SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY | key->key.flags = (
SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY | (pub ? SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY : 0) |
SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY); (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, sl_stat = sl_se_get_storage_size(&key->key,
&key->key.storage.location.buffer.size); &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) if (sl_stat != SL_STATUS_OK)
return WC_HW_E; 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 */ /* copy key from mp components */
if (err == MP_OKAY) if (err == MP_OKAY && pub) {
used = keysize;
err = wc_export_int(key->pubkey.x, err = wc_export_int(key->pubkey.x,
key->key.storage.location.buffer.pointer, key->key.storage.location.buffer.pointer,
&used, keysize, &used, keysize, WC_TYPE_UNSIGNED_BIN);
WC_TYPE_UNSIGNED_BIN); }
if (err == MP_OKAY) if (err == MP_OKAY && pub) {
used = keysize;
err = wc_export_int(key->pubkey.y, err = wc_export_int(key->pubkey.y,
key->key.storage.location.buffer.pointer + keysize, key->key.storage.location.buffer.pointer + keysize,
&used, keysize, &used, keysize, WC_TYPE_UNSIGNED_BIN);
WC_TYPE_UNSIGNED_BIN); }
if (err == MP_OKAY) if (err == MP_OKAY && priv) {
used = keysize;
err = wc_export_int(wc_ecc_key_get_priv(key), err = wc_export_int(wc_ecc_key_get_priv(key),
key->key.storage.location.buffer.pointer + key->key.storage.location.buffer.pointer + (keysize * 2),
(2 * keysize), &used, keysize, WC_TYPE_UNSIGNED_BIN);
&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);
} }
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; return err;
} }

View File

@ -44,16 +44,9 @@ int silabs_ecc_verify_hash (const byte* sig, word32 siglen,
int* stat, ecc_key* key); int* stat, ecc_key* key);
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 silabs_ecc_import(ecc_key* key, word32 keysize, int pub, int priv);
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_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);