Skip to content

Commit

Permalink
Merge pull request #7907 from ColtonWilley/rsa_pad_crypto_cb
Browse files Browse the repository at this point in the history
Add new crypto callback for RSA with padding.
  • Loading branch information
SparkiDev authored Sep 5, 2024
2 parents 6fc9dca + 3b5d0aa commit 96e2c51
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 6 deletions.
12 changes: 12 additions & 0 deletions doc/dox_comments/header_files/rsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,12 @@ int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
if (ret < 0) {
return -1;
}
if (ret != inLen) {
return -1;
}
if (XMEMCMP(in, plain, ret) != 0) {
return -1;
}
\endcode
\sa wc_RsaPad
Expand Down Expand Up @@ -403,6 +409,12 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out,
if (ret < 0) {
return -1;
}
if (ret != inLen) {
return -1;
}
if (XMEMCMP(in, plain, ret) != 0) {
return -1;
}
\endcode
\sa wc_RsaSSL_Sign
Expand Down
71 changes: 71 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -88162,6 +88162,77 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
info->pk.rsa.type, ret, *info->pk.rsa.outLen);
#endif
}
#ifdef WOLF_CRYPTO_CB_RSA_PAD
else if (info->pk.type == WC_PK_TYPE_RSA_PKCS ||
info->pk.type == WC_PK_TYPE_RSA_PSS ||
info->pk.type == WC_PK_TYPE_RSA_OAEP) {
RsaKey key;

if (info->pk.rsa.type == RSA_PUBLIC_ENCRYPT ||
info->pk.rsa.type == RSA_PUBLIC_DECRYPT) {
/* Have all public key ops fall back to SW */
return CRYPTOCB_UNAVAILABLE;
}

if (info->pk.rsa.padding == NULL) {
return BAD_FUNC_ARG;
}

/* Initialize key */
ret = load_pem_key_file_as_der(privKeyFile, &pDer,
&keyFormat);
if (ret != 0) {
return ret;
}

ret = wc_InitRsaKey(&key, HEAP_HINT);
if (ret == 0) {
word32 keyIdx = 0;
/* load RSA private key and perform private transform */
ret = wc_RsaPrivateKeyDecode(pDer->buffer, &keyIdx,
&key, pDer->length);
}
/* Perform RSA operation */
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_PKCS)) {
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
ret = wc_RsaSSL_Sign(info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, *info->pk.rsa.outLen, &key,
info->pk.rsa.rng);
#else
ret = CRYPTOCB_UNAVAILABLE;
#endif
}
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_PSS)) {
#ifdef WC_RSA_PSS
ret = wc_RsaPSS_Sign_ex(info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, *info->pk.rsa.outLen,
info->pk.rsa.padding->hash, info->pk.rsa.padding->mgf,
info->pk.rsa.padding->saltLen, &key, info->pk.rsa.rng);
#else
ret = CRYPTOCB_UNAVAILABLE;
#endif
}
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_OAEP)) {
#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING)
ret = wc_RsaPrivateDecrypt_ex(
info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, *info->pk.rsa.outLen,
&key, WC_RSA_OAEP_PAD, info->pk.rsa.padding->hash,
info->pk.rsa.padding->mgf, info->pk.rsa.padding->label,
info->pk.rsa.padding->labelSz);
#else
ret = CRYPTOCB_UNAVAILABLE;
#endif
}

if (ret > 0) {
*info->pk.rsa.outLen = ret;
}

wc_FreeRsaKey(&key);
wc_FreeDer(&pDer); pDer = NULL;
}
#endif /* ifdef WOLF_CRYPTO_CB_RSA_PAD */
#endif /* !NO_RSA */
#ifdef HAVE_ECC
if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) {
Expand Down
56 changes: 56 additions & 0 deletions wolfcrypt/src/cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,62 @@ int wc_CryptoCb_Rsa(const byte* in, word32 inLen, byte* out,
return wc_CryptoCb_TranslateErrorCode(ret);
}

#ifdef WOLF_CRYPTO_CB_RSA_PAD
int wc_CryptoCb_RsaPad(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key, WC_RNG* rng,
RsaPadding *padding)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;
int pk_type;

if (key == NULL)
return ret;

/* locate registered callback */
dev = wc_CryptoCb_FindDevice(key->devId, WC_ALGO_TYPE_PK);

if (padding) {
switch(padding->pad_type) {
#ifndef NO_PKCS11_RSA_PKCS
case WC_RSA_PKCSV15_PAD:
pk_type = WC_PK_TYPE_RSA_PKCS;
break;
case WC_RSA_PSS_PAD:
pk_type = WC_PK_TYPE_RSA_PSS;
break;
case WC_RSA_OAEP_PAD:
pk_type = WC_PK_TYPE_RSA_OAEP;
break;
#endif /* NO_PKCS11_RSA_PKCS */
default:
pk_type = WC_PK_TYPE_RSA;
}
} else {
pk_type = WC_PK_TYPE_RSA;
}

if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
cryptoInfo.pk.type = pk_type;
cryptoInfo.pk.rsa.in = in;
cryptoInfo.pk.rsa.inLen = inLen;
cryptoInfo.pk.rsa.out = out;
cryptoInfo.pk.rsa.outLen = outLen;
cryptoInfo.pk.rsa.type = type;
cryptoInfo.pk.rsa.key = key;
cryptoInfo.pk.rsa.rng = rng;
cryptoInfo.pk.rsa.padding = padding;

ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}

