RSA OAEP padding

pull/246/head
Jacob Barthelmeh 2016-01-05 10:56:15 -07:00
parent 3725133592
commit d815affe83
4 changed files with 656 additions and 3 deletions

View File

@ -1262,6 +1262,41 @@ void bench_rsa(void)
printf("RSA %d decryption took %6.3f milliseconds, avg over %d" printf("RSA %d decryption took %6.3f milliseconds, avg over %d"
" iterations\n", rsaKeySz, milliEach, ntimes); " iterations\n", rsaKeySz, milliEach, ntimes);
#if !defined(HAVE_FAST_RSA) && !defined(NO_SHA256) && !defined(HAVE_FIPS)
start = current_time(1);
for (i = 0; i < ntimes; i++)
ret = wc_RsaPublicEncrypt_ex(message,len,enc,sizeof(enc), &rsaKey, &rng,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0);
total = current_time(0) - start;
each = total / ntimes; /* per second */
milliEach = each * 1000; /* milliseconds */
printf("RSA-OAEP %d encryption %6.3f milliseconds, avg over %d"
" iterations\n", rsaKeySz, milliEach, ntimes);
if (ret < 0) {
printf("Rsa Public OAEP Encrypt failed\n");
return;
}
start = current_time(1);
for (i = 0; i < ntimes; i++) {
byte out[256]; /* for up to 2048 bit */
wc_RsaPrivateDecrypt_ex(enc, (word32)ret, out, sizeof(out), &rsaKey,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0);
}
total = current_time(0) - start;
each = total / ntimes; /* per second */
milliEach = each * 1000; /* milliseconds */
printf("RSA-OAEP %d decryption %6.3f milliseconds, avg over %d"
" iterations\n", rsaKeySz, milliEach, ntimes);
#endif /* !HAVE_FAST_RSA && !NO_SHA256 && !HAVE_FIPS */
wc_FreeRsaKey(&rsaKey); wc_FreeRsaKey(&rsaKey);
#ifdef HAVE_CAVIUM #ifdef HAVE_CAVIUM
wc_RsaFreeCavium(&rsaKey); wc_RsaFreeCavium(&rsaKey);

View File

