Merge pull request #2547 from SparkiDev/rsa_pss_salt_len

Compile options for larger salt lengths in RSA-PSS
This commit is contained in:
toddouska
2019-11-06 13:03:15 -08:00
committed by GitHub
6 changed files with 281 additions and 75 deletions

View File

@@ -22310,14 +22310,14 @@ static void test_wolfSSL_ERR_print_errors(void)
AssertNotNull(bio = BIO_new(BIO_s_mem())); AssertNotNull(bio = BIO_new(BIO_s_mem()));
ERR_clear_error(); /* clear out any error nodes */ ERR_clear_error(); /* clear out any error nodes */
ERR_put_error(0,SYS_F_ACCEPT, -173, "ssl.c", 0); ERR_put_error(0,SYS_F_ACCEPT, -173, "ssl.c", 0);
ERR_put_error(0,SYS_F_BIND, -273, "asn.c", 100); ERR_put_error(0,SYS_F_BIND, -283, "asn.c", 100);
ERR_print_errors(bio); ERR_print_errors(bio);
AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 56); AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 56);
AssertIntEQ(XSTRNCMP("error:173:wolfSSL library:Bad function argument:ssl.c:0", AssertIntEQ(XSTRNCMP("error:173:wolfSSL library:Bad function argument:ssl.c:0",
buf, 55), 0); buf, 55), 0);
AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 57); AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 57);
AssertIntEQ(XSTRNCMP("error:273:wolfSSL library:unknown error number:asn.c:100", AssertIntEQ(XSTRNCMP("error:283:wolfSSL library:unknown error number:asn.c:100",
buf, 56), 0); buf, 56), 0);
AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 0); AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 0);
AssertIntEQ(ERR_get_error_line(NULL, NULL), 0); AssertIntEQ(ERR_get_error_line(NULL, NULL), 0);

View File

@@ -509,6 +509,9 @@ const char* wc_GetErrorString(int error)
case PKCS7_SIGNEEDS_CHECK: case PKCS7_SIGNEEDS_CHECK:
return "Signature found but no certificate to verify"; return "Signature found but no certificate to verify";
case PSS_SALTLEN_RECOVER_E:
return "PSS - Salt length unable to be recovered";
default: default:
return "unknown error number"; return "unknown error number";

View File