return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif

#ifdef WOLFSSL_KEY_GEN
int wc_CryptoCb_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
{
Expand Down
62 changes: 62 additions & 0 deletions wolfcrypt/src/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -3127,6 +3127,9 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
int ret = 0;
(void)rng;
(void)checkSmallCt;
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
RsaPadding padding;
#endif

if (key == NULL || in == NULL || inLen == 0 || out == NULL ||
outLen == NULL || *outLen == 0 || type == RSA_TYPE_UNKNOWN) {
Expand All @@ -3138,7 +3141,18 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
if (key->devId != INVALID_DEVID)
#endif
{
#if defined(WOLF_CRYPTO_CB_RSA_PAD)
/* If we are here, either the RSA PAD callback was already called
* and returned that it could not implement for that padding scheme,
* or this is a public verify operation. Either way indicate to the
* callback that this should be a raw RSA operation with no padding.*/
XMEMSET(&padding, 0, sizeof(RsaPadding));
padding.pad_type = WC_RSA_NO_PAD;
ret = wc_CryptoCb_RsaPad(in, inLen, out,
outLen, type, key, rng, &padding);
#else
ret = wc_CryptoCb_Rsa(in, inLen, out, outLen, type, key, rng);
#endif
#ifndef WOLF_CRYPTO_CB_ONLY_RSA
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
Expand Down Expand Up @@ -3246,6 +3260,9 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
int ret = 0;
int sz;
int state;
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
RsaPadding padding;
#endif

if (in == NULL || inLen == 0 || out == NULL || key == NULL) {
return BAD_FUNC_ARG;
Expand Down Expand Up @@ -3342,6 +3359,29 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
#endif
#endif /* WOLFSSL_SE050 */

#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
if (key->devId != INVALID_DEVID) {
XMEMSET(&padding, 0, sizeof(RsaPadding));
padding.pad_value = pad_value;
padding.pad_type = pad_type;
padding.hash = hash;
padding.mgf = mgf;
padding.label = label;
padding.labelSz = labelSz;
padding.saltLen = saltLen;
ret = wc_CryptoCb_RsaPad(in, inLen, out, &outLen, rsa_type, key, rng,
&padding);

if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
if (ret < 0) {
break;
}

ret = outLen;
break;
}
}
#endif
key->state = RSA_STATE_ENCRYPT_PAD;
ret = wc_RsaPad_ex(in, inLen, out, (word32)sz, pad_value, rng, pad_type,
hash, mgf, label, labelSz, saltLen,
Expand Down Expand Up @@ -3421,6 +3461,9 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
{
int ret = WC_NO_ERR_TRACE(RSA_WRONG_TYPE_E);
byte* pad = NULL;
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
RsaPadding padding;
#endif

if (in == NULL || inLen == 0 || out == NULL || key == NULL) {
return BAD_FUNC_ARG;
Expand Down Expand Up @@ -3531,6 +3574,25 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
FALL_THROUGH;

case RSA_STATE_DECRYPT_EXPTMOD:
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
if ((key->devId != INVALID_DEVID) && (rsa_type != RSA_PUBLIC_DECRYPT)) {
/* Everything except verify goes to crypto cb if
* WOLF_CRYPTO_CB_RSA_PAD defined */
XMEMSET(&padding, 0, sizeof(RsaPadding));
padding.pad_value = pad_value;
padding.pad_type = pad_type;
padding.hash = hash;
padding.mgf = mgf;
padding.label = label;
padding.labelSz = labelSz;
padding.saltLen = saltLen;
ret = wc_CryptoCb_RsaPad(in, inLen, out,
&outLen, rsa_type, key, rng, &padding);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
break;
}
}
#endif
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE) && \
!defined(WOLFSSL_NO_MALLOC)
ret = wc_RsaFunction_ex(key->data, inLen, key->data, &key->dataLen,
Expand Down
Loading

0 comments on commit 96e2c51

Please sign in to comment.