@ -218,6 +218,199 @@ int wc_FreeRsaKey(RsaKey* key)
return 0; return 0;
} }
/* Uses MGF1 standard as a mask generation function
hType: hash type used
seed: seed to use for generating mask
seedSz: size of seed buffer
out: mask output after generation
outSz: size of output buffer
*/
static int wc_MGF1(int hType, byte* seed, word32 seedSz,
byte* out, word32 outSz)
{
byte tmp[1024]; /* needs to be large enough for seed size plus counter(4) */
int hLen;
int ret;
word32 counter;
word32 idx;
if ((sizeof(tmp) - 4) < seedSz) {
WOLFSSL_MSG("seedSz to wc_MGF1 larger than preset array size");
return BAD_FUNC_ARG;
}
hLen = wc_HashGetDigestSize(hType);
counter = 0;
idx = 0;
do {
int i = 0;
XMEMCPY(tmp, seed, seedSz);
/* counter to byte array appended to tmp */
tmp[seedSz] = (counter >> 24) & 0xFF;
tmp[seedSz + 1] = (counter >> 16) & 0xFF;
tmp[seedSz + 2] = (counter >> 8) & 0xFF;
tmp[seedSz + 3] = (counter) & 0xFF;
/* hash and append to existing output */
if ((ret = wc_Hash(hType, tmp, (seedSz + 4), tmp, sizeof(tmp))) != 0) {
return ret;
}
for (i = 0; i < hLen && idx < outSz; i++) {
out[idx++] = tmp[i];
}
counter++;
}
while (idx < outSz);
return 0;
}
/* helper function to direct which mask generation function is used
switeched on type input
*/
static int wc_MGF(int type, byte* seed, word32 seedSz,
byte* out, word32 outSz)
{
int ret;
switch(type) {
#ifndef NO_SHA
case WC_MGF1SHA1:
ret = wc_MGF1(WC_HASH_TYPE_SHA, seed, seedSz, out, outSz);
break;
#endif
#ifndef NO_SHA256
case WC_MGF1SHA256:
ret = wc_MGF1(WC_HASH_TYPE_SHA256, seed, seedSz, out, outSz);
break;
#endif
#ifdef WOLFSSL_SHA512
#ifdef WOLFSSL_SHA384
case WC_MGF1SHA384:
ret = wc_MGF1(WC_HASH_TYPE_SHA384, seed, seedSz, out, outSz);
break;
#endif
case WC_MGF1SHA512:
ret = wc_MGF1(WC_HASH_TYPE_SHA512, seed, seedSz, out, outSz);
break;
#endif
default:
WOLFSSL_MSG("Unknown MGF function: check build options");
ret = BAD_FUNC_ARG;
}
/* in case of default avoid unused warrning */
(void)seed;
(void)seedSz;
(void)out;
(void)outSz;
return ret;
}
static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
word32 pkcsBlockLen, byte padValue, WC_RNG* rng,
int hType, int mgf, byte* optLabel, word32 labelLen)
{
int ret;
int hLen;
int psLen;
int i;
word32 idx;
byte* dbMask;
byte lHash[128]; /* must be large enough to contain largest hash */
byte seed[128]; /* seed needs to be as large as hash digest */
/* can use with no lable but catch if no lable provided while having
length > 0 */
if (optLabel == NULL && labelLen > 0) {
return BUFFER_E;
}
/* limit of label is the same as limit of hash function which is massive */
hLen = wc_HashGetDigestSize(hType);
if (hLen < 0) {
return hLen;
}
if ((ret = wc_Hash(hType, optLabel, labelLen,
lHash, sizeof(lHash))) != 0) {
WOLFSSL_MSG("OAEP hash type possibly not supported or lHash to small");
return ret;
}
if (inputLen > (pkcsBlockLen - 2 * hLen - 2)) {
return BAD_FUNC_ARG;
}
/* concatinate lHash || PS || 0x01 || msg */
idx = pkcsBlockLen - 1 - inputLen;
psLen = pkcsBlockLen - inputLen - 2 * hLen - 2;
if (pkcsBlockLen < inputLen) { /*make sure not writing over end of buffer */
return BUFFER_E;
}
XMEMCPY(pkcsBlock + (pkcsBlockLen - inputLen), input, inputLen);
pkcsBlock[idx--] = 0x01; /* PS and M seperator */
while (psLen > 0 && idx > 0) {
pkcsBlock[idx--] = 0x00;
psLen--;
}
idx = idx - hLen + 1;
XMEMCPY(pkcsBlock + idx, lHash, hLen);
/* generate random seed */
if ((ret = wc_RNG_GenerateBlock(rng, seed, hLen)) != 0) {
return ret;
}
/* create maskedDB from dbMask */
dbMask = (byte*)XMALLOC(pkcsBlockLen - hLen - 1, NULL, DYNAMIC_TYPE_RSA);
ret = wc_MGF(mgf, seed, hLen, dbMask, pkcsBlockLen - hLen - 1);
if (ret != 0) {
XFREE(dbMask, NULL, DYNAMIC_TYPE_RSA);
return ret;
}
i = 0;
idx = hLen + 1;
while (idx < pkcsBlockLen && (word32)i < (pkcsBlockLen - hLen -1)) {
pkcsBlock[idx] = dbMask[i++] ^ pkcsBlock[idx];
idx++;
}
XFREE(dbMask, NULL, DYNAMIC_TYPE_RSA);
/* create maskedSeed from seedMask */
idx = 0;
pkcsBlock[idx++] = 0x00;
/* create seedMask inline */
if ((ret = wc_MGF(mgf, pkcsBlock + hLen + 1, pkcsBlockLen - hLen - 1,
pkcsBlock + 1, hLen)) != 0) {
return ret;
}
/* xor created seedMask with seed to make maskedSeed */
i = 0;
while (idx < (word32)(hLen + 1) && i < hLen) {
pkcsBlock[idx] = pkcsBlock[idx] ^ seed[i++];
idx++;
}
(void)padValue;
return 0;
}
static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
word32 pkcsBlockLen, byte padValue, WC_RNG* rng) word32 pkcsBlockLen, byte padValue, WC_RNG* rng)
{ {
@ -251,6 +444,112 @@ static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
} }
/* helper function to direct which padding is used */
static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
word32 pkcsBlockLen, byte padValue, WC_RNG* rng, int padType,
int hType, int mgf, byte* optLabel, word32 labelLen)
{
int ret;
switch (padType)
{
case WC_RSA_PKCSV15_PAD:
WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding");
ret = wc_RsaPad(input, inputLen, pkcsBlock, pkcsBlockLen,
padValue, rng);
break;
case WC_RSA_OAEP_PAD:
WOLFSSL_MSG("wolfSSL Using RSA OAEP padding");
ret = wc_RsaPad_OAEP(input, inputLen, pkcsBlock, pkcsBlockLen,
padValue, rng, hType, mgf, optLabel, labelLen);
break;
default:
WOLFSSL_MSG("Unknown RSA Pad Type");
ret = RSA_PAD_E;
}
/* silence warrning if not used with padding scheme */
(void)padType;
(void)hType;
(void)mgf;
(void)optLabel;
(void)labelLen;
return ret;
}
/* UnPad plaintext, set start to *output, return length of plaintext,
* < 0 on error */
static int wc_RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
byte **output, int hType, int mgf, byte* optLabel, word32 labelLen)
{
int hLen;
int ret;
byte h[128]; /* max digest size */
byte tmp[1024];
word32 idx;
XMEMSET(tmp, 0, sizeof(tmp));
hLen = wc_HashGetDigestSize(hType);
if ((hLen < 0) || (pkcsBlockLen < (2 * (word32)hLen + 2))) {
return BAD_FUNC_ARG;
}
/* find seedMask value */
if ((ret = wc_MGF(mgf, (byte*)(pkcsBlock + (hLen + 1)),
pkcsBlockLen - hLen - 1, tmp, hLen)) != 0) {
return ret;
}
/* xor seedMask value with maskedSeed to get seed value */
for (idx = 0; idx < (word32)hLen; idx++) {
tmp[idx] = tmp[idx] ^ pkcsBlock[1 + idx];
}
/* get dbMask value */
if ((ret = wc_MGF(mgf, tmp, hLen, tmp + hLen,
pkcsBlockLen - hLen - 1)) != 0) {
return ret;
}
/* get DB vaule by doing maskedDB xor dbMask */
for (idx = 0; idx < (pkcsBlockLen - hLen - 1); idx++) {
pkcsBlock[hLen + 1 + idx] = pkcsBlock[hLen + 1 + idx] ^ tmp[idx + hLen];
}
/* advance idx to index of PS and msg seperator */
idx = hLen + 2 + hLen;
while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;}
/* create hash of label for comparision with hash sent */
if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) {
return ret;
}
/* say no to chosen ciphertext attack.
Comparision of lHash, Y, and seperator value needs to all happen in
constant time.
Attackers should not be able to get error condition from the timing of
these checks.
*/
ret = 0;
ret |= ConstantCompare(pkcsBlock + hLen + 1, h, hLen);
ret += pkcsBlock[idx++] ^ 0x01; /* seperator value is 0x01 */
ret += pkcsBlock[0] ^ 0x00; /* Y, the first value, should be 0 */
if (ret != 0) {
return BAD_PADDING_E;
}
/* adjust pointer to correct location in array and return size of M */
*output = (byte*)(pkcsBlock + idx);
return pkcsBlockLen - idx;
}
/* UnPad plaintext, set start to *output, return length of plaintext, /* UnPad plaintext, set start to *output, return length of plaintext,
* < 0 on error */ * < 0 on error */
static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
@ -294,6 +593,41 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
} }
/* helper function to direct unpadding */
static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
byte padValue, int padType, int hType, int mgf,
byte* optLabel, word32 labelLen)
{
int ret;
switch (padType)
{
case WC_RSA_PKCSV15_PAD:
WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding");
ret = RsaUnPad(pkcsBlock, pkcsBlockLen, out, padValue);
break;
case WC_RSA_OAEP_PAD:
WOLFSSL_MSG("wolfSSL Using RSA OAEP padding");
ret = wc_RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out,
hType, mgf, optLabel, labelLen);
break;
default:
WOLFSSL_MSG("Unknown RSA Pad Type");
ret = RSA_PAD_E;
}
/* silence warrning if not used with padding scheme */
(void)padType;
(void)hType;
(void)mgf;
(void)optLabel;
(void)labelLen;
return ret;
}
static int wc_RsaFunction(const byte* in, word32 inLen, byte* out, static int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
word32* outLen, int type, RsaKey* key) word32* outLen, int type, RsaKey* key)
{ {
@ -419,6 +753,49 @@ int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
} }
/* Gives the option of chossing padding type
in : input to be encrypted
inLen: length of input buffer
out: encrypted output
outLen: length of encrypted output buffer
key : wolfSSL initialised RSA key struct
rng : wolfSSL initialized random number struct
type : type of padding to use ie WC_RSA_OAEP_PAD
hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
mgf : type of mask generation function to use
label : optional label
labelSz : size of optional label buffer */
int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key, WC_RNG* rng,
int type, int hash, int mgf, byte* label, word32 labelSz)
{
int sz, ret;
#ifdef HAVE_CAVIUM
if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key);
#endif
sz = mp_unsigned_bin_size(&key->n);
if (sz > (int)outLen)
return RSA_BUFFER_E;
if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
return RSA_BUFFER_E;
ret = wc_RsaPad_ex(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng,
type, hash, mgf, label, labelSz);
if (ret != 0)
return ret;
if ((ret = wc_RsaFunction(out, sz, out, &outLen,
RSA_PUBLIC_ENCRYPT, key)) < 0)
sz = ret;
return sz;
}
int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key) int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
{ {
int ret; int ret;
@ -441,6 +818,40 @@ int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
} }
/* Gives the option of chossing padding type
in : input to be decrypted
inLen: length of input buffer
out: pointer to place of decrypted message
key : wolfSSL initialised RSA key struct
type : type of padding to use ie WC_RSA_OAEP_PAD
hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
mgf : type of mask generation function to use
label : optional label
labelSz : size of optional label buffer */
int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out,
RsaKey* key, int type, int hash, int mgf, byte* label, word32 labelSz)
{
int ret;
#ifdef HAVE_CAVIUM
if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) {
ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key);
if (ret > 0)
*out = in;
return ret;
}
#endif
if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
< 0) {
return ret;
}
return wc_RsaUnPad_ex(in, inLen, out, RSA_BLOCK_TYPE_2, type, hash, mgf,
label, labelSz);
}
int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen, int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key) RsaKey* key)
{ {
@ -476,6 +887,53 @@ int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
} }
/* Gives the option of chossing padding type
in : input to be decrypted
inLen: length of input buffer
out: decrypted message
outLen: length of decrypted message in bytes
key : wolfSSL initialised RSA key struct
type : type of padding to use ie WC_RSA_OAEP_PAD
hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
mgf : type of mask generation function to use
label : optional label
labelSz : size of optional label buffer */
int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, word32 outLen,
RsaKey* key, int type, int hash, int mgf, byte* label, word32 labelSz)
{
int plainLen;
byte* tmp;
byte* pad = 0;
#ifdef HAVE_CAVIUM
if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key);
#endif
tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
if (tmp == NULL) {
return MEMORY_E;
}
XMEMCPY(tmp, in, inLen);
if ( (plainLen = wc_RsaPrivateDecryptInline_ex(tmp, inLen, &pad, key,
type, hash, mgf, label, labelSz) ) < 0) {
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
return plainLen;
}
if (plainLen > (int)outLen)
plainLen = BAD_FUNC_ARG;
else
XMEMCPY(out, pad, plainLen);
ForceZero(tmp, inLen);
XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
return plainLen;
}
/* for Rsa Verify */ /* for Rsa Verify */
int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
{ {

View File

@ -3886,7 +3886,6 @@ int certext_test(void)
} }
#endif /* WOLFSSL_CERT_EXT && WOLFSSL_TEST_CERT */ #endif /* WOLFSSL_CERT_EXT && WOLFSSL_TEST_CERT */
int rsa_test(void) int rsa_test(void)
{ {
byte* tmp; byte* tmp;
@ -3981,6 +3980,140 @@ int rsa_test(void)
free(tmp); free(tmp);
return -48; return -48;
} }
/* OAEP padding testing */
#if !defined(HAVE_FAST_RSA) && !defined(HAVE_FIPS)
#ifndef NO_SHA
XMEMSET(plain, 0, sizeof(plain));
ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA, WC_MGF1SHA1, NULL, 0);
if (ret < 0) {
free(tmp);
return -143;
}
ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA, WC_MGF1SHA1, NULL, 0);
if (ret < 0) {
free(tmp);
return -144;
}
if (XMEMCMP(plain, in, inLen)) {
free(tmp);
return -145;
}
#endif /* NO_SHA */
#ifndef NO_SHA256
XMEMSET(plain, 0, sizeof(plain));
ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0);
if (ret < 0) {
free(tmp);
return -243;
}
ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0);
if (ret < 0) {
free(tmp);
return -244;
}
if (XMEMCMP(plain, in, inLen)) {
free(tmp);
return -245;
}
/* check fails if not using the same optional label */
XMEMSET(plain, 0, sizeof(plain));
ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, NULL, 0);
if (ret < 0) {
free(tmp);
return -246;
}
ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in));
if (ret > 0) { /* in this case decrypt should fail */
free(tmp);
return -247;
}
/* check using optional label with encrypt/decrypt */
XMEMSET(plain, 0, sizeof(plain));
ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in));
if (ret < 0) {
free(tmp);
return -248;
}
ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in));
if (ret < 0) {
free(tmp);
return -249;
}
if (XMEMCMP(plain, in, inLen)) {
free(tmp);
return -250;
}
#ifndef NO_SHA
/* check fail using missmatch hash algorithms */
XMEMSET(plain, 0, sizeof(plain));
ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA, WC_MGF1SHA1, in, sizeof(in));
if (ret < 0) {
free(tmp);
return -251;
}
ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256, WC_MGF1SHA256, in, sizeof(in));
if (ret > 0) { /* should fail */
free(tmp);
return -252;
}
#endif /* NO_SHA*/
#endif /* NO_SHA256 */
#ifdef WOLFSSL_SHA512
XMEMSET(plain, 0, sizeof(plain));
ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA512, WC_MGF1SHA512, NULL, 0);
if (ret < 0) {
free(tmp);
return -343;
}
ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key,
WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA512, WC_MGF1SHA512, NULL, 0);
if (ret < 0) {
free(tmp);
return -344;
}
if (XMEMCMP(plain, in, inLen)) {
free(tmp);
return -345;
}
#endif /* NO_SHA */
/* check using pkcsv15 padding with _ex API */
XMEMSET(plain, 0, sizeof(plain));
ret = wc_RsaPublicEncrypt_ex(in, inLen, out, sizeof(out), &key, &rng,
WC_RSA_PKCSV15_PAD, 0, 0, NULL, 0);
if (ret < 0) {
free(tmp);
return -443;
}
ret = wc_RsaPrivateDecrypt_ex(out, ret, plain, sizeof(plain), &key,
WC_RSA_PKCSV15_PAD, 0, 0, NULL, 0);
if (ret < 0) {
free(tmp);
return -444;
}
if (XMEMCMP(plain, in, inLen)) {
free(tmp);
return -445;
}
#endif /* !HAVE_FAST_RSA && !HAVE_FIPS */
#if defined(WOLFSSL_MDK_ARM) #if defined(WOLFSSL_MDK_ARM)
#define sizeof(s) strlen((char *)(s)) #define sizeof(s) strlen((char *)(s))
#endif #endif