@@ -1087,56 +1087,133 @@ static int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock,
word32 pkcsBlockLen, WC_RNG* rng, enum wc_HashType hType, int mgf, word32 pkcsBlockLen, WC_RNG* rng, enum wc_HashType hType, int mgf,
int saltLen, int bits, void* heap) int saltLen, int bits, void* heap)
{ {
int ret; int ret = 0;
int hLen, i; int hLen, i, o, maskLen, hiBits;
byte* s;
byte* m; byte* m;
byte* h; byte* s;
#if defined(WOLFSSL_PSS_LONG_SALT) || defined(WOLFSSL_PSS_SALT_LEN_DISCOVER)
#if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY)
byte salt[RSA_MAX_SIZE/8 + RSA_PSS_PAD_SZ];
#else
byte* salt = NULL;
#endif
#else
byte salt[WC_MAX_DIGEST_SIZE]; byte salt[WC_MAX_DIGEST_SIZE];
#endif
#if defined(WOLFSSL_PSS_LONG_SALT) || defined(WOLFSSL_PSS_SALT_LEN_DISCOVER)
if (pkcsBlockLen > RSA_MAX_SIZE/8) {
return MEMORY_E;
}
#endif
hLen = wc_HashGetDigestSize(hType); hLen = wc_HashGetDigestSize(hType);
if (hLen < 0) if (hLen < 0)
return hLen; return hLen;
if (saltLen == -1) { hiBits = (bits - 1) & 0x7;
if (hiBits == 0) {
*(pkcsBlock++) = 0;
pkcsBlockLen--;
}
if (saltLen == RSA_PSS_SALT_LEN_DEFAULT) {
saltLen = hLen; saltLen = hLen;
#ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA512
/* See FIPS 186-4 section 5.5 item (e). */ /* See FIPS 186-4 section 5.5 item (e). */
if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE) if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE) {
saltLen = RSA_PSS_SALT_MAX_SZ; saltLen = RSA_PSS_SALT_MAX_SZ;
}
#endif #endif
} }
else if (saltLen > hLen || saltLen < -1) #ifndef WOLFSSL_PSS_LONG_SALT
else if (saltLen > hLen) {
return PSS_SALTLEN_E; return PSS_SALTLEN_E;
if ((int)pkcsBlockLen - hLen < saltLen + 2) }
#endif
#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
else if (saltLen < RSA_PSS_SALT_LEN_DEFAULT) {
return PSS_SALTLEN_E; return PSS_SALTLEN_E;
}
#else
else if (saltLen == RSA_PSS_SALT_LEN_DISCOVER) {
saltLen = (int)pkcsBlockLen - hLen - 2;
if (saltLen < 0) {
return PSS_SALTLEN_E;
}
}
else if (saltLen < RSA_PSS_SALT_LEN_DISCOVER) {
return PSS_SALTLEN_E;
}
#endif
if ((int)pkcsBlockLen - hLen < saltLen + 2) {
return PSS_SALTLEN_E;
}
maskLen = pkcsBlockLen - 1 - hLen;
#if defined(WOLFSSL_PSS_LONG_SALT) || defined(WOLFSSL_PSS_SALT_LEN_DISCOVER)
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
salt = (byte*)XMALLOC(RSA_PSS_PAD_SZ + inputLen + saltLen, heap,
DYNAMIC_TYPE_RSA_BUFFER);
if (salt == NULL) {
return MEMORY_E;
}
#endif
s = m = salt;
XMEMSET(m, 0, RSA_PSS_PAD_SZ);
m += RSA_PSS_PAD_SZ;
XMEMCPY(m, input, inputLen);
m += inputLen;
o = (int)(m - s);
if (saltLen > 0) {
ret = wc_RNG_GenerateBlock(rng, m, saltLen);
if (ret == 0) {
m += saltLen;
}
}
#else
s = m = pkcsBlock; s = m = pkcsBlock;
XMEMSET(m, 0, RSA_PSS_PAD_SZ); XMEMSET(m, 0, RSA_PSS_PAD_SZ);
m += RSA_PSS_PAD_SZ; m += RSA_PSS_PAD_SZ;
XMEMCPY(m, input, inputLen); XMEMCPY(m, input, inputLen);
m += inputLen; m += inputLen;
if ((ret = wc_RNG_GenerateBlock(rng, salt, saltLen)) != 0) o = 0;
return ret; if (saltLen > 0) {
ret = wc_RNG_GenerateBlock(rng, salt, saltLen);
if (ret == 0) {
XMEMCPY(m, salt, saltLen); XMEMCPY(m, salt, saltLen);
m += saltLen; m += saltLen;
}
h = pkcsBlock + pkcsBlockLen - 1 - hLen; }
if ((ret = wc_Hash(hType, s, (word32)(m - s), h, hLen)) != 0) #endif
return ret; if (ret == 0) {
/* Put Hash at end of pkcsBlock - 1 */
ret = wc_Hash(hType, s, (word32)(m - s), pkcsBlock + maskLen, hLen);
}
if (ret == 0) {
pkcsBlock[pkcsBlockLen - 1] = RSA_PSS_PAD_TERM; pkcsBlock[pkcsBlockLen - 1] = RSA_PSS_PAD_TERM;
ret = RsaMGF(mgf, h, hLen, pkcsBlock, pkcsBlockLen - hLen - 1, heap); ret = RsaMGF(mgf, pkcsBlock + maskLen, hLen, pkcsBlock, maskLen, heap);
if (ret != 0) }
return ret; if (ret == 0) {
pkcsBlock[0] &= (1 << ((bits - 1) & 0x7)) - 1; pkcsBlock[0] &= (1 << hiBits) - 1;
m = pkcsBlock + pkcsBlockLen - 1 - saltLen - hLen - 1; m = pkcsBlock + maskLen - saltLen - 1;
*(m++) ^= 0x01; *(m++) ^= 0x01;
for (i = 0; i < saltLen; i++) for (i = 0; i < saltLen; i++) {
m[i] ^= salt[i]; m[i] ^= salt[o + i];
}
}
return 0; #if defined(WOLFSSL_PSS_LONG_SALT) || defined(WOLFSSL_PSS_SALT_LEN_DISCOVER)
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
if (salt != NULL) {
XFREE(salt, heap, DYNAMIC_TYPE_RSA_BUFFER);
}
#endif
#endif
return ret;
} }
#endif /* WC_RSA_PSS */ #endif /* WC_RSA_PSS */
@@ -1379,7 +1456,7 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
{ {
int ret; int ret;
byte* tmp; byte* tmp;
int hLen, i; int hLen, i, maskLen;
#if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY) #if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY)
byte tmp_buf[RSA_MAX_SIZE/8]; byte tmp_buf[RSA_MAX_SIZE/8];
tmp = tmp_buf; tmp = tmp_buf;
@@ -1392,8 +1469,21 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
hLen = wc_HashGetDigestSize(hType); hLen = wc_HashGetDigestSize(hType);
if (hLen < 0) if (hLen < 0)
return hLen; return hLen;
bits = (bits - 1) & 0x7;
if ((pkcsBlock[0] & (0xff << bits)) != 0) {
return BAD_PADDING_E;
}
if (bits == 0) {
pkcsBlock++;
pkcsBlockLen--;
}
maskLen = (int)pkcsBlockLen - 1 - hLen;
if (maskLen < 0) {
WOLFSSL_MSG("RsaUnPad_PSS: Hash too large");
return WC_KEY_SIZE_E;
}
if (saltLen == -1) { if (saltLen == RSA_PSS_SALT_LEN_DEFAULT) {
saltLen = hLen; saltLen = hLen;
#ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA512
/* See FIPS 186-4 section 5.5 item (e). */ /* See FIPS 186-4 section 5.5 item (e). */
@@ -1401,10 +1491,23 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
saltLen = RSA_PSS_SALT_MAX_SZ; saltLen = RSA_PSS_SALT_MAX_SZ;
#endif #endif
} }
else if (saltLen > hLen || saltLen < -1) #ifndef WOLFSSL_PSS_LONG_SALT
else if (saltLen > hLen)
return PSS_SALTLEN_E; return PSS_SALTLEN_E;
if ((int)pkcsBlockLen - hLen < saltLen + 2) #endif
#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
else if (saltLen < RSA_PSS_SALT_LEN_DEFAULT)
return PSS_SALTLEN_E; return PSS_SALTLEN_E;
if (maskLen < saltLen + 1) {
return PSS_SALTLEN_E;
}
#else
else if (saltLen < RSA_PSS_SALT_LEN_DISCOVER)
return PSS_SALTLEN_E;
if (saltLen != RSA_PSS_SALT_LEN_DISCOVER && maskLen < saltLen + 1) {
return WC_KEY_SIZE_E;
}
#endif
if (pkcsBlock[pkcsBlockLen - 1] != RSA_PSS_PAD_TERM) { if (pkcsBlock[pkcsBlockLen - 1] != RSA_PSS_PAD_TERM) {
WOLFSSL_MSG("RsaUnPad_PSS: Padding Term Error"); WOLFSSL_MSG("RsaUnPad_PSS: Padding Term Error");
@@ -1412,38 +1515,58 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
} }
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY) #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_RSA_BUFFER); tmp = (byte*)XMALLOC(maskLen, heap, DYNAMIC_TYPE_RSA_BUFFER);
if (tmp == NULL) if (tmp == NULL) {
return MEMORY_E; return MEMORY_E;
}
#endif #endif
if ((ret = RsaMGF(mgf, pkcsBlock + pkcsBlockLen - 1 - hLen, hLen, if ((ret = RsaMGF(mgf, pkcsBlock + maskLen, hLen, tmp, maskLen,
tmp, pkcsBlockLen - 1 - hLen, heap)) != 0) { heap)) != 0) {
XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
return ret; return ret;
} }
tmp[0] &= (1 << ((bits - 1) & 0x7)) - 1; tmp[0] &= (1 << bits) - 1;
for (i = 0; i < (int)(pkcsBlockLen - 1 - saltLen - hLen - 1); i++) { pkcsBlock[0] &= (1 << bits) - 1;
#ifdef WOLFSSL_PSS_SALT_LEN_DISCOVER
if (saltLen == RSA_PSS_SALT_LEN_DISCOVER) {
for (i = 0; i < maskLen - 1; i++) {
if (tmp[i] != pkcsBlock[i]) {
break;
}
}
if (tmp[i] != (pkcsBlock[i] ^ 0x01)) {
XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
WOLFSSL_MSG("RsaUnPad_PSS: Padding Error Match");
return PSS_SALTLEN_RECOVER_E;
}
saltLen = maskLen - (i + 1);
}
else
#endif
{
for (i = 0; i < maskLen - 1 - saltLen; i++) {
if (tmp[i] != pkcsBlock[i]) { if (tmp[i] != pkcsBlock[i]) {
XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
WOLFSSL_MSG("RsaUnPad_PSS: Padding Error Match"); WOLFSSL_MSG("RsaUnPad_PSS: Padding Error Match");
return BAD_PADDING_E; return PSS_SALTLEN_E;
} }
} }
if (tmp[i] != (pkcsBlock[i] ^ 0x01)) { if (tmp[i] != (pkcsBlock[i] ^ 0x01)) {
XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
WOLFSSL_MSG("RsaUnPad_PSS: Padding Error End"); WOLFSSL_MSG("RsaUnPad_PSS: Padding Error End");
return BAD_PADDING_E; return PSS_SALTLEN_E;
} }
for (i++; i < (int)(pkcsBlockLen - 1 - hLen); i++) }
for (i++; i < maskLen; i++)
pkcsBlock[i] ^= tmp[i]; pkcsBlock[i] ^= tmp[i];
#if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY) #if !defined(WOLFSSL_NO_MALLOC) || defined(WOLFSSL_STATIC_MEMORY)
XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
#endif #endif
*output = pkcsBlock + pkcsBlockLen - (hLen + saltLen + 1); *output = pkcsBlock + maskLen - saltLen;
return saltLen + hLen; return saltLen + hLen;
} }
#endif #endif
@@ -1550,7 +1673,8 @@ static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
/* In the case of no padding being used check that input is exactly /* In the case of no padding being used check that input is exactly
* the RSA key length */ * the RSA key length */
if (bits <= 0 || pkcsBlockLen != ((word32)bits/WOLFSSL_BIT_SIZE)) { if (bits <= 0 || pkcsBlockLen !=
((word32)(bits+WOLFSSL_BIT_SIZE-1)/WOLFSSL_BIT_SIZE)) {
WOLFSSL_MSG("Bad input size"); WOLFSSL_MSG("Bad input size");
ret = RSA_PAD_E; ret = RSA_PAD_E;
} }
@@ -2995,7 +3119,13 @@ int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out, int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,
enum wc_HashType hash, int mgf, RsaKey* key) enum wc_HashType hash, int mgf, RsaKey* key)
{ {
return wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf, -1, key); #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
return wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf,
RSA_PSS_SALT_LEN_DEFAULT, key);
#else
return wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf,
RSA_PSS_SALT_LEN_DISCOVER, key);
#endif
} }
/* Verify the message signed with RSA-PSS. /* Verify the message signed with RSA-PSS.
@@ -3007,8 +3137,9 @@ int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,
* hash Hash algorithm. * hash Hash algorithm.
* mgf Mask generation function. * mgf Mask generation function.
* key Public RSA key. * key Public RSA key.
* saltLen Length of salt used. -1 indicates salt length is the same as the * saltLen Length of salt used. RSA_PSS_SALT_LEN_DEFAULT (-1) indicates salt
* hash length. * length is the same as the hash length. RSA_PSS_SALT_LEN_DISCOVER
* indicates salt length is determined from the data.
* returns the length of the PSS data on success and negative indicates failure. * returns the length of the PSS data on success and negative indicates failure.
*/ */
int wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out, int wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out,
@@ -3038,7 +3169,13 @@ int wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out,
int wc_RsaPSS_Verify(byte* in, word32 inLen, byte* out, word32 outLen, int wc_RsaPSS_Verify(byte* in, word32 inLen, byte* out, word32 outLen,
enum wc_HashType hash, int mgf, RsaKey* key) enum wc_HashType hash, int mgf, RsaKey* key)
{ {
return wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash, mgf, -1, key); #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
return wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash, mgf,
RSA_PSS_SALT_LEN_DEFAULT, key);
#else
return wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash, mgf,
RSA_PSS_SALT_LEN_DISCOVER, key);
#endif
} }
/* Verify the message signed with RSA-PSS. /* Verify the message signed with RSA-PSS.
@@ -3049,8 +3186,9 @@ int wc_RsaPSS_Verify(byte* in, word32 inLen, byte* out, word32 outLen,
* hash Hash algorithm. * hash Hash algorithm.
* mgf Mask generation function. * mgf Mask generation function.
* key Public RSA key. * key Public RSA key.
* saltLen Length of salt used. -1 indicates salt length is the same as the * saltLen Length of salt used. RSA_PSS_SALT_LEN_DEFAULT (-1) indicates salt
* hash length. * length is the same as the hash length. RSA_PSS_SALT_LEN_DISCOVER
* indicates salt length is determined from the data.
* returns the length of the PSS data on success and negative indicates failure. * returns the length of the PSS data on success and negative indicates failure.
*/ */
int wc_RsaPSS_Verify_ex(byte* in, word32 inLen, byte* out, word32 outLen, int wc_RsaPSS_Verify_ex(byte* in, word32 inLen, byte* out, word32 outLen,
@@ -3092,8 +3230,9 @@ int wc_RsaPSS_CheckPadding(const byte* in, word32 inSz, byte* sig,
* sig Buffer holding PSS data. * sig Buffer holding PSS data.
* sigSz Size of PSS data. * sigSz Size of PSS data.
* hashType Hash algorithm. * hashType Hash algorithm.
* saltLen Length of salt used. -1 indicates salt length is the same as the * saltLen Length of salt used. RSA_PSS_SALT_LEN_DEFAULT (-1) indicates salt
* hash length. * length is the same as the hash length. RSA_PSS_SALT_LEN_DISCOVER
* indicates salt length is determined from the data.
* returns BAD_PADDING_E when the PSS data is invalid, BAD_FUNC_ARG when * returns BAD_PADDING_E when the PSS data is invalid, BAD_FUNC_ARG when
* NULL is passed in to in or sig or inSz is not the same as the hash * NULL is passed in to in or sig or inSz is not the same as the hash
* algorithm length and 0 on success. * algorithm length and 0 on success.
@@ -3103,32 +3242,67 @@ int wc_RsaPSS_CheckPadding_ex(const byte* in, word32 inSz, byte* sig,
int saltLen, int bits) int saltLen, int bits)
{ {
int ret = 0; int ret = 0;
#ifndef WOLFSSL_PSS_LONG_SALT
byte sigCheck[WC_MAX_DIGEST_SIZE*2 + RSA_PSS_PAD_SZ]; byte sigCheck[WC_MAX_DIGEST_SIZE*2 + RSA_PSS_PAD_SZ];
#else
byte *sigCheck = NULL;
#endif
(void)bits; (void)bits;
if (in == NULL || sig == NULL || if (in == NULL || sig == NULL ||
inSz != (word32)wc_HashGetDigestSize(hashType)) inSz != (word32)wc_HashGetDigestSize(hashType)) {
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
}
if (ret == 0) { if (ret == 0) {
if (saltLen == -1) { if (saltLen == RSA_PSS_SALT_LEN_DEFAULT) {
saltLen = inSz; saltLen = inSz;
#ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA512
/* See FIPS 186-4 section 5.5 item (e). */ /* See FIPS 186-4 section 5.5 item (e). */
if (bits == 1024 && inSz == WC_SHA512_DIGEST_SIZE) if (bits == 1024 && inSz == WC_SHA512_DIGEST_SIZE) {
saltLen = RSA_PSS_SALT_MAX_SZ; saltLen = RSA_PSS_SALT_MAX_SZ;
}
#endif #endif
} }
else if (saltLen < -1 || (word32)saltLen > inSz) #ifndef WOLFSSL_PSS_LONG_SALT
else if ((word32)saltLen > inSz) {
ret = PSS_SALTLEN_E; ret = PSS_SALTLEN_E;
} }
#endif
#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
else if (saltLen < RSA_PSS_SALT_LEN_DEFAULT) {
ret = PSS_SALTLEN_E;
}
#else
else if (saltLen == RSA_PSS_SALT_LEN_DISCOVER) {
saltLen = sigSz - inSz;
if (saltLen < 0) {
ret = PSS_SALTLEN_E;
}
}
else if (saltLen < RSA_PSS_SALT_LEN_DISCOVER) {
ret = PSS_SALTLEN_E;
}
#endif
}
/* Sig = Salt | Exp Hash */ /* Sig = Salt | Exp Hash */
if (ret == 0) { if (ret == 0) {
if (sigSz != inSz + saltLen) if (sigSz != inSz + saltLen) {
ret = BAD_PADDING_E; ret = PSS_SALTLEN_E;
} }
}
#ifdef WOLFSSL_PSS_LONG_SALT
if (ret == 0) {
sigCheck = (byte*)XMALLOC(RSA_PSS_PAD_SZ + inSz + saltLen, NULL,
DYNAMIC_TYPE_RSA_BUFFER);
if (sigCheck == NULL) {
ret = MEMORY_E;
}
}
#endif
/* Exp Hash = HASH(8 * 0x00 | Message Hash | Salt) */ /* Exp Hash = HASH(8 * 0x00 | Message Hash | Salt) */
if (ret == 0) { if (ret == 0) {
@@ -3145,6 +3319,11 @@ int wc_RsaPSS_CheckPadding_ex(const byte* in, word32 inSz, byte* sig,
} }
} }
#ifdef WOLFSSL_PSS_LONG_SALT
if (sigCheck != NULL) {
XFREE(sigCheck, NULL, DYNAMIC_TYPE_RSA_BUFFER);
}
#endif
return ret; return ret;
} }
@@ -3269,7 +3448,8 @@ int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
int wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, int wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
enum wc_HashType hash, int mgf, RsaKey* key, WC_RNG* rng) enum wc_HashType hash, int mgf, RsaKey* key, WC_RNG* rng)
{ {
return wc_RsaPSS_Sign_ex(in, inLen, out, outLen, hash, mgf, -1, key, rng); return wc_RsaPSS_Sign_ex(in, inLen, out, outLen, hash, mgf,
RSA_PSS_SALT_LEN_DEFAULT, key, rng);
} }
/* Sign the hash of a message using RSA-PSS. /* Sign the hash of a message using RSA-PSS.
@@ -3280,8 +3460,9 @@ int wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
* outLen Size of buffer to write to. * outLen Size of buffer to write to.
* hash Hash algorithm. * hash Hash algorithm.
* mgf Mask generation function. * mgf Mask generation function.
* saltLen Length of salt used. -1 indicates salt length is the same as the * saltLen Length of salt used. RSA_PSS_SALT_LEN_DEFAULT (-1) indicates salt
* hash length. * length is the same as the hash length. RSA_PSS_SALT_LEN_DISCOVER
* indicates salt length is determined from the data.
* key Public RSA key. * key Public RSA key.
* rng Random number generator. * rng Random number generator.
* returns the length of the encrypted signature on success, a negative value * returns the length of the encrypted signature on success, a negative value

View File

@@ -10526,6 +10526,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key)
#ifdef RSA_PSS_TEST_WRONG_PARAMS #ifdef RSA_PSS_TEST_WRONG_PARAMS
int k, l; int k, l;
#endif #endif
int len;
byte* plain; byte* plain;
int mgf[] = { int mgf[] = {
#ifndef NO_SHA #ifndef NO_SHA
@@ -10722,6 +10723,11 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key)
/* Test bad salt lengths in various APIs. */ /* Test bad salt lengths in various APIs. */
digestSz = wc_HashGetDigestSize(hash[0]); digestSz = wc_HashGetDigestSize(hash[0]);
outSz = RSA_TEST_BYTES; outSz = RSA_TEST_BYTES;
#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
len = -2;
#else
len = -3;
#endif
do { do {
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &key->asyncDev, ret = wc_AsyncWait(ret, &key->asyncDev,
@@ -10729,7 +10735,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key)
#endif #endif
if (ret >= 0) { if (ret >= 0) {
ret = wc_RsaPSS_Sign_ex(digest, digestSz, out, outSz, hash[0], ret = wc_RsaPSS_Sign_ex(digest, digestSz, out, outSz, hash[0],
mgf[0], -2, key, rng); mgf[0], len, key, rng);
} }
} while (ret == WC_PENDING_E); } while (ret == WC_PENDING_E);
if (ret != PSS_SALTLEN_E) if (ret != PSS_SALTLEN_E)
@@ -10777,21 +10783,31 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key)
ERROR_OUT(-6830, exit_rsa_pss); ERROR_OUT(-6830, exit_rsa_pss);
TEST_SLEEP(); TEST_SLEEP();
#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
len = -2;
#else
len = -3;
#endif
#ifdef HAVE_SELFTEST #ifdef HAVE_SELFTEST
ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, plain, plainSz, hash[0], ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, plain, plainSz, hash[0],
-2); len);
#else #else
ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, plain, plainSz, hash[0], ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, plain, plainSz, hash[0],
-2, 0); len, 0);
#endif #endif
if (ret != PSS_SALTLEN_E) if (ret != PSS_SALTLEN_E)
ERROR_OUT(-6831, exit_rsa_pss); ERROR_OUT(-6831, exit_rsa_pss);
#ifndef WOLFSSL_PSS_LONG_SALT
len = digestSz + 1;
#else
len = plainSz - digestSz - 1;
#endif
#ifdef HAVE_SELFTEST #ifdef HAVE_SELFTEST
ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, plain, plainSz, hash[0], ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, plain, plainSz, hash[0],
digestSz + 1); len);
#else #else
ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, plain, plainSz, hash[0], ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, plain, plainSz, hash[0],
digestSz + 1, 0); len, 0);
#endif #endif
if (ret != PSS_SALTLEN_E) if (ret != PSS_SALTLEN_E)
ERROR_OUT(-6832, exit_rsa_pss); ERROR_OUT(-6832, exit_rsa_pss);

