From cde4e8e13d9ebdcc5636595b64f6bf41c7850003 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 15 Jun 2023 16:26:49 -0700 Subject: [PATCH] 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. --- wolfcrypt/src/ecc.c | 30 +-- wolfcrypt/src/port/silabs/silabs_ecc.c | 244 +++++++-------------- wolfssl/wolfcrypt/port/silabs/silabs_ecc.h | 9 +- 3 files changed, 93 insertions(+), 190 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 8522c95e7..0e4dac739 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -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) { diff --git a/wolfcrypt/src/port/silabs/silabs_ecc.c b/wolfcrypt/src/port/silabs/silabs_ecc.c index 5858313c8..669e2dd4e 100644 --- a/wolfcrypt/src/port/silabs/silabs_ecc.c +++ b/wolfcrypt/src/port/silabs/silabs_ecc.c @@ -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; } diff --git a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h index 4820b577f..88cc5c02b 100644 --- a/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h +++ b/wolfssl/wolfcrypt/port/silabs/silabs_ecc.h @@ -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);