View File

@ -42,6 +42,9 @@
#include <wolfssl/wolfcrypt/random.h> #include <wolfssl/wolfcrypt/random.h>
#endif /* HAVE_FIPS */ #endif /* HAVE_FIPS */
/* header file needed for OAEP padding */
#include <wolfssl/wolfcrypt/hash.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -105,6 +108,30 @@ WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
#ifdef WOLFSSL_KEY_GEN #ifdef WOLFSSL_KEY_GEN
WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen); WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen);
#endif #endif
/*
choice of padding added after fips, so not avialable when using fips RSA
*/
/* Mask Generation Function Identifiers */
#define WC_MGF1SHA1 26
#define WC_MGF1SHA256 1
#define WC_MGF1SHA384 2
#define WC_MGF1SHA512 3
/* Padding types */
#define WC_RSA_PKCSV15_PAD 0
#define WC_RSA_OAEP_PAD 1
WOLFSSL_API int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,
word32 outLen, RsaKey* key, WC_RNG* rng,
int type, int hash, int mgf, byte* label, word32 lableSz);
WOLFSSL_API int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen,
byte* out, word32 outLen, RsaKey* key,
int type, int hash, int mgf, byte* label, word32 lableSz);
WOLFSSL_API int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen,
byte** out, RsaKey* key,
int type, int hash, int mgf, byte* label, word32 lableSz);
#endif /* HAVE_FIPS*/ #endif /* HAVE_FIPS*/
WOLFSSL_API int wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*, WOLFSSL_API int wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*,
word32*); word32*);