View File

@@ -199,7 +199,7 @@ enum {
WC_HW_E = -248, /* Error with hardware crypto use */ WC_HW_E = -248, /* Error with hardware crypto use */
WC_HW_WAIT_E = -249, /* Hardware waiting on resource */ WC_HW_WAIT_E = -249, /* Hardware waiting on resource */
PSS_SALTLEN_E = -250, /* PSS length of salt is to long for hash */ PSS_SALTLEN_E = -250, /* PSS length of salt is too long for hash */
PRIME_GEN_E = -251, /* Failure finding a prime. */ PRIME_GEN_E = -251, /* Failure finding a prime. */
BER_INDEF_E = -252, /* Cannot decode indefinite length BER. */ BER_INDEF_E = -252, /* Cannot decode indefinite length BER. */
RSA_OUT_OF_RANGE_E = -253, /* Ciphertext to decrypt out of range. */ RSA_OUT_OF_RANGE_E = -253, /* Ciphertext to decrypt out of range. */
@@ -226,8 +226,9 @@ enum {
CRYPTOCB_UNAVAILABLE= -271, /* Crypto callback unavailable */ CRYPTOCB_UNAVAILABLE= -271, /* Crypto callback unavailable */
PKCS7_SIGNEEDS_CHECK= -272, /* signature needs verified by caller */ PKCS7_SIGNEEDS_CHECK= -272, /* signature needs verified by caller */
PSS_SALTLEN_RECOVER_E=-273, /* PSS slat length not recoverable */
WC_LAST_E = -272, /* Update this to indicate last error */ WC_LAST_E = -273, /* Update this to indicate last error */
MIN_CODE_E = -300 /* errors -101 - -299 */ MIN_CODE_E = -300 /* errors -101 - -299 */
/* add new companion error id strings for any new error codes /* add new companion error id strings for any new error codes

View File

@@ -130,6 +130,11 @@ enum {
RSA_PSS_PAD_TERM = 0xBC, RSA_PSS_PAD_TERM = 0xBC,
#endif #endif
RSA_PSS_SALT_LEN_DEFAULT = -1,
#ifdef WOLFSSL_PSS_SALT_LEN_DISCOVER
RSA_PSS_SALT_LEN_DISCOVER = -2,
#endif
#ifdef HAVE_PKCS11 #ifdef HAVE_PKCS11
RSA_MAX_ID_LEN = 32, RSA_MAX_ID_LEN = 32,
#endif #endif