#include <wolfssl/wolfcrypt/settings.h>
#if !defined(NO_RSA) && \
defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)
#include <string.h>
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/port/Renesas/renesas_fspsm_internal.h>
#if defined(WOLFSSL_RENESAS_RSIP)
extern FSPSM_INSTANCE gFSPSM_ctrl;
#endif
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;
}
WOLFSSL_LOCAL int wc_fspsm_MakeRsaKey(RsaKey *key, int size, void* ctx)
{
FSPSM_ST *info = (FSPSM_ST*)ctx;
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;
}
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;
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;
}
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;
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;
signature.pdata = out;
signature.data_length = *outLen;
#if defined(WOLFSSL_RENESAS_RSIP)
message_hash.hash_type = signature.hash_type =
info->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;
}
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;
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;
signature.pdata = out;
signature.data_length = (word32)*outLen;
#if defined(WOLFSSL_RENESAS_RSIP)
message_hash.hash_type = signature.hash_type =
info->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