Skip to content

Commit 96e2c51

Browse files
authored
Merge pull request #7907 from ColtonWilley/rsa_pad_crypto_cb
Add new crypto callback for RSA with padding.
2 parents 6fc9dca + 3b5d0aa commit 96e2c51

9 files changed

Lines changed: 456 additions & 6 deletions

File tree

doc/dox_comments/header_files/rsa.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,12 @@ int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
333333
if (ret < 0) {
334334
return -1;
335335
}
336+
if (ret != inLen) {
337+
return -1;
338+
}
339+
if (XMEMCMP(in, plain, ret) != 0) {
340+
return -1;
341+
}
336342
\endcode
337343
338344
\sa wc_RsaPad
@@ -403,6 +409,12 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out,
403409
if (ret < 0) {
404410
return -1;
405411
}
412+
if (ret != inLen) {
413+
return -1;
414+
}
415+
if (XMEMCMP(in, plain, ret) != 0) {
416+
return -1;
417+
}
406418
\endcode
407419
408420
\sa wc_RsaSSL_Sign

tests/api.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88162,6 +88162,77 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
8816288162
info->pk.rsa.type, ret, *info->pk.rsa.outLen);
8816388163
#endif
8816488164
}
88165+
#ifdef WOLF_CRYPTO_CB_RSA_PAD
88166+
else if (info->pk.type == WC_PK_TYPE_RSA_PKCS ||
88167+
info->pk.type == WC_PK_TYPE_RSA_PSS ||
88168+
info->pk.type == WC_PK_TYPE_RSA_OAEP) {
88169+
RsaKey key;
88170+
88171+
if (info->pk.rsa.type == RSA_PUBLIC_ENCRYPT ||
88172+
info->pk.rsa.type == RSA_PUBLIC_DECRYPT) {
88173+
/* Have all public key ops fall back to SW */
88174+
return CRYPTOCB_UNAVAILABLE;
88175+
}
88176+
88177+
if (info->pk.rsa.padding == NULL) {
88178+
return BAD_FUNC_ARG;
88179+
}
88180+
88181+
/* Initialize key */
88182+
ret = load_pem_key_file_as_der(privKeyFile, &pDer,
88183+
&keyFormat);
88184+
if (ret != 0) {
88185+
return ret;
88186+
}
88187+
88188+
ret = wc_InitRsaKey(&key, HEAP_HINT);
88189+
if (ret == 0) {
88190+
word32 keyIdx = 0;
88191+
/* load RSA private key and perform private transform */
88192+
ret = wc_RsaPrivateKeyDecode(pDer->buffer, &keyIdx,
88193+
&key, pDer->length);
88194+
}
88195+
/* Perform RSA operation */
88196+
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_PKCS)) {
88197+
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
88198+
ret = wc_RsaSSL_Sign(info->pk.rsa.in, info->pk.rsa.inLen,
88199+
info->pk.rsa.out, *info->pk.rsa.outLen, &key,
88200+
info->pk.rsa.rng);
88201+
#else
88202+
ret = CRYPTOCB_UNAVAILABLE;
88203+
#endif
88204+
}
88205+
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_PSS)) {
88206+
#ifdef WC_RSA_PSS
88207+
ret = wc_RsaPSS_Sign_ex(info->pk.rsa.in, info->pk.rsa.inLen,
88208+
info->pk.rsa.out, *info->pk.rsa.outLen,
88209+
info->pk.rsa.padding->hash, info->pk.rsa.padding->mgf,
88210+
info->pk.rsa.padding->saltLen, &key, info->pk.rsa.rng);
88211+
#else
88212+
ret = CRYPTOCB_UNAVAILABLE;
88213+
#endif
88214+
}
88215+
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_OAEP)) {
88216+
#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING)
88217+
ret = wc_RsaPrivateDecrypt_ex(
88218+
info->pk.rsa.in, info->pk.rsa.inLen,
88219+
info->pk.rsa.out, *info->pk.rsa.outLen,
88220+
&key, WC_RSA_OAEP_PAD, info->pk.rsa.padding->hash,
88221+
info->pk.rsa.padding->mgf, info->pk.rsa.padding->label,
88222+
info->pk.rsa.padding->labelSz);
88223+
#else
88224+
ret = CRYPTOCB_UNAVAILABLE;
88225+
#endif
88226+
}
88227+
88228+
if (ret > 0) {
88229+
*info->pk.rsa.outLen = ret;
88230+
}
88231+
88232+
wc_FreeRsaKey(&key);
88233+
wc_FreeDer(&pDer); pDer = NULL;
88234+
}
88235+
#endif /* ifdef WOLF_CRYPTO_CB_RSA_PAD */
8816588236
#endif /* !NO_RSA */
8816688237
#ifdef HAVE_ECC
8816788238
if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) {

wolfcrypt/src/cryptocb.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,62 @@ int wc_CryptoCb_Rsa(const byte* in, word32 inLen, byte* out,
418418
return wc_CryptoCb_TranslateErrorCode(ret);
419419
}
420420

421+
#ifdef WOLF_CRYPTO_CB_RSA_PAD
422+
int wc_CryptoCb_RsaPad(const byte* in, word32 inLen, byte* out,
423+
word32* outLen, int type, RsaKey* key, WC_RNG* rng,
424+
RsaPadding *padding)
425+
{
426+
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
427+
CryptoCb* dev;
428+
int pk_type;
429+
430+
if (key == NULL)
431+
return ret;
432+
433+
/* locate registered callback */
434+
dev = wc_CryptoCb_FindDevice(key->devId, WC_ALGO_TYPE_PK);
435+
436+
if (padding) {
437+
switch(padding->pad_type) {
438+
#ifndef NO_PKCS11_RSA_PKCS
439+
case WC_RSA_PKCSV15_PAD:
440+
pk_type = WC_PK_TYPE_RSA_PKCS;
441+
break;
442+
case WC_RSA_PSS_PAD:
443+
pk_type = WC_PK_TYPE_RSA_PSS;
444+
break;
445+
case WC_RSA_OAEP_PAD:
446+
pk_type = WC_PK_TYPE_RSA_OAEP;
447+
break;
448+
#endif /* NO_PKCS11_RSA_PKCS */
449+
default:
450+
pk_type = WC_PK_TYPE_RSA;
451+
}
452+
} else {
453+
pk_type = WC_PK_TYPE_RSA;
454+
}
455+
456+
if (dev && dev->cb) {
457+
wc_CryptoInfo cryptoInfo;
458+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
459+
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
460+
cryptoInfo.pk.type = pk_type;
461+
cryptoInfo.pk.rsa.in = in;
462+
cryptoInfo.pk.rsa.inLen = inLen;
463+
cryptoInfo.pk.rsa.out = out;
464+
cryptoInfo.pk.rsa.outLen = outLen;
465+
cryptoInfo.pk.rsa.type = type;
466+
cryptoInfo.pk.rsa.key = key;
467+
cryptoInfo.pk.rsa.rng = rng;
468+
cryptoInfo.pk.rsa.padding = padding;
469+
470+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
471+
}
472+
473+
return wc_CryptoCb_TranslateErrorCode(ret);
474+
}
475+
#endif
476+
421477
#ifdef WOLFSSL_KEY_GEN
422478
int wc_CryptoCb_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
423479
{

wolfcrypt/src/rsa.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,6 +3127,9 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
31273127
int ret = 0;
31283128
(void)rng;
31293129
(void)checkSmallCt;
3130+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
3131+
RsaPadding padding;
3132+
#endif
31303133

31313134
if (key == NULL || in == NULL || inLen == 0 || out == NULL ||
31323135
outLen == NULL || *outLen == 0 || type == RSA_TYPE_UNKNOWN) {
@@ -3138,7 +3141,18 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out,
31383141
if (key->devId != INVALID_DEVID)
31393142
#endif
31403143
{
3144+
#if defined(WOLF_CRYPTO_CB_RSA_PAD)
3145+
/* If we are here, either the RSA PAD callback was already called
3146+
* and returned that it could not implement for that padding scheme,
3147+
* or this is a public verify operation. Either way indicate to the
3148+
* callback that this should be a raw RSA operation with no padding.*/
3149+
XMEMSET(&padding, 0, sizeof(RsaPadding));
3150+
padding.pad_type = WC_RSA_NO_PAD;
3151+
ret = wc_CryptoCb_RsaPad(in, inLen, out,
3152+
outLen, type, key, rng, &padding);
3153+
#else
31413154
ret = wc_CryptoCb_Rsa(in, inLen, out, outLen, type, key, rng);
3155+
#endif
31423156
#ifndef WOLF_CRYPTO_CB_ONLY_RSA
31433157
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
31443158
return ret;
@@ -3246,6 +3260,9 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
32463260
int ret = 0;
32473261
int sz;
32483262
int state;
3263+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
3264+
RsaPadding padding;
3265+
#endif
32493266

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

3362+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
3363+
if (key->devId != INVALID_DEVID) {
3364+
XMEMSET(&padding, 0, sizeof(RsaPadding));
3365+
padding.pad_value = pad_value;
3366+
padding.pad_type = pad_type;
3367+
padding.hash = hash;
3368+
padding.mgf = mgf;
3369+
padding.label = label;
3370+
padding.labelSz = labelSz;
3371+
padding.saltLen = saltLen;
3372+
ret = wc_CryptoCb_RsaPad(in, inLen, out, &outLen, rsa_type, key, rng,
3373+
&padding);
3374+
3375+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
3376+
if (ret < 0) {
3377+
break;
3378+
}
3379+
3380+
ret = outLen;
3381+
break;
3382+
}
3383+
}
3384+
#endif
33453385
key->state = RSA_STATE_ENCRYPT_PAD;
33463386
ret = wc_RsaPad_ex(in, inLen, out, (word32)sz, pad_value, rng, pad_type,
33473387
hash, mgf, label, labelSz, saltLen,
@@ -3421,6 +3461,9 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out,
34213461
{
34223462
int ret = WC_NO_ERR_TRACE(RSA_WRONG_TYPE_E);
34233463
byte* pad = NULL;
3464+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
3465+
RsaPadding padding;
3466+
#endif
34243467

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

35333576
case RSA_STATE_DECRYPT_EXPTMOD:
3577+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD)
3578+
if ((key->devId != INVALID_DEVID) && (rsa_type != RSA_PUBLIC_DECRYPT)) {
3579+
/* Everything except verify goes to crypto cb if
3580+
* WOLF_CRYPTO_CB_RSA_PAD defined */
3581+
XMEMSET(&padding, 0, sizeof(RsaPadding));
3582+
padding.pad_value = pad_value;
3583+
padding.pad_type = pad_type;
3584+
padding.hash = hash;
3585+
padding.mgf = mgf;
3586+
padding.label = label;
3587+
padding.labelSz = labelSz;
3588+
padding.saltLen = saltLen;
3589+
ret = wc_CryptoCb_RsaPad(in, inLen, out,
3590+
&outLen, rsa_type, key, rng, &padding);
3591+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
3592+
break;
3593+
}
3594+
}
3595+
#endif
35343596
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE) && \
35353597
!defined(WOLFSSL_NO_MALLOC)
35363598
ret = wc_RsaFunction_ex(key->data, inLen, key->data, &key->dataLen,

0 commit comments

Comments
 (0)