Skip to content

Commit 2c90d15

Browse files
Merge pull request #8897 from anhu/compat_additions
Compatibility layer additions for X.509 extensions and RSA PSS
2 parents e06f1bb + c341a9f commit 2c90d15

File tree

14 files changed

+564
-131
lines changed

14 files changed

+564
-131
lines changed

src/pk.c

Lines changed: 138 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3534,9 +3534,43 @@ int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* e,
35343534
* RSA padding APIs
35353535
*/
35363536

3537-
#if defined(WC_RSA_PSS) && (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || \
3538-
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX))
3539-
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
3537+
#ifdef WC_RSA_PSS
3538+
3539+
#if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST) && \
3540+
(!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
3541+
static int rsa_pss_calc_salt(int saltLen, int hashLen, int emLen)
3542+
{
3543+
/* Calculate the salt length to use for special cases. */
3544+
switch (saltLen) {
3545+
/* Negative saltLen values are treated differently. */
3546+
case WC_RSA_PSS_SALTLEN_DIGEST:
3547+
saltLen = hashLen;
3548+
break;
3549+
case WC_RSA_PSS_SALTLEN_MAX_SIGN:
3550+
case WC_RSA_PSS_SALTLEN_MAX:
3551+
#ifdef WOLFSSL_PSS_LONG_SALT
3552+
saltLen = emLen - hashLen - 2;
3553+
#else
3554+
saltLen = hashLen;
3555+
(void)emLen;
3556+
#endif
3557+
break;
3558+
default:
3559+
break;
3560+
}
3561+
if (saltLen < 0) {
3562+
/* log invalid salt, let wolfCrypt handle error */
3563+
WOLFSSL_ERROR_MSG("invalid saltLen");
3564+
saltLen = -3; /* for wolfCrypt to produce error must be < -2 */
3565+
}
3566+
return saltLen;
3567+
}
3568+
#endif /* OPENSSL_EXTRA && !HAVE_SELFTEST */
3569+
3570+
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || \
3571+
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX)) && \
3572+
(!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
3573+
35403574
/* Add PKCS#1 PSS padding to hash.
35413575
*
35423576
*
@@ -3654,28 +3688,7 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS_mgf1(WOLFSSL_RSA *rsa, unsigned char *em,
36543688
}
36553689

36563690
if (ret == 1) {
3657-
/* Calculate the salt length to use for special cases. */
3658-
/* TODO: use special case wolfCrypt values? */
3659-
switch (saltLen) {
3660-
/* Negative saltLen values are treated differently. */
3661-
case RSA_PSS_SALTLEN_DIGEST:
3662-
saltLen = hashLen;
3663-
break;
3664-
case RSA_PSS_SALTLEN_MAX_SIGN:
3665-
case RSA_PSS_SALTLEN_MAX:
3666-
#ifdef WOLFSSL_PSS_LONG_SALT
3667-
saltLen = emLen - hashLen - 2;
3668-
#else
3669-
saltLen = hashLen;
3670-
#endif
3671-
break;
3672-
default:
3673-
if (saltLen < 0) {
3674-
/* No other negative values implemented. */
3675-
WOLFSSL_ERROR_MSG("invalid saltLen");
3676-
ret = 0;
3677-
}
3678-
}
3691+
saltLen = rsa_pss_calc_salt(saltLen, hashLen, emLen);
36793692
}
36803693

36813694
if (ret == 1) {
@@ -3767,31 +3780,7 @@ int wolfSSL_RSA_verify_PKCS1_PSS_mgf1(WOLFSSL_RSA *rsa,
37673780
}
37683781

37693782
if (ret == 1) {
3770-
/* Calculate the salt length to use for special cases. */
3771-
switch (saltLen) {
3772-
/* Negative saltLen values are treated differently */
3773-
case RSA_PSS_SALTLEN_DIGEST:
3774-
saltLen = hashLen;
3775-
break;
3776-
case RSA_PSS_SALTLEN_AUTO:
3777-
#ifdef WOLFSSL_PSS_SALT_LEN_DISCOVER
3778-
saltLen = RSA_PSS_SALT_LEN_DISCOVER;
3779-
break;
3780-
#endif
3781-
case RSA_PSS_SALTLEN_MAX:
3782-
#ifdef WOLFSSL_PSS_LONG_SALT
3783-
saltLen = emLen - hashLen - 2;
3784-
#else
3785-
saltLen = hashLen;
3786-
#endif
3787-
break;
3788-
default:
3789-
if (saltLen < 0) {
3790-
/* No other negative values implemented. */
3791-
WOLFSSL_ERROR_MSG("invalid saltLen");
3792-
ret = 0;
3793-
}
3794-
}
3783+
saltLen = rsa_pss_calc_salt(saltLen, hashLen, emLen);
37953784
}
37963785

37973786
if (ret == 1) {
@@ -3856,18 +3845,23 @@ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
38563845
return wolfSSL_RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, hashAlg, NULL, em,
38573846
saltLen);
38583847
}
3859-
#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
3860-
#endif /* WC_RSA_PSS && (OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY ||
3861-
* WOLFSSL_NGINX) */
3848+
#endif /* (!HAVE_FIPS || FIPS_VERSION_GT(2,0)) && \
3849+
(OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_NGINX) */
3850+
#endif /* WC_RSA_PSS */
38623851

