wolfssl/wolfcrypt/src/port/Renesas/renesas_common.c

1103 lines
36 KiB
C

/* renesas_common.c
*
* Copyright (C) 2006-2022 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 2 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 <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_TSIP_TLS)
#if defined(WOLFSSL_RENESAS_SCEPROTECT)
#include <wolfssl/wolfcrypt/port/Renesas/renesas-sce-crypt.h>
#elif defined(WOLFSSL_RENESAS_TSIP_TLS)
#include <wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h>
#endif
#include <wolfssl/wolfcrypt/wc_port.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/internal.h>
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
uint32_t g_CAscm_Idx = (uint32_t)-1; /* index of CM table */
static int gdevId = 7890; /* initial dev Id for Crypt Callback */
#ifdef WOLF_CRYPTO_CB
#include <wolfssl/wolfcrypt/cryptocb.h>
/* Renesas Security Library Common Callback
* For Crypto Callbacks
*
* devIdArg device Id
* info pointer to wc_CryptInfo
* ctx Crypto Callback context
* return 0 on success, otherwise MEMORY_E or BAD_FUNC_ARG on failure
*/
static int Renesas_cmn_CryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
{
int ret = NOT_COMPILED_IN; /* return this to bypass HW and use SW */
WOLFSSL_ENTER("Renesas_cmn_CryptoDevCb");
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
TsipUserCtx* cbInfo = (TsipUserCtx*)ctx;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
User_SCEPKCbInfo* cbInfo = (User_SCEPKCbInfo*)ctx;
#endif
if (info == NULL || ctx == NULL)
return BAD_FUNC_ARG;
#ifdef DEBUG_WOLFSSL
printf("CryptoDevCb: Algo Type %d session key set: %d\n",
info->algo_type, cbInfo->session_key_set);
#endif
#if defined(WOLFSSL_RENESAS_TSIP)
if (info->algo_type == WC_ALGO_TYPE_CIPHER) {
#if !defined(NO_AES) || !defined(NO_DES3)
#ifdef HAVE_AESGCM
if (info->cipher.type == WC_CIPHER_AES_GCM &&
cbInfo->session_key_set == 1) {
if (info->cipher.enc) {
ret = wc_tsip_AesGcmEncrypt(
info->cipher.aesgcm_enc.aes,
(byte*)info->cipher.aesgcm_enc.out,
(byte*)info->cipher.aesgcm_enc.in,
info->cipher.aesgcm_enc.sz,
(byte*)info->cipher.aesgcm_enc.iv,
info->cipher.aesgcm_enc.ivSz,
(byte*)info->cipher.aesgcm_enc.authTag,
info->cipher.aesgcm_enc.authTagSz,
(byte*)info->cipher.aesgcm_enc.authIn,
info->cipher.aesgcm_enc.authInSz,
(void*)ctx);
}
else {
ret = wc_tsip_AesGcmDecrypt(
info->cipher.aesgcm_dec.aes,
(byte*)info->cipher.aesgcm_dec.out,
(byte*)info->cipher.aesgcm_dec.in,
info->cipher.aesgcm_dec.sz,
(byte*)info->cipher.aesgcm_dec.iv,
info->cipher.aesgcm_dec.ivSz,
(byte*)info->cipher.aesgcm_dec.authTag,
info->cipher.aesgcm_dec.authTagSz,
(byte*)info->cipher.aesgcm_dec.authIn,
info->cipher.aesgcm_dec.authInSz,
(void*)ctx);
}
}
#endif /* HAVE_AESGCM */
#ifdef HAVE_AES_CBC
if (info->cipher.type == WC_CIPHER_AES_CBC &&
cbInfo->session_key_set == 1) {
if (info->cipher.enc) {
ret = wc_tsip_AesCbcEncrypt(
info->cipher.aescbc.aes,
(byte*)info->cipher.aescbc.out,
(byte*)info->cipher.aescbc.in,
info->cipher.aescbc.sz);
}
else {
ret = wc_tsip_AesCbcDecrypt(
info->cipher.aescbc.aes,
(byte*)info->cipher.aescbc.out,
(byte*)info->cipher.aescbc.in,
info->cipher.aescbc.sz);
}
}
#endif /* HAVE_AES_CBC */
#endif /* !NO_AES || !NO_DES3 */
}
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (info->algo_type == WC_ALGO_TYPE_CIPHER) {
#if !defined(NO_AES) || !defined(NO_DES3)
#ifdef HAVE_AESGCM
if (info->cipher.type == WC_CIPHER_AES_GCM) {
if (info->cipher.enc &&
(cbInfo->session_key_set == 1 ||
(cbInfo->aes256_installedkey_set == 1 &&
info->cipher.aesgcm_enc.aes->keylen == 32) ||
(cbInfo->aes128_installedkey_set == 1 &&
info->cipher.aesgcm_enc.aes->keylen == 16))) {
if (cbInfo->aes256_installedkey_set == 1 &&
info->cipher.aesgcm_enc.aes->keylen == 32) {
XMEMCPY(&info->cipher.aesgcm_enc.aes->ctx.sce_wrapped_key,
&cbInfo->sce_wrapped_key_aes256,
sizeof(sce_aes_wrapped_key_t));
info->cipher.aesgcm_enc.aes->ctx.keySize = 32;
}
else if (cbInfo->aes128_installedkey_set == 1 &&
info->cipher.aesgcm_enc.aes->keylen == 16) {
XMEMCPY(&info->cipher.aesgcm_enc.aes->ctx.sce_wrapped_key,
&cbInfo->sce_wrapped_key_aes128,
sizeof(sce_aes_wrapped_key_t));
info->cipher.aesgcm_enc.aes->ctx.keySize = 16;
}
ret = wc_sce_AesGcmEncrypt(
info->cipher.aesgcm_enc.aes,
(byte*)info->cipher.aesgcm_enc.out,
(byte*)info->cipher.aesgcm_enc.in,
info->cipher.aesgcm_enc.sz,
(byte*)info->cipher.aesgcm_enc.iv,
info->cipher.aesgcm_enc.ivSz,
(byte*)info->cipher.aesgcm_enc.authTag,
info->cipher.aesgcm_enc.authTagSz,
(byte*)info->cipher.aesgcm_enc.authIn,
info->cipher.aesgcm_enc.authInSz,
(void*)ctx);
}
else if (cbInfo->session_key_set == 1 ||
(cbInfo->aes256_installedkey_set == 1 &&
info->cipher.aesgcm_dec.aes->keylen == 32) ||
(cbInfo->aes128_installedkey_set == 1 &&
info->cipher.aesgcm_dec.aes->keylen == 16)) {
if (cbInfo->aes256_installedkey_set == 1 &&
info->cipher.aesgcm_dec.aes->keylen == 32) {
XMEMCPY(&info->cipher.aesgcm_dec.aes->ctx.sce_wrapped_key,
&cbInfo->sce_wrapped_key_aes256,
sizeof(sce_aes_wrapped_key_t));
info->cipher.aesgcm_dec.aes->ctx.keySize = 32;
}
else if (cbInfo->aes128_installedkey_set == 1 &&
info->cipher.aesgcm_dec.aes->keylen == 16) {
XMEMCPY(&info->cipher.aesgcm_dec.aes->ctx.sce_wrapped_key,
&cbInfo->sce_wrapped_key_aes128,
sizeof(sce_aes_wrapped_key_t));
info->cipher.aesgcm_dec.aes->ctx.keySize = 16;
}
ret = wc_sce_AesGcmDecrypt(
info->cipher.aesgcm_dec.aes,
(byte*)info->cipher.aesgcm_dec.out,
(byte*)info->cipher.aesgcm_dec.in,
info->cipher.aesgcm_dec.sz,
(byte*)info->cipher.aesgcm_dec.iv,
info->cipher.aesgcm_dec.ivSz,
(byte*)info->cipher.aesgcm_dec.authTag,
info->cipher.aesgcm_dec.authTagSz,
(byte*)info->cipher.aesgcm_dec.authIn,
info->cipher.aesgcm_dec.authInSz,
(void*)ctx);
}
}
#endif /* HAVE_AESGCM */
#ifdef HAVE_AES_CBC
if ((info->cipher.type == WC_CIPHER_AES_CBC) &&
(cbInfo->session_key_set == 1 ||
(cbInfo->aes256_installedkey_set == 1 &&
info->cipher.aescbc.aes->keylen == 32) ||
(cbInfo->aes128_installedkey_set == 1 &&
info->cipher.aescbc.aes->keylen == 16))) {
if (info->cipher.enc) {
if (cbInfo->aes256_installedkey_set == 1 &&
info->cipher.aescbc.aes->keylen == 32) {
XMEMCPY(&info->cipher.aescbc.aes->ctx.sce_wrapped_key,
&cbInfo->sce_wrapped_key_aes256,
sizeof(sce_aes_wrapped_key_t));
info->cipher.aescbc.aes->ctx.keySize = 32;
}
else if (cbInfo->aes128_installedkey_set == 1 &&
info->cipher.aescbc.aes->keylen == 16) {
XMEMCPY(&info->cipher.aescbc.aes->ctx.sce_wrapped_key,
&cbInfo->sce_wrapped_key_aes128,
sizeof(sce_aes_wrapped_key_t));
info->cipher.aescbc.aes->ctx.keySize = 16;
}
ret = wc_sce_AesCbcEncrypt(
info->cipher.aescbc.aes,
(byte*)info->cipher.aescbc.out,
(byte*)info->cipher.aescbc.in,
info->cipher.aescbc.sz);
}
else {
if (cbInfo->aes256_installedkey_set == 1 &&
info->cipher.aescbc.aes->keylen == 32) {
XMEMCPY(&info->cipher.aescbc.aes->ctx.sce_wrapped_key,
&cbInfo->sce_wrapped_key_aes256,
sizeof(sce_aes_wrapped_key_t));
info->cipher.aescbc.aes->ctx.keySize = 32;
} else if (cbInfo->aes128_installedkey_set == 1 &&
info->cipher.aescbc.aes->keylen == 16) {
XMEMCPY(&info->cipher.aescbc.aes->ctx.sce_wrapped_key,
&cbInfo->sce_wrapped_key_aes128,
sizeof(sce_aes_wrapped_key_t));
info->cipher.aescbc.aes->ctx.keySize = 16;
}
ret = wc_sce_AesCbcDecrypt(
info->cipher.aescbc.aes,
(byte*)info->cipher.aescbc.out,
(byte*)info->cipher.aescbc.in,
info->cipher.aescbc.sz);
}
}
#endif /* HAVE_AES_CBC */
#endif /* !NO_AES || !NO_DES3 */
}
#endif /* TSIP or SCE */
(void)devIdArg;
(void)ctx;
return ret;
}
/* Renesas Security Library Common Entry Point
* For usable method
*
* ssl : a pointer to WOLFSSL object
* session_key_generated : if session key has been generated
* return 1 for usable, 0 for unusable
*/
int Renesas_cmn_usable(const WOLFSSL* ssl, byte session_key_generated)
{
int ret;
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
ret = tsip_usable(ssl, session_key_generated);
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
ret = wc_sce_usable(ssl, session_key_generated);
#endif
return ret;
}
/* Renesas Security Library Common Method
* Crypt Callback initialization
*
* ssl : a pointer to WOLFSSL object
* ctx : callback context
* return valid device Id on success, otherwise INVALID_DEVIID
* device Id starts from 7890, and increases + 1 its number
* when the method is successfully called.
*/
int wc_CryptoCb_CryptInitRenesasCmn(WOLFSSL* ssl, void* ctx)
{
(void)ssl;
(void)ctx;
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
TsipUserCtx* cbInfo = (TsipUserCtx*)ctx;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
User_SCEPKCbInfo* cbInfo = (User_SCEPKCbInfo*)ctx;
#endif
if (cbInfo == NULL || ssl == NULL) {
return INVALID_DEVID;
}
cbInfo->devId = gdevId++;
if (wc_CryptoCb_RegisterDevice(cbInfo->devId,
Renesas_cmn_CryptoDevCb, cbInfo) < 0) {
/* undo devId number */
gdevId--;
return INVALID_DEVID;
}
if (ssl)
wolfSSL_SetDevId(ssl, cbInfo->devId);
/* sanity check for overflow */
if (gdevId < 0) {
gdevId = 7890;
}
return cbInfo->devId;
}
/* Renesas Security Library Common Method
* Clean up CryptCb
*
* id : a pointer to device id to unregister
* no return value
*/
void wc_CryptoCb_CleanupRenesasCmn(int* id)
{
wc_CryptoCb_UnRegisterDevice(*id);
*id = INVALID_DEVID;
}
#endif /* WOLF_CRYPTO_CB */
/* Renesas Security Library Common Method
* Check CA index if CA can be used for SCE/TSIP because
* the CA has been verified by SCE/TSIP
*
* cmdIdx : ca index
* return 1 can be used, otherwise 0
*/
WOLFSSL_LOCAL byte Renesas_cmn_checkCA(word32 cmIdx)
{
WOLFSSL_ENTER("Renesas_cmn_checkCA");
return (cmIdx == g_CAscm_Idx? 1:0);
}
/* check if the root CA has been verified by TSIP/SCE,
* and it exists in the CM table.
*/
static byte sce_tsip_rootCAverified(void)
{
WOLFSSL_ENTER("sce_tsip_rootCAverified");
return (g_CAscm_Idx != (uint32_t)-1 ? 1:0);
}
/* Renesas Security Library Common Callback
* Callback for Rsa verify
*
* ssl the WOLFSSL object
* sig Buffer holding signature
* sigSz Length of signature in bytes
* out Buffer to hold hash
* key Buffer to hold ecc key
* keySz Length of key in bytes
* return FSP_SUCCESS(0) on success, otherwise FSP/TSIP error code
*/
WOLFSSL_LOCAL int Renesas_cmn_RsaVerify(WOLFSSL* ssl, unsigned char* sig,
unsigned int sigSz, unsigned char** out,
const unsigned char* key, unsigned int keySz, void* ctx)
{
int ret = 0;
WOLFSSL_ENTER("Renesas_cmn_RsaVerify");
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
ret = wc_tsip_RsaVerify(ssl, sig, sigSz, out, key, keySz, ctx);
if (ret == 0) {
/* Set Callback for SharedSecret when successful */
wolfSSL_CTX_SetEccSharedSecretCb(ssl->ctx, wc_tsip_EccSharedSecret);
wolfSSL_SetEccSharedSecretCtx(ssl, ctx);
}
else {
WOLFSSL_MSG("failed wc_tsip_RsaVerify");
wolfSSL_CTX_SetEccSharedSecretCb(ctx, NULL);
wolfSSL_SetEccSharedSecretCtx(ssl, NULL);
}
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
ret = wc_SCE_RsaVerify(ssl, sig, sigSz, out,key, keySz, ctx);
if (ret == 0) {
/* Set Callback for SharedSecret when successful */
wolfSSL_CTX_SetEccSharedSecretCb(ssl->ctx, SCE_EccSharedSecret);
wolfSSL_SetEccSharedSecretCtx(ssl, ctx);
}
else {
WOLFSSL_MSG("failed R_SCE_TLS_ServerKeyExchangeVerify");
wolfSSL_CTX_SetEccSharedSecretCb(ctx, NULL);
wolfSSL_SetEccSharedSecretCtx(ssl, NULL);
}
#endif
return ret;
}
/* Renesas Security Library Common Callback
* Callback for Ecc verify
*
* ssl the WOLFSSL object
* sig Buffer holding signature
* sigSz Length of signature in bytes
* hash Buffer to hold hash
* hashSz Length of hash
* key Buffer to hold ecc key
* keySz Length of key in bytes
* result a pointer to int indicates if the verify is ok
* return FSP_SUCCESS(0) on success, otherwise FSP/TSIP error code
*/
WOLFSSL_LOCAL int Renesas_cmn_EccVerify(WOLFSSL* ssl, const unsigned char* sig,
unsigned int sigSz, const unsigned char* hash, unsigned int hashSz,
const unsigned char* key, unsigned int keySz, int* result, void* ctx)
{
int ret = 0;
WOLFSSL_ENTER("Renesas_cmn_EccVerify");
#if defined(WOLFSSL_RENESAS_TSIP)
ret = wc_tsip_EccVerify(ssl, sig, sigSz, hash, hashSz, key, keySz,
result, ctx);
if (ret == 0 && *result == 1) {
/* Set callback for SharedSecret when being successful */
wolfSSL_CTX_SetEccSharedSecretCb(ssl->ctx, wc_tsip_EccSharedSecret);
wolfSSL_SetEccSharedSecretCtx(ssl, ctx);
}
else {
WOLFSSL_MSG("failed wc_tsip_EccVerify");
wolfSSL_CTX_SetEccSharedSecretCb(ctx, NULL);
wolfSSL_SetEccSharedSecretCtx(ssl, NULL);
}
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
ret = wc_SCE_EccVerify(ssl, sig, sigSz, hash, hashSz, key, keySz,
result, ctx);
if (ret == 0 && *result == 1) {
/* Set callback for SharedSecret when being successful */
wolfSSL_CTX_SetEccSharedSecretCb(ssl->ctx, SCE_EccSharedSecret);
wolfSSL_SetEccSharedSecretCtx(ssl, ctx);
}
else {
WOLFSSL_MSG("failed R_SCE_TLS_ServerKeyExchangeVerify");
wolfSSL_CTX_SetEccSharedSecretCb(ctx, NULL);
wolfSSL_SetEccSharedSecretCtx(ssl, NULL);
}
#endif
return ret;
}
/* Renesas Security Library Common Entry Point
* For ROOT CA verifycation
*
* cert Buffer to hold cert
* cert_len Length of cert
* key_n_start Byte position of public key in cert
* key_n_len Length of public key in bytes
* key_e_start Byte position of public key exponent in cert
* key_e_len Length of public key exponent
* cm_row CA index
* return FSP_SUCCESS(0) on success, otherwise FSP/TSIP error code
*/
int wc_Renesas_cmn_RootCertVerify(const byte* cert, word32 cert_len, word32 key_n_start,
word32 key_n_len, word32 key_e_start, word32 key_e_len, word32 cm_row)
{
int ret;
WOLFSSL_ENTER("wc_Renesas_cmn_RootCertVerify");
if (sce_tsip_rootCAverified() == 0) {
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
ret = wc_tsip_tls_RootCertVerify(cert, cert_len, key_n_start,
key_n_len, key_e_start, key_e_len, cm_row);
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
ret = wc_sce_tls_RootCertVerify(cert, cert_len, key_n_start,
key_n_len, key_e_start, key_e_len, cm_row);
#endif
}
else {
/* already verified. skipped */
ret = 0;
}
return ret;
}
/* Renesas Security Library Common Callback
* Callback for tls finished
*
* ssl the WOLFSSL object
* side CLIENT or SERVER
* handshake_hash hash while doing handshake
* hashes calculated data by SCE/TSIP pseudo random function
* return FSP_SUCCESS(0) on success, otherwise FSP/TSIP error code
*/
WOLFSSL_LOCAL int Renesas_cmn_TlsFinished(WOLFSSL* ssl, const byte *side,
const byte *handshake_hash,
byte *hashes, void* ctx)
{
int ret = -1;
(void)ctx;
WOLFSSL_ENTER("Renesas_cmn_TlsFinished");
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
ret = wc_tsip_generateVerifyData(ssl->arrays->tsip_masterSecret,
side, handshake_hash, hashes);
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (Renesas_cmn_usable(ssl, 1)) {
ret = wc_sce_generateVerifyData(ssl->arrays->sce_masterSecret,
side, handshake_hash, hashes);
}
else
ret = PROTOCOLCB_UNAVAILABLE;
#endif
return ret;
}
/* Renesas Security Library Common Callback
* Callback for setting Encrypt Keys.
* Register callback for setting Encrypt Keys when keys are generated by SCE/TSIP
*
* ssl the WOLFSSL object
* ctx Callback context
* return 0 on success, -1 when keys are not generated by SCE/TSIP
*/
static int Renesas_cmn_EncryptKeys(WOLFSSL* ssl, void* ctx)
{
int ret;
WOLFSSL_ENTER("Renesas_cmn_EncryptKeys");
/* sanity check */
if (ssl == NULL || ctx == NULL)
return BAD_FUNC_ARG;
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
TsipUserCtx* cbInfo = (TsipUserCtx*)ctx;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
User_SCEPKCbInfo* cbInfo = (User_SCEPKCbInfo*)ctx;
#endif
if (cbInfo->session_key_set == 1) {
ret = 0;
wolfSSL_CTX_SetTlsFinishedCb(ssl->ctx, Renesas_cmn_TlsFinished);
wolfSSL_SetTlsFinishedCtx(ssl, cbInfo);
}
else {
wolfSSL_CTX_SetTlsFinishedCb(ssl->ctx, NULL);
wolfSSL_SetTlsFinishedCtx(ssl, NULL);
ret = -1;
}
return ret;
}
/* Renesas Security Library Common Callback
* Callback for Session Key generation
* Register callback for Set Keys when keys are successfully
* generated by SCE/TSIP
*
* ssl the WOLFSSL object
* ctx Callback context
* return FSP_SUCCESS(0) on success, otherwise SCE/TSIP error code
*/
WOLFSSL_LOCAL int Renesas_cmn_generateSessionKey(WOLFSSL* ssl, void* ctx)
{
int ret = -1;
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
TsipUserCtx* cbInfo = (TsipUserCtx*)ctx;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
User_SCEPKCbInfo* cbInfo = (User_SCEPKCbInfo*)ctx;
#endif
(void)ctx;
WOLFSSL_ENTER("Renesas_cmn_generateSessionKey");
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
ret = wc_tsip_generateSessionKey(ssl, (TsipUserCtx*)ctx, cbInfo->devId);
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (Renesas_cmn_usable(ssl, 0)) {
ret = wc_sce_generateSessionKey(ssl, ctx, cbInfo->devId);
} else
ret = PROTOCOLCB_UNAVAILABLE;
#endif
if (ret == 0) {
wolfSSL_CTX_SetEncryptKeysCb(ssl->ctx, Renesas_cmn_EncryptKeys);
wolfSSL_SetEncryptKeysCtx(ssl, ctx);
}
else {
wolfSSL_CTX_SetEncryptKeysCb(ssl->ctx, NULL);
wolfSSL_SetEncryptKeysCtx(ssl, NULL);
}
return ret;
}
/* Renesas Security Library Common Callback
* Callback for Premaster Secret generation
* Register callback for Set Keys when keys are successfully
* generated by SCE/TSIP
*
* ssl the WOLFSSL object
* premaster Buffer to hold pre master
* preSz Length of pre-master
* ctx Callback context
* return FSP_SUCCESS(0) on success,
* otherwise PROTOCOLCB_UNAVAILABLE
* so that caller could continue to process if want
*/
WOLFSSL_LOCAL int Renesas_cmn_generatePremasterSecret(WOLFSSL* ssl,
byte *premaster, word32 preSz, void* ctx)
{
int ret;
(void) ctx;
(void) ssl;
WOLFSSL_ENTER("Renesas_cmn_generatePremasterSecret");
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
if (Renesas_cmn_usable(ssl, 0)) {
ret = wc_tsip_generatePremasterSecret(premaster, preSz);
ssl->arrays->preMasterSz = preSz;
}
else
ret = PROTOCOLCB_UNAVAILABLE;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (Renesas_cmn_usable(ssl, 0)) {
ret = wc_sce_generatePremasterSecret(premaster, preSz);
ssl->arrays->preMasterSz = preSz;
}
else
ret = PROTOCOLCB_UNAVAILABLE;
#endif
return ret;
}
/* Renesas Security Library Common Callback
* Callback for Master Secret generation
* Register callback for Session Key Generation when master secret is
* successfully generated by SCE/TSIP
*
* ssl the WOLFSSL object
* ctx Callback context
* return FSP_SUCCESS(0) on success,
* otherwise PROTOCOLCB_UNAVAILABLE
* so that caller could continue to process if want
*/
WOLFSSL_LOCAL int Renesas_cmn_genMasterSecret(struct WOLFSSL* ssl, void* ctx)
{
int ret = WOLFSSL_NOT_IMPLEMENTED;
(void) ret;
(void) ctx;
WOLFSSL_ENTER("Renesas_cmn_genMasterSecret");
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
if (Renesas_cmn_usable(ssl, 0)) {
#if (WOLFSSL_RENESAS_TSIP_VER >= 109)
ret = wc_tsip_generateMasterSecretEx(
ssl->options.cipherSuite0,
ssl->options.cipherSuite,
ssl->arrays->preMasterSecret,
ssl->arrays->clientRandom,
ssl->arrays->serverRandom,
ssl->arrays->tsip_masterSecret);
#else
ret = wc_tsip_generateMasterSecret(
ssl->arrays->preMasterSecret,
ssl->arrays->clientRandom,
ssl->arrays->serverRandom,
ssl->arrays->tsip_masterSecret);
#endif
if (ret == 0) {
wc_tsip_storeKeyCtx(ssl, (TsipUserCtx*)ctx);
/* set Session Key generation Callback for use */
wolfSSL_CTX_SetGenSessionKeyCb(ssl->ctx,
Renesas_cmn_generateSessionKey);
wolfSSL_SetGenSessionKeyCtx(ssl, ctx);
}
else {
wolfSSL_CTX_SetGenSessionKeyCb(ssl->ctx, NULL);
wolfSSL_SetGenSessionKeyCtx(ssl, NULL);
}
}
else
ret = PROTOCOLCB_UNAVAILABLE;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (Renesas_cmn_usable(ssl, 0)) {
ret = wc_sce_generateMasterSecret(
ssl->options.cipherSuite0,
ssl->options.cipherSuite,
ssl->arrays->preMasterSecret,
ssl->arrays->clientRandom,
ssl->arrays->serverRandom,
ssl->arrays->sce_masterSecret);
if (ret == 0) {
wc_sce_storeKeyCtx(ssl, ctx);
/* set Session Key generation Callback for use */
wolfSSL_CTX_SetGenSessionKeyCb(ssl->ctx,
Renesas_cmn_generateSessionKey);
wolfSSL_SetGenSessionKeyCtx(ssl, ctx);
}
else {
wolfSSL_CTX_SetGenSessionKeyCb(ssl->ctx, NULL);
wolfSSL_SetGenSessionKeyCtx(ssl, NULL);
}
}
else {
WOLFSSL_MSG("PROTOCOLCB_UNAVAILABLE\n");
ret = PROTOCOLCB_UNAVAILABLE;
}
#endif
return ret;
}
/* Renesas Security Library Common Callback
* Callback for Rsa Encryption
*
* ssl the WOLFSSL object
* in Buffer to hold plain text
* inSz Length of plain text
* out Buffer to hold cipher text
* outSz Length of cipher text buffer
* KeyDer Buffer holding Key in der format
* KeySz Length of Key Der
* ctx Callback context
* return FSP_SUCCESS(0) on success,
* otherwise CRYPTOCB_UNAVAILABLE
* so that caller could continue to process if want
*/
WOLFSSL_LOCAL int Renesas_cmn_RsaEnc(WOLFSSL* ssl, const unsigned char* in,
unsigned int inSz, unsigned char* out, word32* outSz,
const unsigned char* keyDer, unsigned int keySz, void* ctx)
{
int ret;
int EncSz;
(void)ctx;
(void)in;
(void)inSz;
(void)keyDer;
(void)keySz;
(void)EncSz;
WOLFSSL_ENTER("Renesas_cmn_RsaEnc");
/* sanity check */
if (ssl == NULL || in == NULL || out == NULL || keyDer == NULL ||
ctx == NULL) {
return BAD_FUNC_ARG;
}
EncSz = wc_RsaEncryptSize(ssl->peerRsaKey);
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
if (tsip_usable(ssl, 0)) {
if (EncSz == 256) {
ret = wc_tsip_generateEncryptPreMasterSecret(ssl, out, outSz);
}
else {
WOLFSSL_MSG("TSIP can only handle 256 bytes for RSA encrypt size.");
ret = CRYPTOCB_UNAVAILABLE;
}
}
else {
ret = CRYPTOCB_UNAVAILABLE;
}
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (wc_sce_usable(ssl, 0) && EncSz == 256) {
ret = wc_sce_generateEncryptPreMasterSecret(ssl, out, outSz);
}
else {
if (EncSz != 256)
WOLFSSL_MSG("SCE cannot use"
"because Rsa Encrypt Size isn't 256 bytes(2048 bits).");
ret = CRYPTOCB_UNAVAILABLE;
}
#endif
return ret;
}
/* Renesas Security Library Common Callback
* Callback for Verify hmac
*
* ssl the WOLFSSL object
* message Buffer to hold message
* inSz Length of message
* macSz Length of mac size
* content content of inner data
* ctx Callback context
* return FSP_SUCCESS(0) on success,
* otherwise PROTOCOLCB_UNAVAILABLE
* so that caller could continue to process if want
*/
WOLFSSL_LOCAL int Renesas_cmn_VerifyHmac(WOLFSSL *ssl, const byte* message,
word32 messageSz, word32 macSz, word32 content, void* ctx)
{
int ret;
(void)ctx;
WOLFSSL_ENTER("Renesas_cmn_VerifyHmac");
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
if (tsip_usable(ssl, 1)) {
ret = wc_tsip_ShaXHmacVerify(ssl, message, messageSz, macSz, content);
}
else
ret = PROTOCOLCB_UNAVAILABLE;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (wc_sce_usable(ssl, 1)) {
ret = wc_sce_Sha256VerifyHmac(ssl, message, messageSz, macSz, content);
}
else
ret = PROTOCOLCB_UNAVAILABLE;
#endif
return ret;
}
#ifndef WOLFSSL_AEAD_ONLY
/* Renesas Security Library Common Callback
* Callback for TLS hmac
*
* ssl the WOLFSSL object
* digest Buffer to hold digest by hmac
* in Buffer to hold in data
* sz Length of in data
* padSz Length of padding
* content content of inner data
* epochOrder
* return FSP_SUCCESS(0) on success, otherwise error code
*/
WOLFSSL_LOCAL int Renesas_cmn_TLS_hmac(WOLFSSL* ssl, byte* digest,
const byte* in, word32 sz, int padSz, int content, int verify, int epochOrder)
{
int ret;
byte myInner[WOLFSSL_TLS_HMAC_INNER_SZ];
WOLFSSL_ENTER("Renesas_cmn_TLS_hmac");
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
if (Renesas_cmn_usable(ssl, 1)) {
wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
if (ssl->specs.hash_size == WC_SHA_DIGEST_SIZE) {
ret = wc_tsip_Sha1HmacGenerate(ssl, myInner,
WOLFSSL_TLS_HMAC_INNER_SZ, in, sz, digest);
}
else if (ssl->specs.hash_size == WC_SHA256_DIGEST_SIZE) {
ret = wc_tsip_Sha256HmacGenerate(ssl, myInner,
WOLFSSL_TLS_HMAC_INNER_SZ, in, sz, digest);
}
else {
ret = TSIP_MAC_DIGSZ_E;
}
}
else {
WOLFSSL_MSG("TLS_hmac is used instead of TSIP");
/* fall through to original TLS hmac method when TSIP cannot be used */
ret = TLS_hmac(ssl, digest, in, sz, padSz, content, verify, epochOrder);
}
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (Renesas_cmn_usable(ssl, 1)) {
if (ssl->specs.hash_size == WC_SHA256_DIGEST_SIZE) {
wolfSSL_SetTlsHmacInner(ssl, myInner, sz, content, verify);
ret = wc_sce_Sha256GenerateHmac(ssl, myInner,
WOLFSSL_TLS_HMAC_INNER_SZ, in, sz, digest);
}
else
ret = TSIP_MAC_DIGSZ_E;
}
else {
/* fall through to original TLS hmac method when SCE cannot be used */
ret = TLS_hmac(ssl, digest, in, sz, padSz, content, verify, epochOrder);
}
#endif
return ret;
}
#endif /* !WOLFSSL_AEAD_ONLY */
/* Renesas Security Library Common Callback
* Callback for Signature PK Rsa verify
*
* sig Buffer holding signature
* sigSz Length of signature in bytes
* out Buffer to hold hash
* keyDer Buffer to hold rsa key
* keySz Length of key in bytes
* ctx Callback context
* return FSP_SUCCESS(0) on success,
* otherwise CRYPTOCB_UNAVAILABLE
* so that caller could continue to process if want
*/
WOLFSSL_LOCAL int Renesas_cmn_SigPkCbRsaVerify(unsigned char* sig,
unsigned int sigSz, unsigned char** out, const unsigned char* keyDer,
unsigned int keySz, void* ctx)
{
int ret;
CertAttribute* CertAtt;
(void)out;
(void)keyDer;
(void)keySz;
WOLFSSL_ENTER("Renesas_cmn_SigPkCbRsaVerify");
/* sanity check */
if (sig == NULL || out == NULL || keyDer == NULL || ctx == NULL)
return BAD_FUNC_ARG;
CertAtt = (CertAttribute*)ctx;
if (!CertAtt) {
return CRYPTOCB_UNAVAILABLE;
}
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
if (CertAtt->keyIndex != NULL) {
ret = wc_tsip_tls_CertVerify(CertAtt->cert, CertAtt->certSz, sig, sigSz,
CertAtt->pubkey_n_start - CertAtt->certBegin,
CertAtt->pubkey_n_len - 1,
CertAtt->pubkey_e_start - CertAtt->certBegin,
CertAtt->pubkey_e_len -1,
(uint8_t*)CertAtt->keyIndex);
if (ret == 0) {
CertAtt->verifyByTSIP_SCE = 1;
}
else {
WOLFSSL_MSG("RSA Verify by TSIP didn't match");
ret = ASN_SIG_CONFIRM_E;
}
}
else
ret = CRYPTOCB_UNAVAILABLE;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (CertAtt->keyIndex != NULL) {
ret = wc_sce_tls_CertVerify(CertAtt->cert, CertAtt->certSz, sig, sigSz,
CertAtt->pubkey_n_start - CertAtt->certBegin,
CertAtt->pubkey_n_len - 1,
CertAtt->pubkey_e_start - CertAtt->certBegin,
CertAtt->pubkey_e_len -1,
(uint8_t*)CertAtt->keyIndex);
if (ret == 0) {
CertAtt->verifyByTSIP_SCE = 1;
}
else {
WOLFSSL_MSG("RSA Verify by SCE didn't match");
ret = ASN_SIG_CONFIRM_E;
}
}
else
ret = CRYPTOCB_UNAVAILABLE;
#endif
return ret;
}
/* Renesas Security Library Common Callback
* Callback for Signature PK Ecc verify
*
* sig Buffer holding signature
* sigSz Length of signature in bytes
* has Buffer to hold hash
* hashSz Length of hash
* keyDer Buffer to hold rsa key
* keySz Length of key in bytes
* result A pointer to int indicates a result
* ctx Callback context
* return FSP_SUCCESS(0) on success,
* otherwise CRYPTOCB_UNAVAILABLE
* so that caller could continue to process if want
*/
WOLFSSL_LOCAL int Renesas_cmn_SigPkCbEccVerify(const unsigned char* sig,
unsigned int sigSz, const unsigned char* hash, unsigned int hashSz,
const unsigned char* keyDer, unsigned int keySz,
int* result, void* ctx)
{
int ret;
CertAttribute* CertAtt;
(void)result;
(void)keyDer;
(void)keySz;
(void)hash;
(void)hashSz;
WOLFSSL_ENTER("Renesas_cmn_SigPkCbEccVerify");
/* sanity check */
if (sig == NULL || keyDer == NULL || hash == NULL || ctx == NULL ||
result == NULL)
return BAD_FUNC_ARG;
CertAtt = (CertAttribute*)ctx;
if (!CertAtt) {
return CRYPTOCB_UNAVAILABLE;
}
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
if (CertAtt->keyIndex != NULL) {
ret = wc_tsip_tls_CertVerify(CertAtt->cert, CertAtt->certSz, sig, sigSz,
CertAtt->pubkey_n_start - CertAtt->certBegin,
CertAtt->pubkey_n_len - 1,
CertAtt->pubkey_e_start - CertAtt->certBegin,
CertAtt->pubkey_e_len -1,
(uint8_t*)CertAtt->keyIndex);
if (ret == 0) {
CertAtt->verifyByTSIP_SCE = 1;
*result = 1;
}
else {
WOLFSSL_MSG("RSA Verify by TSIP didn't match");
ret = ASN_SIG_CONFIRM_E;
}
}
else
ret = CRYPTOCB_UNAVAILABLE;
#elif defined(WOLFSSL_RENESAS_SCEPROTECT)
if (CertAtt->keyIndex != NULL) {
ret = wc_sce_tls_CertVerify(CertAtt->cert, CertAtt->certSz, sig, sigSz,
CertAtt->pubkey_n_start - CertAtt->certBegin,
CertAtt->pubkey_n_len - 1,
CertAtt->pubkey_e_start - CertAtt->certBegin,
CertAtt->pubkey_e_len -1,
(uint8_t*)CertAtt->keyIndex);
if (ret == 0) {
CertAtt->verifyByTSIP_SCE = 1;
*result = 1;
}
else {
WOLFSSL_MSG("RSA Verify by SCE didn't match");
ret = ASN_SIG_CONFIRM_E;
}
}
else
ret = CRYPTOCB_UNAVAILABLE;
#endif
return ret;
}
#endif /* SCEPROTECT || TSIP */