From f63a799f18f84ff965a3afa267a6703f4231b671 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 1 Nov 2021 09:52:12 -0700 Subject: [PATCH 1/7] Fix for ECC create key public export size and key size bits. Fix for key store ID vs key ID. --- wolfcrypt/src/port/nxp/se050_port.c | 46 +++++++++---------------- wolfssl/wolfcrypt/port/nxp/se050_port.h | 16 ++++----- 2 files changed, 23 insertions(+), 39 deletions(-) diff --git a/wolfcrypt/src/port/nxp/se050_port.c b/wolfcrypt/src/port/nxp/se050_port.c index 92b42dd16..079fbc5ea 100644 --- a/wolfcrypt/src/port/nxp/se050_port.c +++ b/wolfcrypt/src/port/nxp/se050_port.c @@ -60,10 +60,6 @@ struct ecc_key; #include #include -/* AES 55 = keyStoreId - Implementation specific ID */ -/* ECC SIGN 56 = keyStoreId - Implementation specific ID */ -/* ECC VERIFY 57 = keyStoreId - Implementation specific ID */ -/* ED25519 58 = keyStoreId - Implementation specific ID */ /* Global variables */ static sss_session_t *cfg_se050_i2c_pi; @@ -116,17 +112,9 @@ int se050_allocate_key(int keyType) static int keyId_allocator = 100; switch (keyType) { case SE050_AES_KEY: - keyId = SE050_KEYID_AES; - break; case SE050_ECC_SIGN: - keyId = SE050_KEYID_ECC_SIGN; - break; case SE050_ECC_VERIFY: - keyId = SE050_KEYID_ECC_VERIFY; - break; case SE050_ED25519: - keyId = SE050_KEYID_ED25519; - break; case SE050_KEYID_ANY: keyId = keyId_allocator++; break; @@ -277,7 +265,7 @@ int se050_aes_set_key(Aes* aes, const byte* key, word32 len, status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 55); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES); } if (status == kStatus_SSS_Success) { @@ -332,7 +320,7 @@ int se050_aes_crypt(Aes* aes, const byte* in, byte* out, word32 sz, int dir, status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 55); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES); } if (status == kStatus_SSS_Success) { @@ -389,7 +377,7 @@ void se050_aes_free(Aes* aes) status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 55); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES); } if (status == kStatus_SSS_Success) { @@ -447,7 +435,7 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 70); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } if (status == kStatus_SSS_Success) { @@ -550,7 +538,7 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 61); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } if (status == kStatus_SSS_Success) { status = sss_key_object_init(&newKey, &host_keystore); @@ -586,7 +574,7 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 60); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } if (status == kStatus_SSS_Success) { status = sss_key_object_init(&newKey, &host_keystore); @@ -641,7 +629,7 @@ int se050_ecc_free_key(struct ecc_key* key) status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 60); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } if (status == kStatus_SSS_Success) { status = sss_key_object_init(&keyObject, &host_keystore); @@ -666,7 +654,7 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) sss_object_t keyPair; sss_key_store_t host_keystore; int keyId = se050_allocate_key(SE050_KEYID_ANY); - uint8_t keyPairExport[MAX_ECC_BYTES]; + uint8_t keyPairExport[MAX_ECC_BYTES*2]; size_t keyPairExportLen = sizeof(keyPairExport); size_t keyPairExportBitLen = sizeof(keyPairExport) * 8; int ret; @@ -684,19 +672,19 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 60); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } if (status == kStatus_SSS_Success) { status = sss_key_object_init(&keyPair, &host_keystore); } if (status == kStatus_SSS_Success) { status = sss_key_object_allocate_handle(&keyPair, keyId, - kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, 256, + kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, keySize*8, kKeyObject_Mode_None); } if (status == kStatus_SSS_Success) { status = sss_key_store_generate_key(&host_keystore, &keyPair, - 256, NULL); + keySize*8, NULL); } if (status == kStatus_SSS_Success) { status = sss_key_store_get_key(&host_keystore, &keyPair, @@ -749,7 +737,7 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 60); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } if (status == kStatus_SSS_Success) { @@ -765,7 +753,7 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, } if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore_2, 60); + status = sss_key_store_allocate(&host_keystore_2, SE050_KEYSTOREID_ECC); } if (status == kStatus_SSS_Success) { @@ -844,7 +832,7 @@ int se050_ed25519_create_key(ed25519_key* key) status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 55); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519); } if (status == kStatus_SSS_Success) { @@ -894,7 +882,7 @@ void se050_ed25519_free_key(ed25519_key* key) status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 55); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519); } if (status == kStatus_SSS_Success) { status = sss_key_object_init(&newKey, &host_keystore); @@ -931,7 +919,7 @@ int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 55); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519); } if (status == kStatus_SSS_Success) { @@ -989,7 +977,7 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, 61); + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519); } if (status == kStatus_SSS_Success) { diff --git a/wolfssl/wolfcrypt/port/nxp/se050_port.h b/wolfssl/wolfcrypt/port/nxp/se050_port.h index bd3759236..afcf1db8c 100644 --- a/wolfssl/wolfcrypt/port/nxp/se050_port.h +++ b/wolfssl/wolfcrypt/port/nxp/se050_port.h @@ -54,19 +54,15 @@ /* Default key ID's */ -#ifndef SE050_KEYID_AES -#define SE050_KEYID_AES 55 +#ifndef SE050_KEYSTOREID_AES +#define SE050_KEYSTOREID_AES 55 #endif -#ifndef SE050_KEYID_ECC_SIGN -#define SE050_KEYID_ECC_SIGN 56 +#ifndef SE050_KEYSTOREID_ED25519 +#define SE050_KEYSTOREID_ED25519 58 #endif -#ifndef SE050_KEYID_ECC_VERIFY -#define SE050_KEYID_ECC_VERIFY 57 +#ifndef SE050_KEYSTOREID_ECC +#define SE050_KEYSTOREID_ECC 60 #endif -#ifndef SE050_KEYID_ED25519 -#define SE050_KEYID_ED25519 58 -#endif - enum { SSS_BLOCK_SIZE = 512 From 2abb2eae7d6bc0028f53115ddc0e061cd6f01541 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 1 Nov 2021 16:18:59 -0700 Subject: [PATCH 2/7] Changed NXP SE050 to not use symmetric offloading by default. If desired use `WOLFSSL_SE050_HASH` and `WOLFSSL_SE050_CRYPT`. --- configure.ac | 3 +++ wolfcrypt/src/aes.c | 10 +++++----- wolfcrypt/src/port/nxp/README.md | 3 +++ wolfcrypt/src/sha.c | 4 ++-- wolfcrypt/src/sha256.c | 6 +++--- wolfcrypt/src/sha512.c | 20 ++++++++++---------- wolfssl/wolfcrypt/sha.h | 4 ++-- wolfssl/wolfcrypt/sha256.h | 4 ++-- 8 files changed, 30 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index 72d96f51d..482282c0b 100644 --- a/configure.ac +++ b/configure.ac @@ -1451,6 +1451,9 @@ AC_ARG_WITH([se050], # Requires AES direct AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT" + # Does not support SHA2-512 224/256 + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NOSHA512_224 -DWOLFSSL_NOSHA512_256" + AC_MSG_RESULT([yes]) else AC_MSG_RESULT([yes]) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index eb41c25d0..50cd7d4e6 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -68,7 +68,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #ifdef WOLFSSL_IMXRT_DCP #include #endif -#ifdef WOLFSSL_SE050 +#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT) #include #endif @@ -867,7 +867,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #elif defined(WOLFSSL_DEVCRYPTO_AES) /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT) static int AES_ECB_encrypt(Aes* aes, const byte* inBlock, byte* outBlock, int sz) { @@ -2598,7 +2598,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) return wc_AesSetKey(aes, userKey, keylen, iv, dir); } -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT) int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir) { @@ -3876,7 +3876,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #elif defined(WOLFSSL_DEVCRYPTO_CBC) /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT) int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION, @@ -10363,7 +10363,7 @@ void wc_AesFree(Aes* aes) } #endif -#if defined(WOLFSSL_SE050) +#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT) se050_aes_free(aes); #endif diff --git a/wolfcrypt/src/port/nxp/README.md b/wolfcrypt/src/port/nxp/README.md index ba47856ce..ad2ebe9de 100644 --- a/wolfcrypt/src/port/nxp/README.md +++ b/wolfcrypt/src/port/nxp/README.md @@ -44,6 +44,9 @@ make Where `PATH` is the directory location of `simw-top`. Example: `./configure --enable-debug --disable-shared --with-se050=/home/pi/simw-top CFLAGS="-DWOLFSSL_SE050_INIT"` +To enable AES Cipher support use `WOLFSSL_SE050_CRYPT` +To enable SHA-1 and SHA-2 support use `WOLFSSL_SE050_HASH` + ## Building Examples Confirm that you are able to run the examples from the directory: diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index c5b46d5e5..cf94def92 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -336,7 +336,7 @@ #elif defined(WOLFSSL_SILABS_SE_ACCEL) /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) @@ -846,7 +846,7 @@ void wc_ShaFree(wc_Sha* sha) #ifdef WOLFSSL_PIC32MZ_HASH wc_ShaPic32Free(sha); #endif -#ifdef WOLFSSL_SE050 +#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) se050_hash_free(&sha->se050Ctx); #endif #if (defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \ diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 117c834d0..0aa3ff75c 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -184,7 +184,7 @@ where 0 <= L < 2^64. (!defined(WOLFSSL_ESP32WROOM32_CRYPT) || defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)) && \ (!defined(WOLFSSL_RENESAS_TSIP_CRYPT) || defined(NO_WOLFSSL_RENESAS_TSIP_HASH)) && \ !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ - !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050) + !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050_HASH) static int InitSha256(wc_Sha256* sha256) @@ -585,7 +585,7 @@ static int InitSha256(wc_Sha256* sha256) !defined(WOLFSSL_QNX_CAAM) /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId) @@ -1411,7 +1411,7 @@ static int InitSha256(wc_Sha256* sha256) return ret; } -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId) diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 6d59192a7..77b472241 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -49,7 +49,7 @@ #include #endif -#ifdef WOLFSSL_SE050 +#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include #endif @@ -203,7 +203,7 @@ #elif defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) int wc_InitSha512(wc_Sha512* sha512) { if (sha512 == NULL) @@ -952,7 +952,7 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #else @@ -1063,7 +1063,7 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512) #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #else @@ -1135,7 +1135,7 @@ int wc_Sha512Final(wc_Sha512* sha512, byte* hash) #endif /* WOLFSSL_KCAPI_HASH */ -#ifndef WOLFSSL_SE050 +#if !defined(WOLFSSL_SE050) || !defined(WOLFSSL_SE050_HASH) int wc_InitSha512(wc_Sha512* sha512) { return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID); @@ -1217,7 +1217,7 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) } #endif /* OPENSSL_EXTRA */ #endif /* WOLFSSL_SHA512 */ -#endif /* !WOLFSSL_SE050 */ +#endif /* !WOLFSSL_SE050 || !WOLFSSL_SE050_HASH */ /* -------------------------------------------------------------------------- */ @@ -1228,7 +1228,7 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) #if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \ !defined(WOLFSSL_QNX_CAAM) /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) { if (sha384 == NULL) { @@ -1566,7 +1566,7 @@ int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len) #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #else int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash) @@ -1585,7 +1585,7 @@ void wc_Sha512_224Free(wc_Sha512* sha) } #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #else @@ -1630,7 +1630,7 @@ int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len) } #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #else int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash) diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index 6944b1897..8338264d2 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -110,7 +110,7 @@ enum { #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" #else -#if defined(WOLFSSL_SE050) +#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" #endif @@ -118,7 +118,7 @@ enum { struct wc_Sha { #ifdef FREESCALE_LTC_SHA ltc_hash_ctx_t ctx; -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) SE050_HASH_Context se050Ctx; #elif defined(STM32_HASH) STM32_HASH_Context stmCtx; diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 7759823f3..13ddea2da 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -144,7 +144,7 @@ enum { #include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h" #else -#if defined(WOLFSSL_SE050) +#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #include "wolfssl/wolfcrypt/port/nxp/se050_port.h" #endif @@ -152,7 +152,7 @@ enum { struct wc_Sha256 { #ifdef FREESCALE_LTC_SHA ltc_hash_ctx_t ctx; -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) SE050_HASH_Context se050Ctx; #elif defined(STM32_HASH_SHA2) STM32_HASH_Context stmCtx; From 495cac8ad73dfed5a0f36cef20a43f092e0e1140 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 2 Nov 2021 16:34:19 -0700 Subject: [PATCH 3/7] Fixes for NXP SE050 key sizes and key id use. Related to #4526 --- wolfcrypt/src/ecc.c | 14 +- wolfcrypt/src/port/nxp/README.md | 2 +- wolfcrypt/src/port/nxp/se050_port.c | 657 ++++++++++++++---------- wolfssl/wolfcrypt/port/nxp/se050_port.h | 13 +- 4 files changed, 389 insertions(+), 297 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index d6f354a49..dc57c2394 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1218,7 +1218,7 @@ static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); #if (defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || !defined(WOLFSSL_SP_MATH)) && \ !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_CRYPTOCELL) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, mp_int* prime, mp_int* order); #endif @@ -8052,7 +8052,7 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_CRYPTOCELL) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) /* is ecc point on curve described by dp ? */ int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) @@ -8516,7 +8516,8 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) int err = MP_OKAY; #ifndef WOLFSSL_SP_MATH #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ + !defined(WOLFSSL_SE050) mp_int* b = NULL; #ifdef USE_ECC_B_PARAM DECLARE_CURVE_SPECS(curve, 4); @@ -8527,7 +8528,7 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) DECLARE_CURVE_SPECS(curve, 3); #endif /* USE_ECC_B_PARAM */ #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && - !WOLFSSL_CRYPTOCELL && !WOLFSSL_SILABS_SE_ACCEL */ + !WOLFSSL_CRYPTOCELL && !WOLFSSL_SILABS_SE_ACCEL && !WOLFSSL_SE050 */ #endif /* !WOLFSSL_SP_MATH */ ASSERT_SAVED_VECTOR_REGISTERS(); @@ -8558,7 +8559,8 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) #ifndef WOLFSSL_SP_MATH #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ - defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SILABS_SE_ACCEL) + defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SILABS_SE_ACCEL) || \ + defined(WOLFSSL_SE050) /* consider key check success on HW crypto * ex: ATECC508/608A, CryptoCell and Silabs */ @@ -8678,9 +8680,9 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) FREE_CURVE_SPECS(); #endif /* WOLFSSL_ATECC508A */ -#else (void)partial; (void)priv; +#else return WC_KEY_SIZE_E; #endif /* !WOLFSSL_SP_MATH */ return err; diff --git a/wolfcrypt/src/port/nxp/README.md b/wolfcrypt/src/port/nxp/README.md index ad2ebe9de..26fab2e35 100644 --- a/wolfcrypt/src/port/nxp/README.md +++ b/wolfcrypt/src/port/nxp/README.md @@ -42,7 +42,7 @@ make `` Where `PATH` is the directory location of `simw-top`. -Example: `./configure --enable-debug --disable-shared --with-se050=/home/pi/simw-top CFLAGS="-DWOLFSSL_SE050_INIT"` +Example: `./configure --with-se050=/home/pi/simw-top CFLAGS="-DWOLFSSL_SE050_INIT"` To enable AES Cipher support use `WOLFSSL_SE050_CRYPT` To enable SHA-1 and SHA-2 support use `WOLFSSL_SE050_HASH` diff --git a/wolfcrypt/src/port/nxp/se050_port.c b/wolfcrypt/src/port/nxp/se050_port.c index 079fbc5ea..4a59bad45 100644 --- a/wolfcrypt/src/port/nxp/se050_port.c +++ b/wolfcrypt/src/port/nxp/se050_port.c @@ -60,6 +60,9 @@ struct ecc_key; #include #include +#ifndef SE050_ECC_DER_MAX +#define SE050_ECC_DER_MAX 256 +#endif /* Global variables */ static sss_session_t *cfg_se050_i2c_pi; @@ -112,10 +115,9 @@ int se050_allocate_key(int keyType) static int keyId_allocator = 100; switch (keyType) { case SE050_AES_KEY: - case SE050_ECC_SIGN: - case SE050_ECC_VERIFY: - case SE050_ED25519: - case SE050_KEYID_ANY: + case SE050_ECC_KEY: + case SE050_ED25519_KEY: + case SE050_ANY_KEY: keyId = keyId_allocator++; break; } @@ -125,9 +127,9 @@ int se050_allocate_key(int keyType) #ifndef WC_NO_RNG int se050_get_random_number(uint32_t count, uint8_t* rand_out) { + int ret = 0; sss_status_t status; sss_rng_context_t rng; - int ret = 0; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; @@ -137,16 +139,16 @@ int se050_get_random_number(uint32_t count, uint8_t* rand_out) return BAD_MUTEX_E; } status = sss_rng_context_init(&rng, cfg_se050_i2c_pi); - - if (status == kStatus_SSS_Success) + if (status == kStatus_SSS_Success) { status = sss_rng_get_random(&rng, rand_out, count); - - if (status == kStatus_SSS_Success) + } + if (status == kStatus_SSS_Success) { status = sss_rng_context_free(&rng); - + } if (status != kStatus_SSS_Success) { ret = RNG_FAILURE_E; } + wolfSSL_CryptHwMutexUnLock(); return ret; @@ -193,6 +195,7 @@ int se050_hash_update(SE050_HASH_Context* se050Ctx, const byte* data, word32 len int se050_hash_final(SE050_HASH_Context* se050Ctx, byte* hash, size_t digestLen, sss_algorithm_t algo) { + int ret; sss_status_t status; sss_digest_t digest_ctx; const byte* data = se050Ctx->msg; @@ -228,9 +231,11 @@ int se050_hash_final(SE050_HASH_Context* se050Ctx, byte* hash, size_t digestLen, sss_digest_context_free(&digest_ctx); } + ret = (status == kStatus_SSS_Success) ? 0 : WC_HW_E; + wolfSSL_CryptHwMutexUnLock(); - return 0; + return ret; } void se050_hash_free(SE050_HASH_Context* se050Ctx) @@ -239,108 +244,111 @@ void se050_hash_free(SE050_HASH_Context* se050Ctx) } #ifndef NO_AES -int se050_aes_set_key(Aes* aes, const byte* key, word32 len, +int se050_aes_set_key(Aes* aes, const byte* key, word32 keylen, const byte* iv, int dir) { + int ret = 0; sss_status_t status; sss_object_t newKey; sss_key_store_t host_keystore; - int keyId = se050_allocate_key(SE050_AES_KEY); - int ret = BAD_MUTEX_E; + int keyId; + int keyCreated = 0; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + (void)dir; (void)iv; - aes->rounds = len/4 + 6; - aes->keyId = keyId; - - if (wolfSSL_CryptHwMutexLock() != 0) { - return BAD_MUTEX_E; - } + aes->rounds = keylen/4 + 6; status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); - if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES); } - if (status == kStatus_SSS_Success) { status = sss_key_object_init(&newKey, &host_keystore); } - - /* aes_test runs perfectly with kKeyObject_Mode_Persistent, - * but might have caused previous board to have no free key slots */ if (status == kStatus_SSS_Success) { + keyId = se050_allocate_key(SE050_AES_KEY); status = sss_key_object_allocate_handle(&newKey, keyId, - kSSS_KeyPart_Default, kSSS_CipherType_AES, len, + kSSS_KeyPart_Default, kSSS_CipherType_AES, keylen, kKeyObject_Mode_Transient); } + if (status == kStatus_SSS_Success) { + keyCreated = 1; + status = sss_key_store_set_key(&host_keystore, &newKey, key, keylen, + keylen * 8, NULL, 0); + } if (status == kStatus_SSS_Success) { - status = sss_key_store_set_key(&host_keystore, &newKey, key, len, - len * 8, NULL, 0); + aes->keyId = keyId; + ret = 0; + } + else { + if (keyCreated) { + sss_key_object_free(&newKey); + } + ret = WC_HW_E; } wolfSSL_CryptHwMutexUnLock(); - if (status != kStatus_SSS_Success) - ret = WC_HW_E; return ret; } - int se050_aes_crypt(Aes* aes, const byte* in, byte* out, word32 sz, int dir, sss_algorithm_t algorithm) { + int ret = 0; sss_status_t status; sss_object_t keyObject; - sss_mode_t mode; sss_key_store_t host_keystore; - int ret = BAD_MUTEX_E; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } - - XMEMSET(&mode, 0, sizeof(mode)); - - if (dir == AES_DECRYPTION) - mode = kMode_SSS_Decrypt; - else if (dir == AES_ENCRYPTION) - mode = kMode_SSS_Encrypt; + if (aes->keyId <= 0) { + return BAD_FUNC_ARG; + } if (wolfSSL_CryptHwMutexLock() != 0) { return BAD_MUTEX_E; } status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); - if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES); } - if (status == kStatus_SSS_Success) { status = sss_key_object_init(&keyObject, &host_keystore); } - if (status == kStatus_SSS_Success) { status = sss_key_object_get_handle(&keyObject, aes->keyId); } /* The first call to this function needs an initialization call, * subsequent calls just need to call update */ - if (aes->ctxInitDone == 0) { - aes->ctxInitDone = 1; + if (status == kStatus_SSS_Success && aes->ctxInitDone == 0) { + sss_mode_t mode; + + XMEMSET(&mode, 0, sizeof(mode)); + if (dir == AES_DECRYPTION) + mode = kMode_SSS_Decrypt; + else if (dir == AES_ENCRYPTION) + mode = kMode_SSS_Encrypt; + if (status == kStatus_SSS_Success) { status = sss_symmetric_context_init(&aes->aes_ctx, cfg_se050_i2c_pi, &keyObject, algorithm, mode); } - if (status == kStatus_SSS_Success) { + aes->ctxInitDone = 1; status = sss_cipher_init(&aes->aes_ctx, (uint8_t*)aes->reg, sizeof(aes->reg)); } @@ -350,10 +358,10 @@ int se050_aes_crypt(Aes* aes, const byte* in, byte* out, word32 sz, int dir, status = sss_cipher_update(&aes->aes_ctx, in, sz, out, &outSz); } + ret = (status == kStatus_SSS_Success) ? 0 : WC_HW_E; + wolfSSL_CryptHwMutexUnLock(); - if (status != kStatus_SSS_Success) - ret = WC_HW_E; return ret; } @@ -366,57 +374,106 @@ void se050_aes_free(Aes* aes) if (cfg_se050_i2c_pi == NULL) { return; } - - /* sets back to zero to indicate that a free has been called */ - aes->ctxInitDone = 0; + if (aes->keyId <= 0) { + return; + } if (wolfSSL_CryptHwMutexLock() != 0) { return; } - status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + if (aes->ctxInitDone) { + sss_symmetric_context_free(&aes->aes_ctx); + /* sets back to zero to indicate that a free has been called */ + aes->ctxInitDone = 0; + } + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_AES); } - if (status == kStatus_SSS_Success) { status = sss_key_object_init(&keyObject, &host_keystore); } - if (status == kStatus_SSS_Success) { status = sss_key_object_get_handle(&keyObject, aes->keyId); + aes->keyId = 0; } sss_key_object_free(&keyObject); - sss_symmetric_context_free(&aes->aes_ctx); - wolfSSL_CryptHwMutexUnLock(); } #endif /* !NO_AES */ #ifdef HAVE_ECC + +static sss_cipher_type_t se050_map_curve(int curve_id) +{ + sss_cipher_type_t curve_type; + switch (curve_id) { + case ECC_SECP160K1: + case ECC_SECP192K1: + case ECC_SECP224K1: + case ECC_SECP256K1: + curve_type = kSSS_CipherType_EC_NIST_K; + break; + case ECC_BRAINPOOLP160R1: + case ECC_BRAINPOOLP192R1: + case ECC_BRAINPOOLP224R1: + case ECC_BRAINPOOLP256R1: + case ECC_BRAINPOOLP320R1: + case ECC_BRAINPOOLP384R1: + case ECC_BRAINPOOLP512R1: + curve_type = kSSS_CipherType_EC_BRAINPOOL; + break; + case ECC_CURVE_DEF: + case ECC_SECP160R1: + case ECC_SECP192R1: + case ECC_SECP224R1: + case ECC_SECP256R1: + case ECC_SECP384R1: + case ECC_SECP521R1: + default: + curve_type = kSSS_CipherType_EC_NIST_P; + break; + } + return curve_type; +} + int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, word32 *outLen, struct ecc_key* key) { + int ret = 0; sss_status_t status; sss_asymmetric_t ctx_asymm; sss_key_store_t host_keystore; sss_object_t newKey; sss_algorithm_t algorithm = kAlgorithm_None; - int keyId = se050_allocate_key(SE050_ECC_SIGN); - int keysize = (word32)key->dp->size; - int ret = BAD_MUTEX_E; + int keySize; + int keySizeBits; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } + if (key->keyId <= 0) { + return BAD_FUNC_ARG; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } /* truncate if digest is larger than 64 */ if (inLen > 64) inLen = 64; + keySize = key->dp->size; + keySizeBits = keySize * 8; + if (keySizeBits > SSS_MAX_ECC_BITS) + keySizeBits = SSS_MAX_ECC_BITS; + if (inLen == 20) algorithm = kAlgorithm_SSS_SHA1; else if (inLen == 28) @@ -428,69 +485,50 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, else if (inLen == 64) algorithm = kAlgorithm_SSS_SHA512; - if (wolfSSL_CryptHwMutexLock() != 0) { - return BAD_MUTEX_E; - } - status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); - if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } - if (status == kStatus_SSS_Success) { status = sss_key_object_init(&newKey, &host_keystore); } - - if (status == kStatus_SSS_Success) { - status = sss_key_object_allocate_handle(&newKey, keyId, - kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, keysize, - kKeyObject_Mode_Transient); + status = sss_key_object_get_handle(&newKey, key->keyId); } - - if (status == kStatus_SSS_Success) { - status = sss_key_store_generate_key(&host_keystore, &newKey, - keysize * 8, NULL); - } - if (status == kStatus_SSS_Success) { status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, - &newKey, algorithm, kMode_SSS_Sign); + &newKey, algorithm, kMode_SSS_Sign); + if (status == kStatus_SSS_Success) { + size_t outLenSz = (size_t)*outLen; + status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t *)in, + inLen, out, &outLenSz); + *outLen = (word32)outLenSz; + } + sss_asymmetric_context_free(&ctx_asymm); } - if (status == kStatus_SSS_Success) { - size_t outLenSz = (size_t)*outLen; - status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t *)in, inLen, - out, &outLenSz); - *outLen = (word32)outLenSz; - } - sss_asymmetric_context_free(&ctx_asymm); - - wolfSSL_CryptHwMutexUnLock(); - - if (status == kStatus_SSS_Success) { - key->keyId = keyId; - ret = 0; - } - else { + if (status != kStatus_SSS_Success) { ret = WC_HW_E; } + wolfSSL_CryptHwMutexUnLock(); + return ret; } int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, word32 signatureLen, struct ecc_key* key, int* res) { + int ret = 0; sss_status_t status; sss_asymmetric_t ctx_asymm; sss_object_t newKey; sss_key_store_t host_keystore; sss_algorithm_t algorithm = kAlgorithm_None; - word32 derSz = 0; - int ret; - int keySize = (word32)key->dp->size; + int keySize; + int keySizeBits; + sss_cipher_type_t curveType; + int keyCreated = 0; *res = 0; @@ -498,6 +536,10 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, return WC_HW_E; } + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + if (hashLen > 64) hashLen = 64; @@ -512,80 +554,53 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, else if (hashLen == 64) algorithm = kAlgorithm_SSS_SHA512; - if (wolfSSL_CryptHwMutexLock() != 0) { - return BAD_MUTEX_E; + keySize = key->dp->size; + keySizeBits = keySize * 8; + if (keySizeBits > SSS_MAX_ECC_BITS) + keySizeBits = SSS_MAX_ECC_BITS; + curveType = se050_map_curve(key->dp->id); + + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); + if (status == kStatus_SSS_Success) { + status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); + } + if (status == kStatus_SSS_Success) { + status = sss_key_object_init(&newKey, &host_keystore); } /* this is run when a key was not generated and was instead passed in */ - if (key->keyId == 0) { - int keyId = se050_allocate_key(SE050_ECC_VERIFY); - byte* derBuf = NULL; + if (status == kStatus_SSS_Success) { + if (key->keyId == 0) { + byte derBuf[SE050_ECC_DER_MAX]; + word32 derSz; - ret = wc_EccKeyToPKCS8(key, NULL, &derSz); - if (ret != LENGTH_ONLY_E) { - return ret; + ret = wc_EccPublicKeyToDer(key, derBuf, (word32)sizeof(derBuf), 1); + if (ret >= 0) { + derSz = ret; + } + else { + status = kStatus_SSS_Fail; + } + if (status == kStatus_SSS_Success) { + key->keyId = se050_allocate_key(SE050_ECC_KEY); + status = sss_key_object_allocate_handle(&newKey, key->keyId, + kSSS_KeyPart_Public, curveType, keySize, + kKeyObject_Mode_Transient); + } + if (status == kStatus_SSS_Success) { + keyCreated = 1; + status = sss_key_store_set_key(&host_keystore, &newKey, derBuf, + derSz, keySizeBits, NULL, 0); + } } - - derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (derBuf == NULL) { - return MEMORY_E; - } - ret = wc_EccKeyToPKCS8(key, derBuf, &derSz); - if (ret <= 0) { - XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return ret; - } - - status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); - if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); - } - if (status == kStatus_SSS_Success) { - status = sss_key_object_init(&newKey, &host_keystore); - } - if (status == kStatus_SSS_Success) { - status = sss_key_object_allocate_handle(&newKey, keyId, - kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, derSz, - kKeyObject_Mode_Transient); - } - if (status == kStatus_SSS_Success) { - status = sss_key_store_set_key(&host_keystore, &newKey, derBuf, - derSz, keySize * 8, NULL, 0); - } - if (derBuf) { - XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - } - - if (status == kStatus_SSS_Success) { - status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, - &newKey, algorithm, kMode_SSS_Verify); - } - if (status == kStatus_SSS_Success) { - status = sss_asymmetric_verify_digest(&ctx_asymm, (uint8_t *)hash, - hashLen, signature, signatureLen); - } - - sss_asymmetric_context_free(&ctx_asymm); - - key->keyId = keyId; - } - /* this is run after a sign function has taken place */ - else { - status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); - - if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); - } - if (status == kStatus_SSS_Success) { - status = sss_key_object_init(&newKey, &host_keystore); - } - if (status == kStatus_SSS_Success) { + else { status = sss_key_object_get_handle(&newKey, key->keyId); } - if (status == kStatus_SSS_Success) { - status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, - &newKey, algorithm, kMode_SSS_Verify); - } + } + + if (status == kStatus_SSS_Success) { + status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, + &newKey, algorithm, kMode_SSS_Verify); if (status == kStatus_SSS_Success) { status = sss_asymmetric_verify_digest(&ctx_asymm, (uint8_t *)hash, hashLen, signature, signatureLen); @@ -593,41 +608,44 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, sss_asymmetric_context_free(&ctx_asymm); } - wolfSSL_CryptHwMutexUnLock(); if (status == kStatus_SSS_Success) { *res = 1; ret = 0; } else { - ret = WC_HW_E; + if (keyCreated) { + sss_key_object_free(&newKey); + key->keyId = 0; + } + if (ret == 0) + ret = WC_HW_E; } - return 0; + wolfSSL_CryptHwMutexUnLock(); + + return ret; } -int se050_ecc_free_key(struct ecc_key* key) +void se050_ecc_free_key(struct ecc_key* key) { sss_status_t status = kStatus_SSS_Success; sss_object_t keyObject; - int ret = WC_HW_E; sss_key_store_t host_keystore; if (cfg_se050_i2c_pi == NULL) { - return WC_HW_E; + return; } - if (key->keyId <= 0) { - return BAD_FUNC_ARG; + return; } if (wolfSSL_CryptHwMutexLock() != 0) { - return BAD_MUTEX_E; + return; } status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); - if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } @@ -639,37 +657,38 @@ int se050_ecc_free_key(struct ecc_key* key) } if (status == kStatus_SSS_Success) { sss_key_object_free(&keyObject); + key->keyId = 0; } wolfSSL_CryptHwMutexUnLock(); - - if (status != kStatus_SSS_Success) { - ret = WC_CLEANUP_E; - } - - return ret; } + int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) { - sss_status_t status = kStatus_SSS_Success; - sss_object_t keyPair; - sss_key_store_t host_keystore; - int keyId = se050_allocate_key(SE050_KEYID_ANY); - uint8_t keyPairExport[MAX_ECC_BYTES*2]; - size_t keyPairExportLen = sizeof(keyPairExport); - size_t keyPairExportBitLen = sizeof(keyPairExport) * 8; - int ret; + int ret = 0; + sss_status_t status = kStatus_SSS_Success; + sss_object_t keyPair; + sss_key_store_t host_keystore; + uint8_t derBuf[SE050_ECC_DER_MAX]; + size_t derSz = sizeof(derBuf); + size_t derSzBits = derSz * 8; + int keyId; + int keySizeBits; + sss_cipher_type_t curveType; + int keyCreated = 0; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } - - (void)curve_id; - if (wolfSSL_CryptHwMutexLock() != 0) { return BAD_MUTEX_E; } + curveType = se050_map_curve(curve_id); + keySizeBits = keySize * 8; + if (keySizeBits > SSS_MAX_ECC_BITS) + keySizeBits = SSS_MAX_ECC_BITS; + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); @@ -678,31 +697,41 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) status = sss_key_object_init(&keyPair, &host_keystore); } if (status == kStatus_SSS_Success) { + keyId = se050_allocate_key(SE050_ECC_KEY); status = sss_key_object_allocate_handle(&keyPair, keyId, - kSSS_KeyPart_Pair, kSSS_CipherType_EC_NIST_P, keySize*8, + kSSS_KeyPart_Pair, curveType, keySizeBits, kKeyObject_Mode_None); } if (status == kStatus_SSS_Success) { + keyCreated = 1; status = sss_key_store_generate_key(&host_keystore, &keyPair, - keySize*8, NULL); + keySizeBits, NULL); } if (status == kStatus_SSS_Success) { status = sss_key_store_get_key(&host_keystore, &keyPair, - keyPairExport, &keyPairExportLen, &keyPairExportBitLen); + derBuf, &derSz, &derSzBits); + } + if (status == kStatus_SSS_Success) { + word32 idx = 0; + ret = wc_EccPublicKeyDecode(derBuf, &idx, key, (word32)derSz); + if (ret != 0) { + status = kStatus_SSS_Fail; + } } - - wolfSSL_CryptHwMutexUnLock(); - if (status == kStatus_SSS_Success) { - mp_read_unsigned_bin(key->pubkey.x, keyPairExport, keySize); - mp_read_unsigned_bin(key->pubkey.y, keyPairExport + keySize, keySize); key->keyId = keyId; ret = 0; } else { - ret = WC_HW_E; + if (keyCreated) { + sss_key_object_free(&keyPair); + } + if (ret == 0) + ret = WC_HW_E; } + wolfSSL_CryptHwMutexUnLock(); + return ret; } @@ -710,24 +739,24 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outlen) { - sss_status_t status = kStatus_SSS_Success; - sss_key_store_t host_keystore; - sss_key_store_t host_keystore_2; - sss_object_t ref_private_key; - sss_object_t ref_public_key; - sss_object_t deriveKey; - sss_derive_key_t ctx_derive_key; - int keyId; - int keySize = (word32)public_key->dp->size; - size_t ecdhKeyLen = keySize; - size_t ecdhKeyBitLen = keySize; - int ret = WC_HW_E; + int ret; + sss_status_t status = kStatus_SSS_Success; + sss_key_store_t host_keystore; + sss_object_t ref_private_key; + sss_object_t ref_public_key; + sss_object_t deriveKey; + sss_derive_key_t ctx_derive_key; + int keyId; + int keySize; + size_t keySizeBits; + sss_cipher_type_t curveType; + int keyCreated = 0; + int deriveKeyCreated = 0; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } - - if (private_key->keyId <= 0 || public_key->keyId <= 0) { + if (private_key->keyId <= 0) { return BAD_FUNC_ARG; } @@ -735,75 +764,102 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, return BAD_MUTEX_E; } + keySize = private_key->dp->size; + keySizeBits = keySize * 8; + if (keySizeBits > SSS_MAX_ECC_BITS) + keySizeBits = SSS_MAX_ECC_BITS; + curveType = se050_map_curve(private_key->dp->id); + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } - if (status == kStatus_SSS_Success) { status = sss_key_object_init(&ref_public_key, &host_keystore); } - if (status == kStatus_SSS_Success) { - status = sss_key_object_get_handle(&ref_public_key, public_key->keyId); + status = sss_key_object_init(&ref_private_key, &host_keystore); } - - if (status == kStatus_SSS_Success) { - status = sss_key_store_context_init(&host_keystore_2, cfg_se050_i2c_pi); - } - - if (status == kStatus_SSS_Success) { - status = sss_key_store_allocate(&host_keystore_2, SE050_KEYSTOREID_ECC); - } - - if (status == kStatus_SSS_Success) { - status = sss_key_object_init(&ref_private_key, &host_keystore_2); - } - if (status == kStatus_SSS_Success) { status = sss_key_object_get_handle(&ref_private_key, private_key->keyId); } + if (status == kStatus_SSS_Success) { + if (public_key->keyId <= 0) { + byte derBuf[256]; + word32 derSz; + + ret = wc_EccPublicKeyToDer(public_key, derBuf, + (word32)sizeof(derBuf), 1); + if (ret >= 0) { + derSz = ret; + } + else { + status = kStatus_SSS_Fail; + } + if (status == kStatus_SSS_Success) { + keyId = se050_allocate_key(SE050_ECC_KEY); + status = sss_key_object_allocate_handle(&ref_public_key, + keyId, kSSS_KeyPart_Public, curveType, keySize, + kKeyObject_Mode_Transient); + } + if (status == kStatus_SSS_Success) { + keyCreated = 1; + status = sss_key_store_set_key(&host_keystore, &ref_public_key, + derBuf, derSz, keySizeBits, NULL, 0); + } + } + else { + status = sss_key_object_get_handle(&ref_public_key, + public_key->keyId); + } + } if (status == kStatus_SSS_Success) { status = sss_key_object_init(&deriveKey, hostKeyStore); } - if (status == kStatus_SSS_Success) { - keyId = se050_allocate_key(SE050_KEYID_ANY); - + int keyIdAes = se050_allocate_key(SE050_AES_KEY); + deriveKeyCreated = 1; status = sss_key_object_allocate_handle(&deriveKey, - keyId, + keyIdAes, kSSS_KeyPart_Default, kSSS_CipherType_AES, - ecdhKeyLen, + keySize, kKeyObject_Mode_Transient); } - if (status == kStatus_SSS_Success) { status = sss_derive_key_context_init(&ctx_derive_key, cfg_se050_i2c_pi, &ref_private_key, kAlgorithm_SSS_ECDH, kMode_SSS_ComputeSharedSecret); - } + if (status == kStatus_SSS_Success) { + status = sss_derive_key_dh(&ctx_derive_key, &ref_public_key, + &deriveKey); + } + if (status == kStatus_SSS_Success) { + size_t outlenSz = (size_t)*outlen; + /* derived key export */ + status = sss_key_store_get_key(hostKeyStore, &deriveKey, out, + &outlenSz, &keySizeBits); + *outlen = (word32)outlenSz; + } - if (status == kStatus_SSS_Success) { - status = sss_derive_key_dh(&ctx_derive_key, &ref_public_key, &deriveKey); - } - - if (status == kStatus_SSS_Success) { - size_t outlenSz = (size_t)*outlen; - status = sss_key_store_get_key(hostKeyStore, &deriveKey, out, &outlenSz, - &ecdhKeyBitLen); - *outlen = (word32)outlenSz; - } - if (ctx_derive_key.session != NULL) sss_derive_key_context_free(&ctx_derive_key); - if (deriveKey.keyStore != NULL) + } + if (deriveKeyCreated) { sss_key_object_free(&deriveKey); + } - if (status == kStatus_SSS_Success) + if (status == kStatus_SSS_Success) { ret = 0; - else - ret = WC_HW_E; + } + else { + if (keyCreated) { + sss_key_object_free(&public_key); + public_key->keyId = 0; + } + if (ret == 0) + ret = WC_HW_E; + } wolfSSL_CryptHwMutexUnLock(); @@ -815,12 +871,13 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, int se050_ed25519_create_key(ed25519_key* key) { + int ret = 0; sss_status_t status; sss_key_store_t host_keystore; sss_object_t newKey; - int keysize = ED25519_KEY_SIZE; int keyId; - int ret = 0; + int keySize = ED25519_KEY_SIZE; + int keyCreated = 0; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; @@ -834,21 +891,19 @@ int se050_ed25519_create_key(ed25519_key* key) if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519); } - if (status == kStatus_SSS_Success) { status = sss_key_object_init(&newKey, &host_keystore); } - if (status == kStatus_SSS_Success) { - keyId = se050_allocate_key(SE050_ED25519); + keyId = se050_allocate_key(SE050_ED25519_KEY); status = sss_key_object_allocate_handle(&newKey, keyId, - kSSS_KeyPart_Pair, kSSS_CipherType_EC_TWISTED_ED, keysize, + kSSS_KeyPart_Pair, kSSS_CipherType_EC_TWISTED_ED, keySize, kKeyObject_Mode_Transient); } - if (status == kStatus_SSS_Success) { + keyCreated = 1; status = sss_key_store_generate_key(&host_keystore, &newKey, - keysize * 8, NULL); + keySize * 8, NULL); } if (status == kStatus_SSS_Success) { @@ -856,7 +911,9 @@ int se050_ed25519_create_key(ed25519_key* key) ret = 0; } else { - sss_key_object_free(&newKey); + if (keyCreated) { + sss_key_object_free(&newKey); + } ret = WC_HW_E; } @@ -874,9 +931,12 @@ void se050_ed25519_free_key(ed25519_key* key) if (cfg_se050_i2c_pi == NULL) { return; } + if (key->keyId <= 0) { + return; + } if (wolfSSL_CryptHwMutexLock() != 0) { - return /*BAD_MUTEX_E*/; + return; } status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); @@ -892,6 +952,7 @@ void se050_ed25519_free_key(ed25519_key* key) } if (status == kStatus_SSS_Success) { sss_key_object_free(&newKey); + key->keyId = 0; } wolfSSL_CryptHwMutexUnLock(); } @@ -899,11 +960,11 @@ void se050_ed25519_free_key(ed25519_key* key) int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, ed25519_key* key) { + int ret = 0; sss_status_t status = kStatus_SSS_Success; sss_asymmetric_t ctx_asymm; sss_key_store_t host_keystore; sss_object_t newKey; - int ret = 0; inLen = 64; *outLen = 64; @@ -911,41 +972,38 @@ int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } + if (key->keyId <= 0) { + return BAD_FUNC_ARG; + } if (wolfSSL_CryptHwMutexLock() != 0) { return BAD_MUTEX_E; } status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); - if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519); } - if (status == kStatus_SSS_Success) { status = sss_key_object_init(&newKey, &host_keystore); } - if (status == kStatus_SSS_Success) { status = sss_key_object_get_handle(&newKey, key->keyId); } - if (status == kStatus_SSS_Success) { status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, &newKey, kAlgorithm_SSS_SHA512, kMode_SSS_Sign); - } + if (status == kStatus_SSS_Success) { + size_t outlenSz = (size_t)*outLen; + status = sss_se05x_asymmetric_sign((sss_se05x_asymmetric_t *)&ctx_asymm, + (uint8_t *)in, inLen, out, &outlenSz); + *outLen = (word32)outlenSz; + } - if (status == kStatus_SSS_Success) { - size_t outlenSz = (size_t)*outLen; - status = sss_se05x_asymmetric_sign((sss_se05x_asymmetric_t *)&ctx_asymm, - (uint8_t *)in, inLen, out, &outlenSz); - *outLen = (word32)outlenSz; + sss_asymmetric_context_free(&ctx_asymm); } - sss_asymmetric_context_free(&ctx_asymm); - if (status != kStatus_SSS_Success) { - sss_key_object_free(&newKey); ret = WC_HW_E; } @@ -958,34 +1016,58 @@ int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, const byte* msg, word32 msgLen, struct ed25519_key* key, int* res) { + int ret = 0; sss_status_t status = kStatus_SSS_Success; sss_asymmetric_t ctx_asymm; sss_object_t newKey; sss_key_store_t host_keystore; - int ret = 0; + int keyId; + int keySize = ED25519_KEY_SIZE; + int keyCreated = 0; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } - msgLen = 64; - if (wolfSSL_CryptHwMutexLock() != 0) { return BAD_MUTEX_E; } status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); - if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ED25519); } - if (status == kStatus_SSS_Success) { status = sss_key_object_init(&newKey, &host_keystore); } - if (status == kStatus_SSS_Success) { - status = sss_key_object_get_handle(&newKey, key->keyId); + if (key->keyId == 0) { + byte derBuf[48]; + word32 derSz = 0, idx = 0; + + ret = wc_Ed25519PublicKeyDecode(derBuf, &idx, key, + (word32)sizeof(derBuf)); + if (ret >= 0) { + derSz = ret; + } + else { + status = kStatus_SSS_Fail; + } + if (status == kStatus_SSS_Success) { + keyId = se050_allocate_key(SE050_ED25519_KEY); + status = sss_key_object_allocate_handle(&newKey, keyId, + kSSS_KeyPart_Pair, kSSS_CipherType_EC_TWISTED_ED, keySize, + kKeyObject_Mode_Transient); + } + if (status == kStatus_SSS_Success) { + keyCreated = 1; + status = sss_key_store_set_key(&host_keystore, &newKey, derBuf, + derSz, keySize * 8, NULL, 0); + } + } + else { + status = sss_key_object_get_handle(&newKey, key->keyId); + } } if (status == kStatus_SSS_Success) { @@ -1001,14 +1083,21 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, sss_asymmetric_context_free(&ctx_asymm); - wolfSSL_CryptHwMutexUnLock(); - if (status == kStatus_SSS_Success) { + key->keyId = keyId; *res = 1; + ret = 0; } else { - ret = WC_HW_E; + if (keyCreated) { + sss_key_object_free(&newKey); + } + if (ret == 0) + ret = WC_HW_E; } + + wolfSSL_CryptHwMutexUnLock(); + return ret; } diff --git a/wolfssl/wolfcrypt/port/nxp/se050_port.h b/wolfssl/wolfcrypt/port/nxp/se050_port.h index afcf1db8c..7d8b9a153 100644 --- a/wolfssl/wolfcrypt/port/nxp/se050_port.h +++ b/wolfssl/wolfcrypt/port/nxp/se050_port.h @@ -65,15 +65,16 @@ #endif enum { - SSS_BLOCK_SIZE = 512 + SSS_BLOCK_SIZE = 512, + + SSS_MAX_ECC_BITS = 521 }; enum SE050KeyType { - SE050_KEYID_ANY, + SE050_ANY_KEY, SE050_AES_KEY, - SE050_ECC_SIGN, - SE050_ECC_VERIFY, - SE050_ED25519, + SE050_ECC_KEY, + SE050_ED25519_KEY }; @@ -132,7 +133,7 @@ WOLFSSL_LOCAL int se050_ecc_verify_hash_ex(const byte* hash, word32 hashlen, WOLFSSL_LOCAL int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize); WOLFSSL_LOCAL int se050_ecc_shared_secret(struct ecc_key* private_key, struct ecc_key* public_key, byte* out, word32* outlen); -WOLFSSL_LOCAL int se050_ecc_free_key(struct ecc_key* key); +WOLFSSL_LOCAL void se050_ecc_free_key(struct ecc_key* key); struct ed25519_key; WOLFSSL_LOCAL int se050_ed25519_create_key(struct ed25519_key* key); From e9fbd94150f7dbea1e32e16e076a461211291dbc Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 3 Nov 2021 08:10:37 -0700 Subject: [PATCH 4/7] Fix for `_ecc_validate_public_key` and unused parameters for `partial` and `priv`. --- wolfcrypt/src/ecc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index dc57c2394..111e9fe87 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -8513,7 +8513,7 @@ int wc_ecc_get_generator(ecc_point* ecp, int curve_idx) * checks on the bounds of the private key. */ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) { - int err = MP_OKAY; + int err = MP_OKAY; #ifndef WOLFSSL_SP_MATH #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ @@ -8680,11 +8680,11 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) FREE_CURVE_SPECS(); #endif /* WOLFSSL_ATECC508A */ +#else + err = WC_KEY_SIZE_E; +#endif /* !WOLFSSL_SP_MATH */ (void)partial; (void)priv; -#else - return WC_KEY_SIZE_E; -#endif /* !WOLFSSL_SP_MATH */ return err; } From b84edb5c67f81ebfb2054de1a20c576ac652999e Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 3 Nov 2021 12:08:30 -0700 Subject: [PATCH 5/7] Fixes for NXP SE050 testing with hardware. --- wolfcrypt/src/ecc.c | 94 ++------ wolfcrypt/src/port/nxp/se050_port.c | 293 ++++++++++++++++++------ wolfcrypt/test/test.c | 67 +++--- wolfssl/wolfcrypt/port/nxp/se050_port.h | 2 +- 4 files changed, 275 insertions(+), 181 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 111e9fe87..97f0acf22 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4720,7 +4720,7 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, err = NOT_COMPILED_IN; } #elif defined(WOLFSSL_SE050) - err = se050_ecc_create_key(key, curve_id, keysize); + err = se050_ecc_create_key(key, key->dp->id, key->dp->size); key->type = ECC_PRIVATEKEY; #elif defined(WOLFSSL_CRYPTOCELL) @@ -5239,10 +5239,7 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, (void)rng; #elif defined(WOLFSSL_SE050) err = se050_ecc_sign_hash_ex(in, inlen, out, outlen, key); - if (err == 0) - err = DecodeECC_DSA_Sig(out, *outlen, r, s); - - return err; + (void)rng; #endif /* Load R and S */ @@ -7032,11 +7029,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #elif defined(WOLFSSL_KCAPI_ECC) byte sigRS[MAX_ECC_BYTES*2]; #elif defined(WOLFSSL_SE050) - #ifdef WOLFSSL_SMALL_STACK - byte* sigRS = NULL; - #else - byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2]; - #endif + byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2]; #elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) int did_init = 0; ecc_point *mG = NULL, *mQ = NULL; @@ -7098,7 +7091,9 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } #endif -#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ + defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SILABS_SE_ACCEL) || \ + defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_SE050) /* Extract R and S */ err = mp_to_unsigned_bin(r, &sigRS[0]); if (err != MP_OKAY) { @@ -7109,6 +7104,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, return err; } +#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res); if (err != 0) { return err; @@ -7116,17 +7112,6 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, (void)hashlen; #elif defined(WOLFSSL_CRYPTOCELL) - /* Extract R and S */ - - err = mp_to_unsigned_bin(r, &sigRS[0]); - if (err != MP_OKAY) { - return err; - } - err = mp_to_unsigned_bin(s, &sigRS[keySz]); - if (err != MP_OKAY) { - return err; - } - /* truncate if hash is longer than key size */ if (msgLenInBytes > keySz) { msgLenInBytes = keySz; @@ -7153,69 +7138,18 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, /* valid signature if we get to this point */ *res = 1; #elif defined(WOLFSSL_SILABS_SE_ACCEL) - /* Extract R and S */ - - err = mp_to_unsigned_bin(r, &sigRS[0]); - if (err != MP_OKAY) { - return err; - } - err = mp_to_unsigned_bin(s, &sigRS[keySz]); - if (err != MP_OKAY) { - return err; - } - - err = silabs_ecc_verify_hash(&sigRS[0], keySz*2, + err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2, hash, hashlen, res, key); - #elif defined(WOLFSSL_KCAPI_ECC) - /* Extract R and S */ - err = mp_to_unsigned_bin(r, &sigRS[0]); - if (err != MP_OKAY) { - return err; + err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2); + if (err == 0) { + *res = 1; } - err = mp_to_unsigned_bin(s, &sigRS[key->dp->size]); - if (err != MP_OKAY) { - return err; - } - - err = KcapiEcc_Verify(key, hash, hashlen, sigRS, key->dp->size * 2); #elif defined(WOLFSSL_SE050) - { - /* Used when following a hardware sign operation */ - int rLeadingZero = mp_leading_bit(r); - int sLeadingZero = mp_leading_bit(s); - int rLen = mp_unsigned_bin_size(r); - int sLen = mp_unsigned_bin_size(s); - word32 signatureLen = rLeadingZero + sLeadingZero + - rLen + sLen + SIG_HEADER_SZ; /* see StoreECC_DSA_Sig */ + err = se050_ecc_verify_hash_ex(hash, hashlen, sigRS, keySz * 2, key, res); +#endif - #ifdef WOLFSSL_SMALL_STACK - sigRS = (byte*)XMALLOC(signatureLen, NULL, DYNAMIC_TYPE_SIGNATURE); - if (sigRS == NULL) { - err = MEMORY_E; - } - #else - if (signatureLen > sizeof(sigRS)) { - err = BUFFER_E; - } - #endif - if (err == 0) { - err = StoreECC_DSA_Sig(sigRS, &signatureLen, r, s); - } - if (err == 0) { - err = se050_ecc_verify_hash_ex(hash, hashlen, sigRS, - signatureLen, key, res); - } - #ifdef WOLFSSL_SMALL_STACK - if (sigRS != NULL) { - XFREE(sigRS, NULL, DYNAMIC_TYPE_SIGNATURE); - sigRS = NULL; - } - #endif - if (err != 0) - return err; - } #else /* checking if private key with no public part */ if (key->type == ECC_PRIVATEKEY_ONLY) { @@ -8989,7 +8923,7 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, } } else - #endif + #endif { err = wc_export_int(&key->k, d, dLen, keySz, encType); if (err != MP_OKAY) diff --git a/wolfcrypt/src/port/nxp/se050_port.c b/wolfcrypt/src/port/nxp/se050_port.c index 4a59bad45..7e618bdf7 100644 --- a/wolfcrypt/src/port/nxp/se050_port.c +++ b/wolfcrypt/src/port/nxp/se050_port.c @@ -58,16 +58,21 @@ #endif struct ecc_key; #include -#include +#include #ifndef SE050_ECC_DER_MAX #define SE050_ECC_DER_MAX 256 #endif +/* enable for debugging */ +/* #define SE050_DEBUG*/ +/* enable to factory erase chip */ +/* #define WOLFSSL_SE050_FACTORY_RESET */ + /* Global variables */ static sss_session_t *cfg_se050_i2c_pi; -static sss_key_store_t *hostKeyStore; -static sss_key_store_t *keyStore; +static sss_key_store_t *gHostKeyStore; +static sss_key_store_t *gHeyStore; int wc_se050_set_config(sss_session_t *pSession, sss_key_store_t *pHostKeyStore, sss_key_store_t *pKeyStore) @@ -75,8 +80,8 @@ int wc_se050_set_config(sss_session_t *pSession, sss_key_store_t *pHostKeyStore, WOLFSSL_MSG("Setting SE050 session configuration"); cfg_se050_i2c_pi = pSession; - hostKeyStore = pHostKeyStore; - keyStore = pKeyStore; + gHostKeyStore = pHostKeyStore; + gHeyStore = pKeyStore; return 0; } @@ -101,6 +106,10 @@ int wc_se050_init(const char* portName) NULL, #endif &pCtx.ks); + + #ifdef WOLFSSL_SE050_FACTORY_RESET + ex_sss_boot_factory_reset(&pCtx); + #endif } else { ret = WC_HW_E; @@ -111,7 +120,7 @@ int wc_se050_init(const char* portName) int se050_allocate_key(int keyType) { - int keyId = 0; + int keyId = -1; static int keyId_allocator = 100; switch (keyType) { case SE050_AES_KEY: @@ -121,6 +130,9 @@ int se050_allocate_key(int keyType) keyId = keyId_allocator++; break; } +#ifdef SE050_DEBUG + printf("se050_allocate_key: keyId %d\n", keyId); +#endif return keyId; } @@ -131,6 +143,10 @@ int se050_get_random_number(uint32_t count, uint8_t* rand_out) sss_status_t status; sss_rng_context_t rng; +#ifdef SE050_DEBUG + printf("se050_get_random_number: %p (%d)\n", rand_out, count); +#endif + if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } @@ -292,6 +308,7 @@ int se050_aes_set_key(Aes* aes, const byte* key, word32 keylen, } else { if (keyCreated) { + sss_key_store_erase_key(&host_keystore, &newKey); sss_key_object_free(&newKey); } ret = WC_HW_E; @@ -398,8 +415,9 @@ void se050_aes_free(Aes* aes) } if (status == kStatus_SSS_Success) { status = sss_key_object_get_handle(&keyObject, aes->keyId); - aes->keyId = 0; + aes->keyId = -1; } + sss_key_store_erase_key(&host_keystore, &keyObject); sss_key_object_free(&keyObject); wolfSSL_CryptHwMutexUnLock(); @@ -454,6 +472,11 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, int keySize; int keySizeBits; +#ifdef SE050_DEBUG + printf("se050_ecc_sign_hash_ex: key %p, in %p (%d), out %p (%d), keyId %d\n", + key, in, inLen, out, *outLen, key->keyId); +#endif + if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } @@ -461,19 +484,15 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, return BAD_FUNC_ARG; } - if (wolfSSL_CryptHwMutexLock() != 0) { - return BAD_MUTEX_E; - } - - /* truncate if digest is larger than 64 */ - if (inLen > 64) - inLen = 64; - keySize = key->dp->size; keySizeBits = keySize * 8; if (keySizeBits > SSS_MAX_ECC_BITS) keySizeBits = SSS_MAX_ECC_BITS; + /* truncate if digest is larger than key size */ + if (inLen > (word32)keySize) + inLen = (word32)keySize; + if (inLen == 20) algorithm = kAlgorithm_SSS_SHA1; else if (inLen == 28) @@ -484,6 +503,17 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, algorithm = kAlgorithm_SSS_SHA384; else if (inLen == 64) algorithm = kAlgorithm_SSS_SHA512; + else { + /* not supported curve key size */ + return ECC_CURVE_OID_E; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + + /* mark that key was used for signing */ + key->flags |= WC_ECC_FLAG_DEC_SIGN; status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { @@ -499,25 +529,45 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, &newKey, algorithm, kMode_SSS_Sign); if (status == kStatus_SSS_Success) { - size_t outLenSz = (size_t)*outLen; - status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t *)in, - inLen, out, &outLenSz); - *outLen = (word32)outLenSz; + byte sigBuf[ECC_MAX_SIG_SIZE]; + size_t sigSz = sizeof(sigBuf); + status = sss_asymmetric_sign_digest(&ctx_asymm, (uint8_t*)in, + inLen, sigBuf, &sigSz); + if (status == kStatus_SSS_Success) { + /* SE050 returns ASN.1 encoded signature */ + word32 rLen = keySize, sLen = keySize; + ret = DecodeECC_DSA_Sig_Bin(sigBuf, (word32)sigSz, + out, &rLen, + out+keySize, &sLen); + if (ret != 0) { + status = kStatus_SSS_Fail; + } + } } sss_asymmetric_context_free(&ctx_asymm); } - if (status != kStatus_SSS_Success) { - ret = WC_HW_E; + if (status == kStatus_SSS_Success) { + ret = 0; + } + else { + if (ret == 0) + ret = WC_HW_E; } wolfSSL_CryptHwMutexUnLock(); +#ifdef SE050_DEBUG + printf("se050_ecc_sign_hash_ex: ret %d, outLen %d\n", ret, *outLen); +#endif + + (void)outLen; /* caller sets outLen */ + return ret; } -int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, - word32 signatureLen, struct ecc_key* key, int* res) +int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* sigRS, + word32 sigRSLen, struct ecc_key* key, int* res) { int ret = 0; sss_status_t status; @@ -525,23 +575,33 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, sss_object_t newKey; sss_key_store_t host_keystore; sss_algorithm_t algorithm = kAlgorithm_None; + int keyId; int keySize; int keySizeBits; sss_cipher_type_t curveType; int keyCreated = 0; +#ifdef SE050_DEBUG + printf("se050_ecc_verify_hash_ex: key %p, hash %p (%d), sig %p (%d)\n", + key, hash, hashLen, sigRS, sigRSLen); +#endif + *res = 0; + (void)sigRSLen; if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } - if (wolfSSL_CryptHwMutexLock() != 0) { - return BAD_MUTEX_E; - } + keySize = key->dp->size; + keySizeBits = keySize * 8; + if (keySizeBits > SSS_MAX_ECC_BITS) + keySizeBits = SSS_MAX_ECC_BITS; + curveType = se050_map_curve(key->dp->id); - if (hashLen > 64) - hashLen = 64; + /* truncate hash if larger than key size */ + if (hashLen > (word32)keySize) + hashLen = (word32)keySize; if (hashLen == 20) algorithm = kAlgorithm_SSS_SHA1; @@ -553,12 +613,14 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, algorithm = kAlgorithm_SSS_SHA384; else if (hashLen == 64) algorithm = kAlgorithm_SSS_SHA512; + else { + /* not supported curve key size */ + return ECC_CURVE_OID_E; + } - keySize = key->dp->size; - keySizeBits = keySize * 8; - if (keySizeBits > SSS_MAX_ECC_BITS) - keySizeBits = SSS_MAX_ECC_BITS; - curveType = se050_map_curve(key->dp->id); + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { @@ -570,20 +632,22 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, /* this is run when a key was not generated and was instead passed in */ if (status == kStatus_SSS_Success) { - if (key->keyId == 0) { + keyId = key->keyId; + if (keyId <= 0) { byte derBuf[SE050_ECC_DER_MAX]; word32 derSz; ret = wc_EccPublicKeyToDer(key, derBuf, (word32)sizeof(derBuf), 1); if (ret >= 0) { derSz = ret; + ret = 0; } else { status = kStatus_SSS_Fail; } if (status == kStatus_SSS_Success) { - key->keyId = se050_allocate_key(SE050_ECC_KEY); - status = sss_key_object_allocate_handle(&newKey, key->keyId, + keyId = se050_allocate_key(SE050_ECC_KEY); + status = sss_key_object_allocate_handle(&newKey, keyId, kSSS_KeyPart_Public, curveType, keySize, kKeyObject_Mode_Transient); } @@ -594,7 +658,7 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, } } else { - status = sss_key_object_get_handle(&newKey, key->keyId); + status = sss_key_object_get_handle(&newKey, keyId); } } @@ -602,21 +666,33 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, &newKey, algorithm, kMode_SSS_Verify); if (status == kStatus_SSS_Success) { - status = sss_asymmetric_verify_digest(&ctx_asymm, (uint8_t *)hash, - hashLen, signature, signatureLen); + /* SE050 expects ASN.1 encoded signature */ + byte sigBuf[ECC_MAX_SIG_SIZE]; + word32 sigSz = (word32)sizeof(sigBuf); + ret = StoreECC_DSA_Sig_Bin(sigBuf, &sigSz, + sigRS, keySize, + sigRS+keySize, keySize); + if (ret == 0) { + status = sss_asymmetric_verify_digest(&ctx_asymm, + (uint8_t*)hash, hashLen, sigBuf, sigSz); + } + else { + status = kStatus_SSS_Fail; + } } sss_asymmetric_context_free(&ctx_asymm); } if (status == kStatus_SSS_Success) { + key->keyId = keyId; *res = 1; ret = 0; } else { if (keyCreated) { + sss_key_store_erase_key(&host_keystore, &newKey); sss_key_object_free(&newKey); - key->keyId = 0; } if (ret == 0) ret = WC_HW_E; @@ -624,6 +700,11 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* signature, wolfSSL_CryptHwMutexUnLock(); +#ifdef SE050_DEBUG + printf("se050_ecc_verify_hash_ex: key %p, ret %d, res %d\n", + key, ret, *res); +#endif + return ret; } @@ -634,6 +715,10 @@ void se050_ecc_free_key(struct ecc_key* key) sss_object_t keyObject; sss_key_store_t host_keystore; +#ifdef SE050_DEBUG + printf("se050_ecc_free_key: key %p, keyId %d\n", key, key->keyId); +#endif + if (cfg_se050_i2c_pi == NULL) { return; } @@ -656,8 +741,12 @@ void se050_ecc_free_key(struct ecc_key* key) status = sss_key_object_get_handle(&keyObject, key->keyId); } if (status == kStatus_SSS_Success) { + if ((key->flags & WC_ECC_FLAG_DEC_SIGN) == 0) { + /* key was not used for signing, so release it */ + sss_key_store_erase_key(&host_keystore, &keyObject); + } sss_key_object_free(&keyObject); - key->keyId = 0; + key->keyId = -1; } wolfSSL_CryptHwMutexUnLock(); } @@ -676,19 +765,29 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) sss_cipher_type_t curveType; int keyCreated = 0; +#ifdef SE050_DEBUG + printf("se050_ecc_create_key: key %p, curve %d, keySize %d\n", + key, curve_id, keySize); +#endif + if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } - if (wolfSSL_CryptHwMutexLock() != 0) { - return BAD_MUTEX_E; - } - curveType = se050_map_curve(curve_id); keySizeBits = keySize * 8; if (keySizeBits > SSS_MAX_ECC_BITS) keySizeBits = SSS_MAX_ECC_BITS; + if (keySize == 30) { + /* not supported curve key size */ + return ECC_CURVE_OID_E; + } + + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); @@ -700,7 +799,7 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) keyId = se050_allocate_key(SE050_ECC_KEY); status = sss_key_object_allocate_handle(&keyPair, keyId, kSSS_KeyPart_Pair, curveType, keySizeBits, - kKeyObject_Mode_None); + kKeyObject_Mode_Transient); } if (status == kStatus_SSS_Success) { keyCreated = 1; @@ -724,6 +823,7 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) } else { if (keyCreated) { + sss_key_store_erase_key(&host_keystore, &keyPair); sss_key_object_free(&keyPair); } if (ret == 0) @@ -732,6 +832,11 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) wolfSSL_CryptHwMutexUnLock(); +#ifdef SE050_DEBUG + printf("se050_ecc_create_key: key %p, ret %d, keyId %d\n", + key, ret, key->keyId); +#endif + return ret; } @@ -753,6 +858,11 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, int keyCreated = 0; int deriveKeyCreated = 0; +#ifdef SE050_DEBUG + printf("se050_ecc_shared_secret: priv %p, pub %p, out %p (%d)\n", + private_key, public_key, out, *outlen); +#endif + if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } @@ -760,32 +870,32 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, return BAD_FUNC_ARG; } - if (wolfSSL_CryptHwMutexLock() != 0) { - return BAD_MUTEX_E; - } - keySize = private_key->dp->size; keySizeBits = keySize * 8; if (keySizeBits > SSS_MAX_ECC_BITS) keySizeBits = SSS_MAX_ECC_BITS; curveType = se050_map_curve(private_key->dp->id); + if (wolfSSL_CryptHwMutexLock() != 0) { + return BAD_MUTEX_E; + } + status = sss_key_store_context_init(&host_keystore, cfg_se050_i2c_pi); if (status == kStatus_SSS_Success) { status = sss_key_store_allocate(&host_keystore, SE050_KEYSTOREID_ECC); } - if (status == kStatus_SSS_Success) { - status = sss_key_object_init(&ref_public_key, &host_keystore); - } if (status == kStatus_SSS_Success) { status = sss_key_object_init(&ref_private_key, &host_keystore); } if (status == kStatus_SSS_Success) { status = sss_key_object_get_handle(&ref_private_key, private_key->keyId); } - if (status == kStatus_SSS_Success) { - if (public_key->keyId <= 0) { + status = sss_key_object_init(&ref_public_key, &host_keystore); + } + if (status == kStatus_SSS_Success) { + keyId = public_key->keyId; + if (keyId <= 0) { byte derBuf[256]; word32 derSz; @@ -793,6 +903,7 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, (word32)sizeof(derBuf), 1); if (ret >= 0) { derSz = ret; + ret = 0; } else { status = kStatus_SSS_Fail; @@ -810,12 +921,11 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, } } else { - status = sss_key_object_get_handle(&ref_public_key, - public_key->keyId); + status = sss_key_object_get_handle(&ref_public_key, keyId); } } if (status == kStatus_SSS_Success) { - status = sss_key_object_init(&deriveKey, hostKeyStore); + status = sss_key_object_init(&deriveKey, &host_keystore); } if (status == kStatus_SSS_Success) { int keyIdAes = se050_allocate_key(SE050_AES_KEY); @@ -823,7 +933,7 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, status = sss_key_object_allocate_handle(&deriveKey, keyIdAes, kSSS_KeyPart_Default, - kSSS_CipherType_AES, + kSSS_CipherType_Binary, keySize, kKeyObject_Mode_Transient); } @@ -838,7 +948,7 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, if (status == kStatus_SSS_Success) { size_t outlenSz = (size_t)*outlen; /* derived key export */ - status = sss_key_store_get_key(hostKeyStore, &deriveKey, out, + status = sss_key_store_get_key(&host_keystore, &deriveKey, out, &outlenSz, &keySizeBits); *outlen = (word32)outlenSz; } @@ -846,16 +956,18 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, sss_derive_key_context_free(&ctx_derive_key); } if (deriveKeyCreated) { + sss_key_store_erase_key(&host_keystore, &deriveKey); sss_key_object_free(&deriveKey); } if (status == kStatus_SSS_Success) { + public_key->keyId = keyId; ret = 0; } else { if (keyCreated) { + sss_key_store_erase_key(&host_keystore, &public_key); sss_key_object_free(&public_key); - public_key->keyId = 0; } if (ret == 0) ret = WC_HW_E; @@ -863,6 +975,10 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, wolfSSL_CryptHwMutexUnLock(); +#ifdef SE050_DEBUG + printf("se050_ecc_shared_secret: ret %d, outlen %d\n", ret, *outlen); +#endif + return ret; } #endif /* HAVE_ECC */ @@ -879,6 +995,10 @@ int se050_ed25519_create_key(ed25519_key* key) int keySize = ED25519_KEY_SIZE; int keyCreated = 0; +#ifdef SE050_DEBUG + printf("se050_ed25519_create_key: %p\n", key); +#endif + if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } @@ -912,6 +1032,7 @@ int se050_ed25519_create_key(ed25519_key* key) } else { if (keyCreated) { + sss_key_store_erase_key(&host_keystore, &newKey); sss_key_object_free(&newKey); } ret = WC_HW_E; @@ -919,6 +1040,10 @@ int se050_ed25519_create_key(ed25519_key* key) wolfSSL_CryptHwMutexUnLock(); +#ifdef SE050_DEBUG + printf("se050_ed25519_create_key: ret %d, keyId %d\n", ret, key->keyId); +#endif + return ret; } @@ -928,6 +1053,10 @@ void se050_ed25519_free_key(ed25519_key* key) sss_object_t newKey; sss_key_store_t host_keystore; +#ifdef SE050_DEBUG + printf("se050_ed25519_free_key: %p, id %d\n", key, key->keyId); +#endif + if (cfg_se050_i2c_pi == NULL) { return; } @@ -952,7 +1081,7 @@ void se050_ed25519_free_key(ed25519_key* key) } if (status == kStatus_SSS_Success) { sss_key_object_free(&newKey); - key->keyId = 0; + key->keyId = -1; } wolfSSL_CryptHwMutexUnLock(); } @@ -966,8 +1095,10 @@ int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, sss_key_store_t host_keystore; sss_object_t newKey; - inLen = 64; - *outLen = 64; +#ifdef SE050_DEBUG + printf("se050_ed25519_sign_msg: key %p, in %p (%d), out %p (%d), keyId %d\n", + key, in, inLen, out, *outLen, key->keyId); +#endif if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; @@ -1009,6 +1140,10 @@ int se050_ed25519_sign_msg(const byte* in, word32 inLen, byte* out, wolfSSL_CryptHwMutexUnLock(); +#ifdef SE050_DEBUG + printf("se050_ed25519_sign_msg: ret %d, outLen %d\n", ret, *outLen); +#endif + return ret; } @@ -1025,6 +1160,11 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, int keySize = ED25519_KEY_SIZE; int keyCreated = 0; +#ifdef SE050_DEBUG + printf("se050_ed25519_verify_msg: key %p, sig %p (%d), msg %p (%d)\n", + key, signature, signatureLen, msg, msgLen); +#endif + if (cfg_se050_i2c_pi == NULL) { return WC_HW_E; } @@ -1041,7 +1181,8 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, status = sss_key_object_init(&newKey, &host_keystore); } if (status == kStatus_SSS_Success) { - if (key->keyId == 0) { + keyId = key->keyId; + if (keyId <= 0) { byte derBuf[48]; word32 derSz = 0, idx = 0; @@ -1049,6 +1190,7 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, (word32)sizeof(derBuf)); if (ret >= 0) { derSz = ret; + ret = 0; } else { status = kStatus_SSS_Fail; @@ -1066,23 +1208,21 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, } } else { - status = sss_key_object_get_handle(&newKey, key->keyId); + status = sss_key_object_get_handle(&newKey, keyId); } } if (status == kStatus_SSS_Success) { status = sss_asymmetric_context_init(&ctx_asymm, cfg_se050_i2c_pi, &newKey, kAlgorithm_SSS_SHA512, kMode_SSS_Verify); + if (status == kStatus_SSS_Success) { + status = sss_se05x_asymmetric_verify( + (sss_se05x_asymmetric_t*)&ctx_asymm, (uint8_t*)msg, msgLen, + (uint8_t*)signature, (size_t)signatureLen); + } + sss_asymmetric_context_free(&ctx_asymm); } - if (status == kStatus_SSS_Success) { - status = sss_se05x_asymmetric_verify( - (sss_se05x_asymmetric_t*)&ctx_asymm, (uint8_t*)msg, msgLen, - (uint8_t*)signature, (size_t)signatureLen); - } - - sss_asymmetric_context_free(&ctx_asymm); - if (status == kStatus_SSS_Success) { key->keyId = keyId; *res = 1; @@ -1090,6 +1230,7 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, } else { if (keyCreated) { + sss_key_store_erase_key(&host_keystore, &newKey); sss_key_object_free(&newKey); } if (ret == 0) @@ -1098,6 +1239,10 @@ int se050_ed25519_verify_msg(const byte* signature, word32 signatureLen, wolfSSL_CryptHwMutexUnLock(); +#ifdef SE050_DEBUG + printf("se050_ed25519_verify_msg: ret %d, res %d\n", ret, *res); +#endif + return ret; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index e953e8ef5..657e2aa03 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -22002,6 +22002,8 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE); #endif + if (ret == ECC_CURVE_OID_E) + goto done; /* catch case, where curve is not supported */ if (ret != 0) ERROR_OUT(-9910, done); TEST_SLEEP(); @@ -22945,7 +22947,7 @@ static int ecc_def_curve_test(WC_RNG *rng) #else ecc_key key[1]; #endif -#ifdef WC_NO_RNG +#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) word32 idx = 0; #endif @@ -22970,46 +22972,59 @@ static int ecc_def_curve_test(WC_RNG *rng) #ifndef WC_NO_RNG ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, key); -#if defined(WOLFSSL_ASYNC_CRYPT) + #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); -#endif -#else - /* use test ECC key */ - ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, key, - (word32)sizeof_ecc_key_der_256); - (void)rng; -#endif + #endif if (ret != 0) { - ret = -10092; goto done; } - TEST_SLEEP(); -#ifndef NO_SIG_WRAPPER + #ifndef NO_SIG_WRAPPER ret = ecc_sig_test(rng, key); if (ret < 0) goto done; -#endif -#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) && \ - !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_QNX_CAAM) + #endif + TEST_SLEEP(); + + #ifdef HAVE_ECC_DHE + ret = ecc_ssh_test(key, rng); + if (ret < 0) + goto done; + #endif +#else + (void)rng; +#endif /* !WC_NO_RNG */ + +#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) + /* Use test ECC key - ensure real private "d" exists */ + #ifdef USE_CERT_BUFFERS_256 + ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, key, + sizeof_ecc_key_der_256); + #else + { + XFILE file = XFOPEN("./certs/ecc-key.der", "rb"); + byte der[128]; + word32 derSz; + if (!file) { + ERROR_OUT(-10093, done); + } + derSz = (word32)XFREAD(der, 1, sizeof(der), file); + XFCLOSE(file); + ret = wc_EccPrivateKeyDecode(der, &idx, key, derSz); + } + #endif + if (ret != 0) { + goto done; + } + ret = ecc_exp_imp_test(key); if (ret < 0) goto done; -#endif -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_QNX_CAAM) -#if defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT) ret = ecc_mulmod_test(key); if (ret < 0) goto done; #endif -#if defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG) - ret = ecc_ssh_test(key, rng); - if (ret < 0) - goto done; -#endif -#endif /* WOLFSSL_ATECC508A */ + done: #ifdef WOLFSSL_SMALL_STACK diff --git a/wolfssl/wolfcrypt/port/nxp/se050_port.h b/wolfssl/wolfcrypt/port/nxp/se050_port.h index 7d8b9a153..65db423c4 100644 --- a/wolfssl/wolfcrypt/port/nxp/se050_port.h +++ b/wolfssl/wolfcrypt/port/nxp/se050_port.h @@ -128,7 +128,7 @@ WOLFSSL_LOCAL int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, word32 *outLen, struct ecc_key* key); WOLFSSL_LOCAL int se050_ecc_verify_hash_ex(const byte* hash, word32 hashlen, - byte* signature, word32 signatureLen, struct ecc_key* key, int* res); + byte* sigRS, word32 sigRSLen, struct ecc_key* key, int* res); WOLFSSL_LOCAL int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize); WOLFSSL_LOCAL int se050_ecc_shared_secret(struct ecc_key* private_key, From d8faa2219475d00d99a6133a1c90fd9d2372d0c4 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 3 Nov 2021 15:10:29 -0700 Subject: [PATCH 6/7] Fix for `ecc_def_curve_test` test changes. --- wolfcrypt/test/test.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 657e2aa03..66dfa38b7 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -22692,9 +22692,7 @@ static int ecc_sig_test(WC_RNG* rng, ecc_key* key) } #endif -#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) && \ - !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_QNX_CAAM) +#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) static int ecc_exp_imp_test(ecc_key* key) { @@ -22824,8 +22822,6 @@ done: } #endif /* HAVE_ECC_KEY_IMPORT && HAVE_ECC_KEY_EXPORT */ -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_QNX_CAAM) #if defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT) static int ecc_mulmod_test(ecc_key* key1) { @@ -22937,7 +22933,6 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) return 0; } #endif /* HAVE_ECC_DHE && !WC_NO_RNG */ -#endif static int ecc_def_curve_test(WC_RNG *rng) { @@ -22991,11 +22986,14 @@ static int ecc_def_curve_test(WC_RNG *rng) if (ret < 0) goto done; #endif + + wc_ecc_free(key); #else (void)rng; #endif /* !WC_NO_RNG */ -#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) +#if (defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT)) || \ + (defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT)) /* Use test ECC key - ensure real private "d" exists */ #ifdef USE_CERT_BUFFERS_256 ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, key, @@ -23017,24 +23015,27 @@ static int ecc_def_curve_test(WC_RNG *rng) goto done; } +#if defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT) ret = ecc_exp_imp_test(key); if (ret < 0) goto done; +#endif +#if defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT) ret = ecc_mulmod_test(key); if (ret < 0) goto done; #endif +#endif done: + wc_ecc_free(key); #ifdef WOLFSSL_SMALL_STACK - if (key != NULL) { - wc_ecc_free(key); + if (key != NULL) { XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); } -#else - wc_ecc_free(key); #endif + return ret; } #endif /* !NO_ECC256 || HAVE_ALL_CURVES */ From 3941eea62649b6d806be9b99081a3540ba0ab113 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 5 Nov 2021 14:37:41 -0700 Subject: [PATCH 7/7] Fixes for peer review feedback. Improve the ECC key bit calculation. Improve the signature RS unsigned bin creation. --- wolfcrypt/src/ecc.c | 10 ++-- wolfcrypt/src/port/nxp/se050_port.c | 74 ++++++++++++++++++----------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 97f0acf22..a33e538df 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -7094,12 +7094,16 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \ defined(WOLFSSL_CRYPTOCELL) || defined(WOLFSSL_SILABS_SE_ACCEL) || \ defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_SE050) - /* Extract R and S */ - err = mp_to_unsigned_bin(r, &sigRS[0]); + + /* Extract R and S with front zero padding (if required) */ + XMEMSET(sigRS, 0, keySz * 2); + err = mp_to_unsigned_bin(r, sigRS + + (keySz - mp_unsigned_bin_size(r))); if (err != MP_OKAY) { return err; } - err = mp_to_unsigned_bin(s, &sigRS[keySz]); + err = mp_to_unsigned_bin(s, sigRS + keySz + + (keySz - mp_unsigned_bin_size(s))); if (err != MP_OKAY) { return err; } diff --git a/wolfcrypt/src/port/nxp/se050_port.c b/wolfcrypt/src/port/nxp/se050_port.c index 7e618bdf7..9add06bca 100644 --- a/wolfcrypt/src/port/nxp/se050_port.c +++ b/wolfcrypt/src/port/nxp/se050_port.c @@ -427,15 +427,22 @@ void se050_aes_free(Aes* aes) #ifdef HAVE_ECC -static sss_cipher_type_t se050_map_curve(int curve_id) +static int se050_map_curve(int curve_id, int keySize, + int* keySizeBits, sss_cipher_type_t* pcurve_type) { + int ret = 0; sss_cipher_type_t curve_type; + *keySizeBits = keySize * 8; /* set default */ switch (curve_id) { - case ECC_SECP160K1: + case ECC_SECP160K1: case ECC_SECP192K1: case ECC_SECP224K1: case ECC_SECP256K1: + #ifdef HAVE_ECC_KOBLITZ curve_type = kSSS_CipherType_EC_NIST_K; + #else + ret = ECC_CURVE_OID_E; + #endif break; case ECC_BRAINPOOLP160R1: case ECC_BRAINPOOLP192R1: @@ -444,7 +451,15 @@ static sss_cipher_type_t se050_map_curve(int curve_id) case ECC_BRAINPOOLP320R1: case ECC_BRAINPOOLP384R1: case ECC_BRAINPOOLP512R1: + #ifdef HAVE_ECC_BRAINPOOL curve_type = kSSS_CipherType_EC_BRAINPOOL; + #else + ret = ECC_CURVE_OID_E; + #endif + break; + case ECC_SECP521R1: + curve_type = kSSS_CipherType_EC_NIST_P; + *keySizeBits = 521; break; case ECC_CURVE_DEF: case ECC_SECP160R1: @@ -452,12 +467,18 @@ static sss_cipher_type_t se050_map_curve(int curve_id) case ECC_SECP224R1: case ECC_SECP256R1: case ECC_SECP384R1: - case ECC_SECP521R1: - default: curve_type = kSSS_CipherType_EC_NIST_P; break; + case ECC_PRIME239V1: + case ECC_PRIME192V2: + case ECC_PRIME192V3: + default: + ret = ECC_CURVE_OID_E; + break; } - return curve_type; + if (pcurve_type) + *pcurve_type = curve_type; + return ret; } int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, @@ -485,9 +506,10 @@ int se050_ecc_sign_hash_ex(const byte* in, word32 inLen, byte* out, } keySize = key->dp->size; - keySizeBits = keySize * 8; - if (keySizeBits > SSS_MAX_ECC_BITS) - keySizeBits = SSS_MAX_ECC_BITS; + ret = se050_map_curve(key->dp->id, keySize, &keySizeBits, NULL); + if (ret != 0) { + return ret; + } /* truncate if digest is larger than key size */ if (inLen > (word32)keySize) @@ -594,10 +616,10 @@ int se050_ecc_verify_hash_ex(const byte* hash, word32 hashLen, byte* sigRS, } keySize = key->dp->size; - keySizeBits = keySize * 8; - if (keySizeBits > SSS_MAX_ECC_BITS) - keySizeBits = SSS_MAX_ECC_BITS; - curveType = se050_map_curve(key->dp->id); + ret = se050_map_curve(key->dp->id, keySize, &keySizeBits, &curveType); + if (ret != 0) { + return ret; + } /* truncate hash if larger than key size */ if (hashLen > (word32)keySize) @@ -759,7 +781,6 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) sss_key_store_t host_keystore; uint8_t derBuf[SE050_ECC_DER_MAX]; size_t derSz = sizeof(derBuf); - size_t derSzBits = derSz * 8; int keyId; int keySizeBits; sss_cipher_type_t curveType; @@ -774,14 +795,9 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) return WC_HW_E; } - curveType = se050_map_curve(curve_id); - keySizeBits = keySize * 8; - if (keySizeBits > SSS_MAX_ECC_BITS) - keySizeBits = SSS_MAX_ECC_BITS; - - if (keySize == 30) { - /* not supported curve key size */ - return ECC_CURVE_OID_E; + ret = se050_map_curve(curve_id, keySize, &keySizeBits, &curveType); + if (ret != 0) { + return ret; } if (wolfSSL_CryptHwMutexLock() != 0) { @@ -807,8 +823,10 @@ int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize) keySizeBits, NULL); } if (status == kStatus_SSS_Success) { + size_t derSzBits = derSz * 8; status = sss_key_store_get_key(&host_keystore, &keyPair, derBuf, &derSz, &derSzBits); + (void)derSzBits; /* not used */ } if (status == kStatus_SSS_Success) { word32 idx = 0; @@ -853,7 +871,7 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, sss_derive_key_t ctx_derive_key; int keyId; int keySize; - size_t keySizeBits; + int keySizeBits; sss_cipher_type_t curveType; int keyCreated = 0; int deriveKeyCreated = 0; @@ -871,10 +889,10 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, } keySize = private_key->dp->size; - keySizeBits = keySize * 8; - if (keySizeBits > SSS_MAX_ECC_BITS) - keySizeBits = SSS_MAX_ECC_BITS; - curveType = se050_map_curve(private_key->dp->id); + ret = se050_map_curve(private_key->dp->id, keySize, &keySizeBits, &curveType); + if (ret != 0) { + return ret; + } if (wolfSSL_CryptHwMutexLock() != 0) { return BAD_MUTEX_E; @@ -947,10 +965,12 @@ int se050_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, } if (status == kStatus_SSS_Success) { size_t outlenSz = (size_t)*outlen; + size_t outlenSzBits = outlenSz * 8; /* derived key export */ status = sss_key_store_get_key(&host_keystore, &deriveKey, out, - &outlenSz, &keySizeBits); + &outlenSz, &outlenSzBits); *outlen = (word32)outlenSz; + (void)outlenSzBits; /* not used */ } sss_derive_key_context_free(&ctx_derive_key);