38633852
/*
38643853
* RSA sign/verify APIs
38653854
*/
38663855

3867-
#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
3868-
#define DEF_PSS_SALT_LEN RSA_PSS_SALT_LEN_DEFAULT
3856+
#if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && \
3857+
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,1))
3858+
#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
3859+
#define DEF_PSS_SALT_LEN RSA_PSS_SALT_LEN_DEFAULT
3860+
#else
3861+
#define DEF_PSS_SALT_LEN RSA_PSS_SALT_LEN_DISCOVER
3862+
#endif
38693863
#else
3870-
#define DEF_PSS_SALT_LEN RSA_PSS_SALT_LEN_DISCOVER
3864+
#define DEF_PSS_SALT_LEN 0 /* not used */
38713865
#endif
38723866

38733867
#if defined(OPENSSL_EXTRA)
@@ -3980,6 +3974,14 @@ int wolfSSL_RSA_sign_ex(int hashAlg, const unsigned char* hash,
39803974
return ret;
39813975
}
39823976

3977+
int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
3978+
unsigned int hLen, unsigned char* sigRet, unsigned int* sigLen,
3979+
WOLFSSL_RSA* rsa, int flag, int padding)
3980+
{
3981+
return wolfSSL_RSA_sign_mgf(hashAlg, hash, hLen, sigRet, sigLen, rsa, flag,
3982+
padding, hashAlg, DEF_PSS_SALT_LEN);
3983+
}
3984+
39833985
/**
39843986
* Sign a message hash with the chosen message digest, padding, and RSA key.
39853987
*
@@ -3998,12 +4000,14 @@ int wolfSSL_RSA_sign_ex(int hashAlg, const unsigned char* hash,
39984000
* @param [in] padding Padding to use. Only RSA_PKCS1_PSS_PADDING and
39994001
* WC_RSA_PKCS1_PADDING are currently supported for
40004002
* signing.
4003+
* @param [in] mgf1Hash MGF1 Hash NID
4004+
* @param [in] saltLen Length of RSA PSS salt
40014005
* @return 1 on success.
40024006
* @return 0 on failure.
40034007
*/
4004-
int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
4008+
int wolfSSL_RSA_sign_mgf(int hashAlg, const unsigned char* hash,
40054009
unsigned int hLen, unsigned char* sigRet, unsigned int* sigLen,
4006-
WOLFSSL_RSA* rsa, int flag, int padding)
4010+
WOLFSSL_RSA* rsa, int flag, int padding, int mgf1Hash, int saltLen)
40074011
{
40084012
int ret = 1;
40094013
word32 outLen = 0;
@@ -4020,8 +4024,7 @@ int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
40204024
#endif
40214025
unsigned int encSz = 0;
40224026

4023-
4024-
WOLFSSL_ENTER("wolfSSL_RSA_sign_generic_padding");
4027+
WOLFSSL_ENTER("wolfSSL_RSA_sign_mgf");
40254028

40264029
if (flag == 0) {
40274030
/* Only encode message. */
@@ -4088,7 +4091,7 @@ int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
40884091
case WC_RSA_NO_PAD:
40894092
if ((signSz = wc_RsaDirect(encodedSig, encSz, sigRet, &outLen,
40904093
(RsaKey*)rsa->internal, RSA_PRIVATE_ENCRYPT, rng)) <= 0) {
4091-
WOLFSSL_ERROR_MSG("Bad Rsa Sign no pad");
4094+
WOLFSSL_ERROR_MSG("Bad RSA Sign no pad");
40924095
ret = 0;
40934096
}
40944097
break;
@@ -4097,17 +4100,20 @@ int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
40974100
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,1))
40984101
case WC_RSA_PKCS1_PSS_PADDING:
40994102
{
4100-
enum wc_HashType hType =
4101-
wc_OidGetHash((int)nid2oid(hashAlg, oidHashType));
4102-
#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
4103-
WOLFSSL_MSG("Using RSA-PSS with hash length salt. "
4104-
"OpenSSL uses max length by default.");
4105-
#endif
4103+
RsaKey* key = (RsaKey*)rsa->internal;
4104+
enum wc_HashType mgf1, hType;
4105+
hType = wc_OidGetHash((int)nid2oid(hashAlg, oidHashType));
4106+
if (mgf1Hash == WC_NID_undef)
4107+
mgf1Hash = hashAlg;
4108+
mgf1 = wc_OidGetHash((int)nid2oid(mgf1Hash, oidHashType));
4109+
/* handle compat layer salt special cases */
4110+
saltLen = rsa_pss_calc_salt(saltLen, wc_HashGetDigestSize(hType),
4111+
wolfSSL_RSA_size(rsa));
4112+
41064113
/* Create RSA PSS signature. */
41074114
if ((signSz = wc_RsaPSS_Sign_ex(encodedSig, encSz, sigRet, outLen,
4108-
hType, wc_hash2mgf(hType), DEF_PSS_SALT_LEN,
4109-
(RsaKey*)rsa->internal, rng)) <= 0) {
4110-
WOLFSSL_ERROR_MSG("Bad Rsa Sign");
4115+
hType, wc_hash2mgf(mgf1), saltLen, key, rng)) <= 0) {
4116+
WOLFSSL_ERROR_MSG("Bad RSA PSS Sign");
41114117
ret = 0;
41124118
}
41134119
break;
@@ -4126,13 +4132,15 @@ int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
41264132
/* Sign (private encrypt) PKCS#1 encoded signature. */
41274133
if ((signSz = wc_RsaSSL_Sign(encodedSig, encSz, sigRet, outLen,
41284134
(RsaKey*)rsa->internal, rng)) <= 0) {
4129-
WOLFSSL_ERROR_MSG("Bad Rsa Sign");
4135+
WOLFSSL_ERROR_MSG("Bad PKCS1 RSA Sign");
41304136
ret = 0;
41314137
}
41324138
break;
41334139
}
41344140
default:
41354141
WOLFSSL_ERROR_MSG("Unsupported padding");
4142+
(void)mgf1Hash;
4143+
(void)saltLen;
41364144
ret = 0;
41374145
break;
41384146
}
@@ -4153,7 +4161,7 @@ int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
41534161
XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE);
41544162
#endif
41554163

