From 7efe61fbd0bed551ca311c1113eb8479b93dfb92 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 22 Jan 2026 23:11:36 +0100 Subject: [PATCH] [TA-100] Fixed RSA keygen/sign/verify, tests --- wolfcrypt/src/port/atmel/atmel.c | 36 +++++++++-------- wolfcrypt/src/rsa.c | 28 ++++++++++++++ wolfcrypt/test/test.c | 66 ++++++++++++++++++++++++++------ 3 files changed, 101 insertions(+), 29 deletions(-) diff --git a/wolfcrypt/src/port/atmel/atmel.c b/wolfcrypt/src/port/atmel/atmel.c index 1e480c6f87..84f391c7c9 100644 --- a/wolfcrypt/src/port/atmel/atmel.c +++ b/wolfcrypt/src/port/atmel/atmel.c @@ -897,7 +897,7 @@ int wc_Microchip_rsa_create_key(struct RsaKey* key, int size, long e) /* Private key for signing AND decryption */ ret = talib_handle_init_private_key(&rKeyA, TA_KEY_TYPE_RSA2048, - TA_ALG_MODE_RSA_SSA_1_5, TA_PROP_SIGN_INT_EXT_DIGEST, + TA_ALG_MODE_RSA_SSA_PSS, TA_PROP_SIGN_INT_EXT_DIGEST, TA_PROP_KEY_AGREEMENT_OUT_BUFF); if (ret != ATCA_SUCCESS) return WC_HW_E; @@ -910,7 +910,7 @@ int wc_Microchip_rsa_create_key(struct RsaKey* key, int size, long e) /* Public key - use 0, 0 for encryption support! */ ret = talib_handle_init_public_key(&uKeyA, TA_KEY_TYPE_RSA2048, - TA_ALG_MODE_RSA_SSA_1_5, 0, 0); + TA_ALG_MODE_RSA_SSA_PSS, 0, 0); if (ret != ATCA_SUCCESS) return WC_HW_E; @@ -975,24 +975,28 @@ int wc_Microchip_rsa_sign(const byte* in, word32 inLen, byte* out, word32 outLen { int ret; uint16_t sign_size = (uint16_t)outLen; - byte hash_data[WC_SHA256_DIGEST_SIZE]; if (in == NULL || out == NULL || key == NULL) { return BAD_FUNC_ARG; } - /* Hash the input message */ - ret = wc_Sha256Hash(in, inLen, hash_data); - if (ret != 0) { - return ret; + /* TA100 expects a digest for RSA sign. */ + if (inLen != WC_SHA256_DIGEST_SIZE) { + return BAD_FUNC_ARG; } /* Sign using the signing private key handle */ - ret = talib_sign_external(atcab_get_device(), WOLFSSL_TA_KEY_TYPE_RSA, - key->rKeyH, TA_HANDLE_INPUT_BUFFER, hash_data, - WC_SHA256_DIGEST_SIZE, out, &sign_size); + ret = talib_sign_external(atcab_get_device(), + (uint8_t)(TA_SIGN_MODE_EXTERNAL_MSG | + WOLFSSL_TA_KEY_TYPE_RSA), + key->rKeyH, TA_HANDLE_INPUT_BUFFER, in, + (uint16_t)inLen, out, &sign_size); - return atmel_ecc_translate_err(ret); + ret = atmel_ecc_translate_err(ret); + if (ret == 0) { + return (int)sign_size; + } + return ret; } @@ -1001,22 +1005,20 @@ int wc_Microchip_rsa_verify(const byte* in, word32 inLen, byte* sig, word32 sigL { int ret; bool verified = false; - byte hash_data[WC_SHA256_DIGEST_SIZE]; if (in == NULL || sig == NULL || key == NULL) { return BAD_FUNC_ARG; } - /* Hash the input message */ - ret = wc_Sha256Hash(in, inLen, hash_data); - if (ret != 0) { - return ret; + /* TA100 expects a digest for RSA verify. */ + if (inLen != WC_SHA256_DIGEST_SIZE) { + return BAD_FUNC_ARG; } /* Verify using the verification public key handle */ ret = talib_verify(atcab_get_device(), WOLFSSL_TA_KEY_TYPE_RSA, TA_HANDLE_INPUT_BUFFER, key->uKeyH, sig, - sigLen, hash_data, WC_SHA256_DIGEST_SIZE, NULL, + sigLen, in, (uint16_t)inLen, NULL, sigLen, &verified); ret = atmel_ecc_translate_err(ret); diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 04f93b6c6a..996540dc2b 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -3655,6 +3655,9 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, else if (rsa_type == RSA_PRIVATE_ENCRYPT && pad_value == RSA_BLOCK_TYPE_1) { if (key->rKeyH != 0) { + if (pad_type != WC_RSA_PSS_PAD) { + return WC_HW_E; + } return wc_Microchip_rsa_sign(in, inLen, out, outLen, key); } return WC_HW_E; @@ -3837,6 +3840,9 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out, else if (rsa_type == RSA_PUBLIC_DECRYPT && pad_value == RSA_BLOCK_TYPE_1) { if (key->uKeyH != 0) { + if (pad_type != WC_RSA_PSS_PAD) { + return WC_HW_E; + } int tmp; return wc_Microchip_rsa_verify(in, inLen, out, outLen, key, &tmp); } @@ -4543,6 +4549,17 @@ int wc_RsaPSS_VerifyCheckInline(byte* in, word32 inLen, byte** out, enum wc_HashType hash, int mgf, RsaKey* key) { int ret = 0, verify, saltLen, hLen, bits = 0; +#ifdef WOLFSSL_MICROCHIP_TA100 + if (key != NULL && key->uKeyH != 0) { + int verified = 0; + ret = wc_Microchip_rsa_verify(digest, digestLen, in, inLen, key, + &verified); + if (ret != 0) { + return ret; + } + return verified ? (int)inLen : SIG_VERIFY_E; + } +#endif hLen = wc_HashGetDigestSize(hash); if (hLen < 0) @@ -4592,6 +4609,17 @@ int wc_RsaPSS_VerifyCheck(const byte* in, word32 inLen, byte* out, word32 outLen RsaKey* key) { int ret = 0, verify, saltLen, hLen, bits = 0; +#ifdef WOLFSSL_MICROCHIP_TA100 + if (key != NULL && key->uKeyH != 0) { + int verified = 0; + ret = wc_Microchip_rsa_verify(digest, digestLen, (byte*)in, inLen, + key, &verified); + if (ret != 0) { + return ret; + } + return verified ? (int)inLen : SIG_VERIFY_E; + } +#endif hLen = wc_HashGetDigestSize(hash); if (hLen < 0) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 62fa10325a..35d727d08b 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -23947,6 +23947,13 @@ static wc_test_ret_t rsa_flatten_test(RsaKey* key) ERROR_OUT(WC_TEST_RET_ENC_EC(MEMORY_E), exit_rsa_flatten); #endif +#ifdef WOLFSSL_MICROCHIP_TA100 + /* TA100 keys are hardware-only; flattening isn't supported. */ + if (key != NULL && (key->rKeyH != 0 || key->uKeyH != 0)) { + return 0; + } +#endif + /* Parameter Validation testing. */ ret = wc_RsaFlattenPublicKey(NULL, e, &eSz, n, &nSz); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) @@ -24018,6 +24025,13 @@ static wc_test_ret_t rsa_export_key_test(RsaKey* key) word32 qSz = RSA_TEST_BYTES/2; word32 zero = 0; +#ifdef WOLFSSL_MICROCHIP_TA100 + /* TA100 keys are hardware-only; exporting components is not supported. */ + if (key != NULL && (key->rKeyH != 0 || key->uKeyH != 0)) { + return 0; + } +#endif + #if !defined(WOLFSSL_NO_MALLOC) n = (byte*)XMALLOC(RSA_TEST_BYTES, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); d = (byte*)XMALLOC(RSA_TEST_BYTES, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -24723,6 +24737,7 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) const char inStr[] = TEST_STRING; word32 inLen = (word32)TEST_STRING_SZ; word32 outSz; + word32 sigSz; word32 plainSz; word32 digestSz; int i, j; @@ -24733,6 +24748,10 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) int len; #endif byte* plain; +#ifdef WOLFSSL_MICROCHIP_TA100 + int mgf[] = { WC_MGF1SHA256 }; + enum wc_HashType hash[] = { WC_HASH_TYPE_SHA256 }; +#else int mgf[] = { #ifndef NO_SHA WC_MGF1SHA1, @@ -24767,6 +24786,7 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) WC_HASH_TYPE_SHA512, #endif }; +#endif /* WOLFSSL_MICROCHIP_TA100 */ WC_DECLARE_VAR(in, byte, RSA_TEST_BYTES, HEAP_HINT); WC_DECLARE_VAR(out, byte, RSA_TEST_BYTES, HEAP_HINT); @@ -24810,11 +24830,29 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) if (ret <= 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa_pss); outSz = (word32)ret; + /* Preserve signature length for TA100 verify. */ + sigSz = outSz; XMEMCPY(sig, out, outSz); plain = NULL; TEST_SLEEP(); +#if defined(WOLFSSL_MICROCHIP_TA100) + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key->asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + #endif + if (ret >= 0) { + ret = wc_RsaPSS_VerifyCheck(sig, sigSz, out, outSz, + digest, digestSz, hash[j], mgf[i], key); + } + } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); + if (ret <= 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa_pss); + /* TA100 PSS verify done; skip remaining software-only variants. */ + return 0; +#else do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, @@ -24843,6 +24881,7 @@ static wc_test_ret_t rsa_pss_test(WC_RNG* rng, RsaKey* key) #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa_pss); +#endif /* WOLFSSL_MICROCHIP_TA100 */ #ifdef RSA_PSS_TEST_WRONG_PARAMS for (k = 0; k < (int)(sizeof(mgf)/sizeof(*mgf)); k++) { @@ -26738,13 +26777,21 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) } #endif #endif +#ifdef WOLFSSL_MICROCHIP_TA100 + /* TA100 RSA tests are limited to PSS verify/sign with HW keys. */ + goto ta100_rsa_pss_only; +#endif #endif /* WOLFSSL_KEY_GEN && WOLFSSL_MICROCHIP_TA100 */ #ifndef NO_SIG_WRAPPER #ifndef NO_SHA256 + #if !defined(WOLFSSL_MICROCHIP_TA100) ret = rsa_sig_test(key, sizeof *key, modLen, &rng); if (ret != 0) goto exit_rsa; + #else + (void)modLen; + #endif /* !WOLFSSL_MICROCHIP_TA100 */ #else /* NO_SHA256 */ (void)modLen; #endif /* NO_SHA256 */ @@ -26773,6 +26820,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); #endif +#ifndef WOLFSSL_MICROCHIP_TA100 do { #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -26794,6 +26842,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) if (ret < 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); TEST_SLEEP(); +#endif /* !WOLFSSL_MICROCHIP_TA100 */ #ifdef WC_RSA_BLINDING { @@ -26839,18 +26888,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, exit_rsa); } TEST_SLEEP(); - - do { -#if defined(WOLFSSL_ASYNC_CRYPT) - ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); -#endif - if (ret >= 0) { - ret = wc_RsaSSL_Sign(in, inLen, out, outSz, key, &rng); - } - } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); - if (ret < 0) - ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); - TEST_SLEEP(); +#endif /* !WOLFSSL_MICROCHIP_TA100 */ #elif defined(WOLFSSL_PUBLIC_MP) { @@ -27204,6 +27242,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void) #endif /* WOLFSSL_CERT_REQ */ #endif /* WOLFSSL_CERT_GEN */ +#ifdef WOLFSSL_MICROCHIP_TA100 +ta100_rsa_pss_only: +#endif + #if defined(WC_RSA_PSS) && \ (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0)) && \ !defined(WC_NO_RNG)