/* renesas_tsip_rsa.c * * Copyright (C) 2006-2026 wolfSSL Inc. * * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #include #if !defined(NO_RSA) && \ defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY) #include #include #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include /* Make sure at least RSA 1024 or RSA 2048 is enabled */ #if (defined(TSIP_RSAES_1024) && TSIP_RSAES_1024 == 0) && \ (defined(TSIP_RSAES_2048) && TSIP_RSAES_2048 == 0) #error Please enable TSIP RSA 1024 or 2048. \ This code assumes at least one is enabled #endif /* Make RSA key for TSIP and set it to callback ctx * Assumes to be called by Crypt Callback * * size desired key length, in bits. supports 1024 or 2048 bits * ctx Callback context including pointer to hold generated key * return TSIP_SUCCESS(0) on Success, otherwise negative value */ int wc_tsip_MakeRsaKey(int size, void* ctx) { e_tsip_err_t ret; TsipUserCtx *info = (TsipUserCtx*)ctx; #if defined(TSIP_RSAES_1024) && TSIP_RSAES_1024 == 1 tsip_rsa1024_key_pair_index_t *tsip_pair1024_key = NULL; #endif #if defined(TSIP_RSAES_2048) && TSIP_RSAES_2048 == 1 tsip_rsa2048_key_pair_index_t *tsip_pair2048_key = NULL; #endif /* sanity check */ if (ctx == NULL) return BAD_FUNC_ARG; if (size != 1024 && size != 2048) { WOLFSSL_MSG("TSIP RSA KeyGen bit size not supported"); return CRYPTOCB_UNAVAILABLE; } #if defined(TSIP_RSAES_1024) && TSIP_RSAES_1024 == 0 if (size == 1024) return CRYPTOCB_UNAVAILABLE; #endif #if defined(TSIP_RSAES_2048) && TSIP_RSAES_2048 == 0 if (size == 2048) return CRYPTOCB_UNAVAILABLE; #endif if ((ret = tsip_hw_lock()) == 0) { if (size == 1024) { #if defined(TSIP_RSAES_1024) && TSIP_RSAES_1024 == 1 tsip_pair1024_key = (tsip_rsa1024_key_pair_index_t*)XMALLOC( sizeof(tsip_rsa1024_key_pair_index_t), NULL, DYNAMIC_TYPE_RSA_BUFFER); if (tsip_pair1024_key == NULL) { tsip_hw_unlock(); return MEMORY_E; } ret = R_TSIP_GenerateRsa1024RandomKeyIndex(tsip_pair1024_key); #endif } else if (size == 2048) { #if defined(TSIP_RSAES_2048) && TSIP_RSAES_2048 == 1 tsip_pair2048_key = (tsip_rsa2048_key_pair_index_t*)XMALLOC( sizeof(tsip_rsa2048_key_pair_index_t), NULL, DYNAMIC_TYPE_RSA_BUFFER); if (tsip_pair2048_key == NULL) { tsip_hw_unlock(); return MEMORY_E; } ret = R_TSIP_GenerateRsa2048RandomKeyIndex(tsip_pair2048_key); #endif } if (ret == TSIP_SUCCESS) { if (size == 1024) { #if defined(TSIP_RSAES_1024) && TSIP_RSAES_1024 == 1 XFREE(info->rsa1024pri_keyIdx, NULL, DYNAMIC_TYPE_RSA_BUFFER); XFREE(info->rsa1024pub_keyIdx, NULL, DYNAMIC_TYPE_RSA_BUFFER); info->rsa1024pri_keyIdx = (tsip_rsa1024_private_key_index_t*)XMALLOC( sizeof(tsip_rsa1024_private_key_index_t), NULL, DYNAMIC_TYPE_RSA_BUFFER); if (info->rsa1024pri_keyIdx == NULL) { XFREE(tsip_pair1024_key, NULL, DYNAMIC_TYPE_RSA_BUFFER); tsip_hw_unlock(); return MEMORY_E; } info->rsa1024pub_keyIdx = (tsip_rsa1024_public_key_index_t*)XMALLOC( sizeof(tsip_rsa1024_public_key_index_t), NULL, DYNAMIC_TYPE_RSA_BUFFER); if (info->rsa1024pub_keyIdx == NULL) { XFREE(tsip_pair1024_key, NULL, DYNAMIC_TYPE_RSA_BUFFER); XFREE(info->rsa1024pri_keyIdx, NULL, DYNAMIC_TYPE_RSA_BUFFER); tsip_hw_unlock(); return MEMORY_E; } /* copy generated key pair and free malloced key */ XMEMCPY(info->rsa1024pri_keyIdx, &tsip_pair1024_key->private, sizeof(tsip_rsa1024_private_key_index_t)); XMEMCPY(info->rsa1024pub_keyIdx, &tsip_pair1024_key->public, sizeof(tsip_rsa1024_public_key_index_t)); XFREE(tsip_pair1024_key, NULL, DYNAMIC_TYPE_RSA_BUFFER); info->keyflgs_crypt.bits.rsapri1024_key_set = 1; info->keyflgs_crypt.bits.rsapub1024_key_set = 1; info->wrappedKeyType = TSIP_KEY_TYPE_RSA1024; #endif } else if (size == 2048) { #if defined(TSIP_RSAES_2048) && TSIP_RSAES_2048 == 1 XFREE(info->rsa2048pri_keyIdx, NULL, DYNAMIC_TYPE_RSA_BUFFER); XFREE(info->rsa2048pub_keyIdx, NULL, DYNAMIC_TYPE_RSA_BUFFER); info->rsa2048pri_keyIdx = (tsip_rsa2048_private_key_index_t*)XMALLOC( sizeof(tsip_rsa2048_private_key_index_t), NULL, DYNAMIC_TYPE_RSA_BUFFER); if (info->rsa2048pri_keyIdx == NULL) { XFREE(tsip_pair2048_key, NULL, DYNAMIC_TYPE_RSA_BUFFER); tsip_hw_unlock(); return MEMORY_E; } info->rsa2048pub_keyIdx = (tsip_rsa2048_public_key_index_t*)XMALLOC( sizeof(tsip_rsa2048_public_key_index_t), NULL, DYNAMIC_TYPE_RSA_BUFFER); if (info->rsa2048pub_keyIdx == NULL) { XFREE(tsip_pair2048_key, NULL, DYNAMIC_TYPE_RSA_BUFFER); XFREE(info->rsa2048pri_keyIdx, NULL, DYNAMIC_TYPE_RSA_BUFFER); tsip_hw_unlock(); return MEMORY_E; } /* copy generated key pair and free malloced key */ XMEMCPY(info->rsa2048pri_keyIdx, &tsip_pair2048_key->private, sizeof(tsip_rsa2048_private_key_index_t)); XMEMCPY(info->rsa2048pub_keyIdx, &tsip_pair2048_key->public, sizeof(tsip_rsa2048_public_key_index_t)); XFREE(tsip_pair2048_key, NULL, DYNAMIC_TYPE_RSA_BUFFER); info->keyflgs_crypt.bits.rsapri2048_key_set = 1; info->keyflgs_crypt.bits.rsapub2048_key_set = 1; info->wrappedKeyType = TSIP_KEY_TYPE_RSA2048; #endif } } tsip_hw_unlock(); } return 0; } /* Generate TSIP key index if needed * * tuc struct pointer of TsipUserCtx * return FSP_SUCCESS(0) on Success, otherwise CRYPTOCB_UNAVAILABLE */ static int tsip_RsakeyImport(TsipUserCtx* tuc) { int ret = 0; switch (tuc->wrappedKeyType) { #if defined(TSIP_RSAES_1024) && TSIP_RSAES_1024 == 1 case TSIP_KEY_TYPE_RSA1024: if (tuc->keyflgs_crypt.bits.rsapub1024_key_set != 1) { ret = tsip_ImportPublicKey(tuc, tuc->wrappedKeyType); WOLFSSL_MSG("tsip rsa private key 1024 not set"); if (ret != 0) ret = CRYPTOCB_UNAVAILABLE; } break; #endif #if defined(TSIP_RSAES_2048) && TSIP_RSAES_2048 == 1 case TSIP_KEY_TYPE_RSA2048: if (tuc->keyflgs_crypt.bits.rsapub2048_key_set != 1) { ret = tsip_ImportPublicKey(tuc, tuc->wrappedKeyType); WOLFSSL_MSG("tsip rsa private key 2048 not set"); if (ret != 0) ret = CRYPTOCB_UNAVAILABLE; } break; #endif default: WOLFSSL_MSG("wrapped private key is not supported"); ret = CRYPTOCB_UNAVAILABLE; break; } return ret; } /* Perform rsa encryption/decryption by TSIP * Assumes to be called by Crypt Callback * * info struct pointer of wc_CryptoInfo including necessary info * tuc struct pointer of TsipUserCtx including TSIP key info * return FSP_SUCCESS(0) on Success, otherwise negative value */ int wc_tsip_RsaFunction(wc_CryptoInfo* info, TsipUserCtx* tuc) { int ret = CRYPTOCB_UNAVAILABLE; int keySize; int type; tsip_rsa_byte_data_t plain, cipher; if (info == NULL || tuc == NULL) { return BAD_FUNC_ARG; } if (tsip_RsakeyImport(tuc) == 0) { type = info->pk.rsa.type; keySize = (int)tuc->wrappedKeyType; if ((ret = tsip_hw_lock()) == 0) { if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) { plain.pdata = (uint8_t*)info->pk.rsa.in; plain.data_length = info->pk.rsa.inLen; cipher.pdata = (uint8_t*)info->pk.rsa.out; cipher.data_length = *(info->pk.rsa.outLen); switch (keySize) { #if defined(TSIP_RSAES_1024) && TSIP_RSAES_1024 == 1 case TSIP_KEY_TYPE_RSA1024: ret = R_TSIP_RsaesPkcs1024Encrypt(&plain, &cipher, tuc->rsa1024pub_keyIdx); break; #endif #if defined(TSIP_RSAES_2048) && TSIP_RSAES_2048 == 1 case TSIP_KEY_TYPE_RSA2048: ret = R_TSIP_RsaesPkcs2048Encrypt(&plain, &cipher, tuc->rsa2048pub_keyIdx); break; #endif default: ret = CRYPTOCB_UNAVAILABLE; } if (ret == 0) { *(info->pk.rsa.outLen) = cipher.data_length; } } else if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) { plain.pdata = (uint8_t*)info->pk.rsa.out; plain.data_length = *(info->pk.rsa.outLen); cipher.pdata = (uint8_t*)info->pk.rsa.in; cipher.data_length = info->pk.rsa.inLen; switch (keySize) { #if defined(TSIP_RSAES_1024) && TSIP_RSAES_1024 == 1 case TSIP_KEY_TYPE_RSA1024: ret = R_TSIP_RsaesPkcs1024Decrypt(&cipher, &plain, tuc->rsa1024pri_keyIdx); break; #endif #if defined(TSIP_RSAES_2048) && TSIP_RSAES_2048 == 1 case TSIP_KEY_TYPE_RSA2048: ret = R_TSIP_RsaesPkcs2048Decrypt(&cipher, &plain, tuc->rsa2048pri_keyIdx); break; #endif default: ret = CRYPTOCB_UNAVAILABLE; } if (ret == 0) { *(info->pk.rsa.outLen) = plain.data_length; } } else { ret = CRYPTOCB_UNAVAILABLE; } tsip_hw_unlock(); } } if (ret != 0) { WOLFSSL_MSG("RSA key size is not supported (only 1024 or 2048 bits)"); } return ret; } /* Perform Rsa verify by TSIP * Assumes to be called by Crypt Callback * * info struct pointer of wc_CryptoInfo including necessary info * tuc struct pointer of TsipUserCtx including TSIP key info * return FSP_SUCCESS(0) on Success, otherwise negative value */ int wc_tsip_RsaVerifyPkcs(wc_CryptoInfo* info, TsipUserCtx* tuc) { int ret = 0; e_tsip_err_t err = TSIP_SUCCESS; tsip_rsa_byte_data_t hashData, sigData; uint8_t tsip_hash_type; /* sanity check */ if (info == NULL || tuc == NULL){ return BAD_FUNC_ARG; } if (ret == 0) { if (tuc->sign_hash_type == md5_mac) tsip_hash_type = R_TSIP_RSA_HASH_MD5; else if (tuc->sign_hash_type == sha_mac) tsip_hash_type = R_TSIP_RSA_HASH_SHA1; else if (tuc->sign_hash_type == sha256_mac) tsip_hash_type = R_TSIP_RSA_HASH_SHA256; else ret = CRYPTOCB_UNAVAILABLE; } if (tsip_RsakeyImport(tuc) == 0) { hashData.pdata = (uint8_t*)info->pk.rsa.out; hashData.data_length = *(info->pk.rsa.outLen); hashData.data_type = tuc->keyflgs_crypt.bits.message_type;/* message 0, hash 1 */ sigData.pdata = (uint8_t*)info->pk.rsa.in; sigData.data_length = info->pk.rsa.inLen; if ((ret = tsip_hw_lock()) == 0) { switch (tuc->wrappedKeyType) { #if defined(TSIP_RSASSA_1024) && TSIP_RSASSA_1024 == 1 case TSIP_KEY_TYPE_RSA1024: err = R_TSIP_RsassaPkcs1024SignatureVerification(&sigData, &hashData, (tsip_rsa1024_public_key_index_t *) tuc->rsa1024pub_keyIdx, tsip_hash_type); if (err == TSIP_ERR_AUTHENTICATION) { ret = SIG_VERIFY_E; } else if (err == TSIP_SUCCESS) { ret = 0; } else { ret = WC_HW_E; } break; #endif #if defined(TSIP_RSASSA_2048) && TSIP_RSASSA_2048 == 1 case TSIP_KEY_TYPE_RSA2048: err = R_TSIP_RsassaPkcs2048SignatureVerification(&sigData, &hashData, (tsip_rsa2048_public_key_index_t *) tuc->rsa2048pub_keyIdx, tsip_hash_type); if (err == TSIP_ERR_AUTHENTICATION) { ret = SIG_VERIFY_E; } else if (err == TSIP_SUCCESS) { ret = 0; } else { ret = WC_HW_E; } break; #endif default: ret = CRYPTOCB_UNAVAILABLE; } tsip_hw_unlock(); } } return ret; } #endif /* !NO_RSA && WOLFSSL_RENESAS_TSIP_CRYPTONLY */