4156-
WOLFSSL_LEAVE("wolfSSL_RSA_sign_generic_padding", ret);
4164+
WOLFSSL_LEAVE("wolfSSL_RSA_sign_mgf", ret);
41574165
return ret;
41584166
}
41594167

@@ -4177,6 +4185,14 @@ int wolfSSL_RSA_verify(int hashAlg, const unsigned char* hash,
41774185
WC_RSA_PKCS1_PADDING);
41784186
}
41794187

4188+
int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash,
4189+
unsigned int hLen, const unsigned char* sig, unsigned int sigLen,
4190+
WOLFSSL_RSA* rsa, int padding)
4191+
{
4192+
return wolfSSL_RSA_verify_mgf(hashAlg, hash, hLen, sig, sigLen, rsa,
4193+
padding, hashAlg, DEF_PSS_SALT_LEN);
4194+
}
4195+
41804196
/**
41814197
* Verify a message hash with the chosen message digest, padding, and RSA key.
41824198
*
@@ -4191,12 +4207,14 @@ int wolfSSL_RSA_verify(int hashAlg, const unsigned char* hash,
41914207
* @param [in] padding Padding to use. Only RSA_PKCS1_PSS_PADDING and
41924208
* WC_RSA_PKCS1_PADDING are currently supported for
41934209
* signing.
4210+
* @param [in] mgf1Hash MGF1 Hash NID
4211+
* @param [in] saltLen Length of RSA PSS salt
41944212
* @return 1 on success.
41954213
* @return 0 on failure.
41964214
*/
4197-
int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash,
4215+
int wolfSSL_RSA_verify_mgf(int hashAlg, const unsigned char* hash,
41984216
unsigned int hLen, const unsigned char* sig, unsigned int sigLen,
4199-
WOLFSSL_RSA* rsa, int padding)
4217+
WOLFSSL_RSA* rsa, int padding, int mgf1Hash, int saltLen)
42004218
{
42014219
int ret = 1;
42024220
#ifdef WOLFSSL_SMALL_STACK
@@ -4211,7 +4229,7 @@ int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash,
42114229
enum wc_HashType hType = WC_HASH_TYPE_NONE;
42124230
#endif
42134231

4214-
WOLFSSL_ENTER("wolfSSL_RSA_verify");
4232+
WOLFSSL_ENTER("wolfSSL_RSA_verify_mgf");
42154233

42164234
/* Validate parameters. */
42174235
if ((hash == NULL) || (sig == NULL) || (rsa == NULL)) {
@@ -4228,8 +4246,49 @@ int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash,
42284246
ret = 0;
42294247
}
42304248
}
4249+
if (ret == 1 && padding == WC_RSA_PKCS1_PSS_PADDING) {
4250+
#if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && \
4251+
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,1))
4252+
RsaKey* key = (RsaKey*)rsa->internal;
4253+
enum wc_HashType mgf1;
4254+
hType = wc_OidGetHash((int)nid2oid(hashAlg, oidHashType));
4255+
if (mgf1Hash == WC_NID_undef)
4256+
mgf1Hash = hashAlg;
4257+
mgf1 = wc_OidGetHash((int)nid2oid(mgf1Hash, oidHashType));
4258+
4259+
/* handle compat layer salt special cases */
4260+
saltLen = rsa_pss_calc_salt(saltLen, wc_HashGetDigestSize(hType),
4261+
wolfSSL_RSA_size(rsa));
4262+
4263+
verLen = wc_RsaPSS_Verify_ex((byte*)sig, sigLen, sigDec, sigLen,
4264+
hType, wc_hash2mgf(mgf1), saltLen, key);
4265+
if (verLen > 0) {
4266+
/* Check PSS padding is valid. */
4267+
if (wc_RsaPSS_CheckPadding_ex(hash, hLen, sigDec, (word32)verLen,
4268+
hType, saltLen, mp_count_bits(&key->n)) != 0) {
4269+
WOLFSSL_ERROR_MSG("wc_RsaPSS_CheckPadding_ex error");
4270+
ret = WOLFSSL_FAILURE;
4271+
}
4272+
else {
4273+
/* Success! Free resources and return early */
4274+
XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4275+
return WOLFSSL_SUCCESS;
4276+
}
4277+
}
4278+
else {
4279+
WOLFSSL_ERROR_MSG("wc_RsaPSS_Verify_ex failed!");
4280+
ret = WOLFSSL_FAILURE;
4281+
}
4282+
#else
4283+
(void)mgf1Hash;
4284+
(void)saltLen;
4285+
WOLFSSL_ERROR_MSG("RSA PSS not compiled in!");
4286+
ret = WOLFSSL_FAILURE;
4287+
#endif
4288+
}
4289+
42314290
#ifdef WOLFSSL_SMALL_STACK
4232-
if ((ret == 1) && (padding != WC_RSA_PKCS1_PSS_PADDING)) {
4291+
if (ret == 1) {
42334292
/* Allocate memory for encoded signature. */
42344293
encodedSig = (unsigned char *)XMALLOC(len, NULL,
42354294
DYNAMIC_TYPE_TMP_BUFFER);
@@ -4239,7 +4298,7 @@ int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash,
42394298
}
42404299
}
42414300
#endif
4242-
if ((ret == 1) && (padding != WC_RSA_PKCS1_PSS_PADDING)) {
4301+
if (ret == 1) {
42434302
/* Make encoded signature to compare with decrypted signature. */
42444303
if (wolfssl_rsa_sig_encode(hashAlg, hash, hLen, encodedSig, &len,
42454304
padding) <= 0) {
@@ -4266,20 +4325,6 @@ int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash,
42664325
#endif
42674326
}
42684327
if (ret == 1) {
4269-
#if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && \
4270-
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 1))
4271-
if (padding == WC_RSA_PKCS1_PSS_PADDING) {
4272-
/* Check PSS padding is valid. */
4273-
if (wc_RsaPSS_CheckPadding_ex(hash, hLen, sigDec, (word32)verLen,
4274-
hType, DEF_PSS_SALT_LEN,
4275-
mp_count_bits(&((RsaKey*)rsa->internal)->n)) != 0) {
4276-
WOLFSSL_ERROR_MSG("wc_RsaPSS_CheckPadding_ex error");
4277-
ret = 0;
4278-
}
4279-
}
4280-
else
4281-
#endif /* WC_RSA_PSS && !HAVE_SELFTEST && (!HAVE_FIPS ||
4282-
* FIPS_VERSION >= 5.1) */
42834328
/* Compare decrypted signature to encoded signature. */
42844329
if (((int)len != verLen) ||
42854330
(XMEMCMP(encodedSig, sigDec, (size_t)verLen) != 0)) {
@@ -4293,6 +4338,8 @@ int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash,
42934338
XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
42944339
#endif
42954340
XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4341+
4342+
WOLFSSL_LEAVE("wolfSSL_RSA_verify_mgf", ret);
42964343
return ret;
42974344
}
42984345

0 commit comments

Comments
 (0)