/* renesas_fspsm_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_FSPSM_CRYPTONLY) #include #include #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #if defined(WOLFSSL_RENESAS_RSIP) extern FSPSM_INSTANCE gFSPSM_ctrl; #endif /* Set Ctx pointer to NULL. * A created wrapped key should be freed by user * * key RsaKey object * return none */ WOLFSSL_LOCAL void wc_fspsm_RsaKeyFree(RsaKey *key) { if (key == NULL) return; if(key->ctx.wrapped_pri1024_key) key->ctx.wrapped_pri1024_key = NULL; if(key->ctx.wrapped_pub1024_key) key->ctx.wrapped_pub1024_key = NULL; if(key->ctx.wrapped_pri2048_key) key->ctx.wrapped_pri2048_key = NULL; if(key->ctx.wrapped_pub2048_key) key->ctx.wrapped_pub2048_key = NULL; } /* Set Rsa key by pre-created wrapped user key * * key RsaKey object * size desired key length, in bits. supports 1024 or 2048 bits * ctx Callback context including pointer to hold generated key * return FSP_SUCCESS(0) on Success, otherwise negative value */ WOLFSSL_LOCAL int wc_fspsm_MakeRsaKey(RsaKey *key, int size, void* ctx) { FSPSM_ST *info = (FSPSM_ST*)ctx; /* sanity check */ if (key == NULL || size < 0 || ctx == NULL) return BAD_FUNC_ARG; if (size == 1024) { if(info->keyflgs_crypt.bits.rsapri1024_installedkey_set != 1 || info->keyflgs_crypt.bits.rsapub1024_installedkey_set != 1) { WOLFSSL_MSG("Caller should create user key in advance."); WOLFSSL_MSG("Caller also need to installedkey to 1."); return BAD_FUNC_ARG; } key->ctx.wrapped_pri1024_key = info->wrapped_key_rsapri1024; key->ctx.wrapped_pub1024_key = info->wrapped_key_rsapub1024; key->ctx.keySz = 1024; } else if (size == 2048) { if(info->keyflgs_crypt.bits.rsapri2048_installedkey_set != 1 || info->keyflgs_crypt.bits.rsapub2048_installedkey_set != 1) { WOLFSSL_MSG("Caller should create user key in advance."); WOLFSSL_MSG("Caller also need to installedkey to 1."); return BAD_FUNC_ARG; } key->ctx.wrapped_pri2048_key = info->wrapped_key_rsapri2048; key->ctx.wrapped_pub2048_key = info->wrapped_key_rsapub2048; key->ctx.keySz = 2048; } else if (size == 0) { if((info->keyflgs_crypt.bits.rsapri2048_installedkey_set != 1) && (info->keyflgs_crypt.bits.rsapub2048_installedkey_set != 1) && (info->keyflgs_crypt.bits.rsapri1024_installedkey_set != 1) && (info->keyflgs_crypt.bits.rsapub1024_installedkey_set != 1)) { WOLFSSL_MSG("Caller should create user key in advance."); WOLFSSL_MSG("Caller also need to installedkey to 1."); return BAD_FUNC_ARG; } if (info->keyflgs_crypt.bits.rsapri1024_installedkey_set == 1) { key->ctx.wrapped_pri1024_key = info->wrapped_key_rsapri1024; key->ctx.keySz = 1024; } if (info->keyflgs_crypt.bits.rsapub1024_installedkey_set == 1) { key->ctx.wrapped_pub1024_key = info->wrapped_key_rsapub1024; key->ctx.keySz = 1024; } if (info->keyflgs_crypt.bits.rsapri2048_installedkey_set == 1) { key->ctx.wrapped_pri2048_key = info->wrapped_key_rsapri2048; key->ctx.keySz = 2048; } if (info->keyflgs_crypt.bits.rsapub2048_installedkey_set == 1) { key->ctx.wrapped_pub2048_key = info->wrapped_key_rsapub2048; key->ctx.keySz = 2048; } } else return CRYPTOCB_UNAVAILABLE; return 0; } /* Perform rsa encryption/decryption by FSP SM * Assumes to be called by Crypt Callback * * in Buffer to hold plain text * inLen Length of plain text in bytes * out Buffer to hold cipher text * outLen Length of cipher in bytes * key Rsa key object * rng rng object * ctx Callback context * return FSP_SUCCESS(0) on Success, otherwise negative value */ WOLFSSL_LOCAL int wc_fspsm_RsaFunction(const byte* in, word32 inLen, byte* out, word32 *outLen, int type, struct RsaKey* key, struct WC_RNG* rng) { int ret; FSPSM_RSA_DATA plain; FSPSM_RSA_DATA cipher; int keySize; (void) key; (void) rng; /* sanity check */ if (in == NULL || out == NULL || key == NULL){ return BAD_FUNC_ARG; } keySize = (int)key->ctx.keySz; if (keySize == 0) { WOLFSSL_MSG("keySize is invalid, neither 128 or 256 bytes, " "1024 or 2048 bits."); return BAD_FUNC_ARG; } if ((ret = wc_fspsm_hw_lock()) == 0) { if (type == RSA_PUBLIC_ENCRYPT) { plain.pdata = (byte*)in; plain.data_length = inLen; cipher.pdata = out; cipher.data_length = *outLen; if (keySize == 1024) { ret = FSPSM_RSA1024_PKCSENC_FUNC(&plain, &cipher, (FSPSM_RSA1024_WPB_KEY*) key->ctx.wrapped_pub1024_key); } else { ret = FSPSM_RSA2048_PKCSENC_FUNC(&plain, &cipher, (FSPSM_RSA2048_WPB_KEY*) key->ctx.wrapped_pub2048_key); } } else if (type == RSA_PRIVATE_DECRYPT) { plain.pdata = out; plain.data_length = *outLen; cipher.pdata = (byte*)in; cipher.data_length = inLen; if (keySize == 1024) { ret = FSPSM_RSA1024_PKCSDEC_FUNC(&cipher, &plain, (FSPSM_RSA1024_WPI_KEY*) key->ctx.wrapped_pri1024_key, &outLen); } else { ret = FSPSM_RSA2048_PKCSDEC_FUNC(&cipher, &plain, (FSPSM_RSA2048_WPI_KEY*) key->ctx.wrapped_pri2048_key, &outLen); } } wc_fspsm_hw_unlock(); } return ret; } /* Perform Rsa sign by FSP SM * Assumes to be called by Crypt Callback * * in Buffer to hold plaintext * inLen Length of plaintext in bytes * out Buffer to hold generated signature * outLen Length of signature in bytes * key rsa key object * ctx The callback context * return FSP_SUCCESS(0) on Success, otherwise negative value */ WOLFSSL_LOCAL int wc_fspsm_RsaSign(const byte* in, word32 inLen, byte* out, word32* outLen, struct RsaKey* key, void* ctx) { int ret; FSPSM_RSA_DATA message_hash; FSPSM_RSA_DATA signature; FSPSM_ST *info = (FSPSM_ST*)ctx; int keySize; /* sanity check */ if (in == NULL || out == NULL || *outLen <= 0 || info == NULL || key == NULL){ return BAD_FUNC_ARG; } keySize = (int)key->ctx.keySz; message_hash.pdata = (byte *)in; message_hash.data_length = inLen; message_hash.data_type = info->keyflgs_crypt.bits.message_type;/* message 0, hash 1 */ signature.pdata = out; signature.data_length = *outLen; #if defined(WOLFSSL_RENESAS_RSIP) message_hash.hash_type = signature.hash_type = info->hash_type; /* hash type */ #endif if ((ret = wc_fspsm_hw_lock()) == 0) { if (keySize == 1024) { ret = FSPSM_RSA1024_SIGN_FUNC(&message_hash, &signature, (FSPSM_RSA1024_WPI_KEY *) key->ctx.wrapped_pri1024_key, HW_SCE_RSA_HASH_SHA256); } else { ret = FSPSM_RSA2048_SIGN_FUNC(&message_hash, &signature, (FSPSM_RSA2048_WPI_KEY *) key->ctx.wrapped_pri2048_key, HW_SCE_RSA_HASH_SHA256); } wc_fspsm_hw_unlock(); } return ret; } /* Perform Rsa verify by FSP SM * Assumes to be called by Crypt Callback * * in Buffer to hold plaintext * inLen Length of plaintext in bytes * out Buffer to hold generated signature * outLen Length of signature in bytes * key rsa key object * ctx The callback context * return FSP_SUCCESS(0) on Success, otherwise negative value */ WOLFSSL_LOCAL int wc_fspsm_RsaVerify(const byte* in, word32 inLen, byte* out, word32* outLen,struct RsaKey* key, void* ctx) { int ret; FSPSM_RSA_DATA message_hash; FSPSM_RSA_DATA signature; FSPSM_ST *info = (FSPSM_ST*)ctx; int keySize; (void) key; /* sanity check */ if (in == NULL || out == NULL || *outLen <= 0 || info == NULL || key == NULL){ return BAD_FUNC_ARG; } keySize = (int)key->ctx.keySz; message_hash.pdata =(byte*)in; message_hash.data_length = inLen; message_hash.data_type = info->keyflgs_crypt.bits.message_type;/* message 0, hash 1 */ signature.pdata = out; signature.data_length = (word32)*outLen; #if defined(WOLFSSL_RENESAS_RSIP) message_hash.hash_type = signature.hash_type = info->hash_type; /* hash type */ #endif if ((ret = wc_fspsm_hw_lock()) == 0) { if (keySize == 1024) { ret = FSPSM_RSA1024_VRY_FUNC(&signature, &message_hash, (FSPSM_RSA1024_WPB_KEY *) key->ctx.wrapped_pub1024_key, HW_SCE_RSA_HASH_SHA256); } else { ret = FSPSM_RSA2048_VRY_FUNC(&signature, &message_hash, (FSPSM_RSA2048_WPB_KEY *) key->ctx.wrapped_pub2048_key, HW_SCE_RSA_HASH_SHA256 ); } wc_fspsm_hw_unlock(); } return ret; } #endif /* !NO_RSA && WOLFSSL_RENESAS_FSPSM_CRYPTONLY */