diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index 6065b171..9661f0f9 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -415,8 +415,12 @@ static int wp_rsagen_check_key_size(wp_RsaGenCtx* rsagen) */ void wp_rsa_get_pss_mds(wp_Rsa* rsa, char** mdName, char** mgfMdName) { - *mdName = rsa->pssParams.mdName; - *mgfMdName = rsa->pssParams.mgfMdName; + if (mdName != NULL) { + *mdName = rsa->pssParams.mdName; + } + if (mgfMdName != NULL) { + *mgfMdName = rsa->pssParams.mgfMdName; + } } /** diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index 270f1cf4..e92c1085 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -118,6 +118,7 @@ static int wp_rsa_setup_md(wp_RsaSigCtx* ctx, const char* mdName, const char* mdProps, int op) { int ok = 1; + char *localMdName = NULL; WOLFPROV_ENTER(WP_LOG_RSA, "wp_rsa_setup_md"); @@ -125,7 +126,16 @@ static int wp_rsa_setup_md(wp_RsaSigCtx* ctx, const char* mdName, mdProps = ctx->propQuery; } - if (mdName != NULL) { + /* For PSS restricted mode, not allowed to set new MD */ + if (ctx->padMode == RSA_PKCS1_PSS_PADDING && ctx->minSaltLen != -1) { + wp_rsa_get_pss_mds(ctx->rsa, &localMdName, NULL); + if (mdName != NULL && + XSTRNCASECMP(localMdName, mdName, XSTRLEN(localMdName)) != 0) { + ok = 0; + } + } + + if (ok && mdName != NULL) { int rc; enum wc_HashType hashType; @@ -381,7 +391,10 @@ static int wp_pss_salt_len_to_wc(int saltLen, enum wc_HashType hashType, } else if (saltLen == RSA_PSS_SALTLEN_AUTO) { #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER - saltLen = wc_HashGetDigestSize(hashType); + saltLen = wc_RsaEncryptSize(key) - wc_HashGetDigestSize(hashType) - 2; + if (((mp_count_bits(&key->n) - 1) & 0x7) == 0) { + saltLen--; + } #else saltLen = RSA_PSS_SALT_LEN_DISCOVER; #endif @@ -462,6 +475,7 @@ static int wp_rsa_signverify_init(wp_RsaSigCtx* ctx, wp_Rsa* rsa, const OSSL_PARAM params[], int op) { int ok = 1; + int saltLen = 0; WOLFPROV_ENTER(WP_LOG_RSA, "wp_rsa_signverify_init"); @@ -498,6 +512,13 @@ static int wp_rsa_signverify_init(wp_RsaSigCtx* ctx, wp_Rsa* rsa, ctx->saltLen = WP_RSA_DEFAULT_SALT_LEN; #endif ctx->minSaltLen = 0; + + /* If we have already set PSS salt len, use that */ + saltLen = wp_rsa_get_pss_salt_len(ctx->rsa); + if (saltLen != 0) { + ctx->saltLen = saltLen; + ctx->minSaltLen = saltLen; + } } else { char* mdName; @@ -2142,8 +2163,13 @@ static int wp_rsa_set_salt_len(wp_RsaSigCtx* ctx, const OSSL_PARAM* p) else { ok = 0; } +#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX + /* RSA_PSS_SALTLEN_AUTO_DIGEST_MAX is the smallest negative value supported. */ + if (ok && (ctx->saltLen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX)) { +#else /* RSA_PSS_SALTLEN_MAX is the smallest negative value supported. */ if (ok && (ctx->saltLen < RSA_PSS_SALTLEN_MAX)) { +#endif ok = 0; } if (ok && (ctx->saltLen >= 0) && (ctx->saltLen < ctx->minSaltLen)) { diff --git a/test/test_ecc.c b/test/test_ecc.c index ea1d0244..2cd21cf4 100644 --- a/test/test_ecc.c +++ b/test/test_ecc.c @@ -1253,19 +1253,19 @@ int test_ecdsa_p192(void *data) if (err == 0) { PRINT_MSG("Sign with OpenSSL"); ecdsaSigLen = sizeof(ecdsaSig); - err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), md, - ecdsaSig, &ecdsaSigLen, 0); + err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with wolfprovider"); - err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify bad signature with wolfprovider"); ecdsaSig[1] ^= 0x80; - res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); if (res != 1) err = 1; } @@ -1273,8 +1273,8 @@ int test_ecdsa_p192(void *data) if (err == 0) { PRINT_MSG("Sign with wolfprovider"); ecdsaSigLen = sizeof(ecdsaSig); - err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, &ecdsaSigLen, 0); + err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, &ecdsaSigLen, 0, 0); #if defined(HAVE_FIPS) || defined(HAVE_FIPS_VERSION) err = err != 1; if (err == 0) { @@ -1289,8 +1289,8 @@ int test_ecdsa_p192(void *data) } if (err == 0) { PRINT_MSG("Verify with OpenSSL"); - err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); } #endif /* HAVE_FIPS || HAVE_FIPS_VERSION */ @@ -1326,32 +1326,32 @@ int test_ecdsa_p224(void *data) if (err == 0) { PRINT_MSG("Sign with OpenSSL"); ecdsaSigLen = sizeof(ecdsaSig); - err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), md, - ecdsaSig, &ecdsaSigLen, 0); + err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with wolfprovider"); - err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify bad signature with wolfprovider"); ecdsaSig[1] ^= 0x80; - res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); if (res != 1) err = 1; } if (err == 0) { PRINT_MSG("Sign with wolfprovider"); ecdsaSigLen = sizeof(ecdsaSig); - err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, &ecdsaSigLen, 0); + err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with OpenSSL"); - err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); } EVP_PKEY_free(pkey); @@ -1382,18 +1382,18 @@ int test_ecdsa_p256(void *data) PRINT_MSG("Sign with OpenSSL"); ecdsaSigLen = sizeof(ecdsaSig); err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), "SHA-256", - ecdsaSig, &ecdsaSigLen, 0); + NULL, ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with wolfprovider"); err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), "SHA-256", - ecdsaSig, ecdsaSigLen, 0); + NULL, ecdsaSig, ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify bad signature with wolfprovider"); ecdsaSig[1] ^= 0x80; res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), "SHA-256", - ecdsaSig, ecdsaSigLen, 0); + NULL, ecdsaSig, ecdsaSigLen, 0, 0); if (res != 1) err = 1; } @@ -1401,12 +1401,12 @@ int test_ecdsa_p256(void *data) PRINT_MSG("Sign with wolfprovider"); ecdsaSigLen = sizeof(ecdsaSig); err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), "SHA-256", - ecdsaSig, &ecdsaSigLen, 0); + NULL, ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with OpenSSL"); err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), "SHA-256", - ecdsaSig, ecdsaSigLen, 0); + NULL, ecdsaSig, ecdsaSigLen, 0, 0); } EVP_PKEY_free(pkey); @@ -1441,32 +1441,32 @@ int test_ecdsa_p384(void *data) if (err == 0) { PRINT_MSG("Sign with OpenSSL"); ecdsaSigLen = sizeof(ecdsaSig); - err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), md, - ecdsaSig, &ecdsaSigLen, 0); + err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with wolfprovider"); - err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify bad signature with wolfprovider"); ecdsaSig[1] ^= 0x80; - res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); if (res != 1) err = 1; } if (err == 0) { PRINT_MSG("Sign with wolfprovider"); ecdsaSigLen = sizeof(ecdsaSig); - err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, &ecdsaSigLen, 0); + err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with OpenSSL"); - err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); } EVP_PKEY_free(pkey); @@ -1501,32 +1501,32 @@ int test_ecdsa_p521(void *data) if (err == 0) { PRINT_MSG("Sign with OpenSSL"); ecdsaSigLen = sizeof(ecdsaSig); - err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), md, - ecdsaSig, &ecdsaSigLen, 0); + err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with wolfprovider"); - err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify bad signature with wolfprovider"); ecdsaSig[1] ^= 0x80; - res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + res = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); if (res != 1) err = 1; } if (err == 0) { PRINT_MSG("Sign with wolfprovider"); ecdsaSigLen = sizeof(ecdsaSig); - err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), md, - ecdsaSig, &ecdsaSigLen, 0); + err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, &ecdsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with OpenSSL"); - err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), md, - ecdsaSig, ecdsaSigLen, 0); + err = test_digest_verify(pkey, osslLibCtx, buf, sizeof(buf), md, NULL, + ecdsaSig, ecdsaSigLen, 0, 0); } EVP_PKEY_free(pkey); diff --git a/test/test_ecx.c b/test/test_ecx.c index a53ff798..99304fcf 100644 --- a/test/test_ecx.c +++ b/test/test_ecx.c @@ -107,29 +107,29 @@ static int sign_verify(unsigned char* sig, size_t sigLen, if (err == 0) { PRINT_MSG("Sign with OpenSSL (%s)", name); - err = test_digest_sign(pkey, osslLibCtx, buf, bufLen, NULL, - sig, &sigLen, 0); + err = test_digest_sign(pkey, osslLibCtx, buf, bufLen, NULL, NULL, sig, + &sigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with WolfProvider (%s)", name); - err = test_digest_verify(pkey, wpLibCtx, buf, bufLen, NULL, - sig, sigLen, 0); + err = test_digest_verify(pkey, wpLibCtx, buf, bufLen, NULL, NULL, sig, + sigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify bad signature with WolfProvider (%s)", name); sig[1] ^= 0x80; - err = test_digest_verify(pkey, wpLibCtx, buf, bufLen, NULL, - sig, sigLen, 0) != 1; + err = test_digest_verify(pkey, wpLibCtx, buf, bufLen, NULL, NULL, sig, + sigLen, 0, 0) != 1; } if (err == 0) { PRINT_MSG("Sign with WolfProvider (%s)", name); - err = test_digest_sign(pkey, wpLibCtx, buf, bufLen, NULL, - sig, &sigLen, 0); + err = test_digest_sign(pkey, wpLibCtx, buf, bufLen, NULL, NULL, sig, + &sigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with OpenSSL (%s)", name); - err = test_digest_verify(pkey, osslLibCtx, buf, bufLen, NULL, - sig, sigLen, 0); + err = test_digest_verify(pkey, osslLibCtx, buf, bufLen, NULL, NULL, sig, + sigLen, 0, 0); } return err; @@ -409,7 +409,7 @@ int test_ecx_sign_verify_raw_pub(void *data) if (err == 0) { PRINT_MSG("Sign with OpenSSL (%s)", types[i].name); err = test_digest_sign(pkey_der, osslLibCtx, buf, bufLen, NULL, - types[i].sig, &types[i].sigLen, 0); + NULL, types[i].sig, &types[i].sigLen, 0, 0); } /* Create keys from the public byte arrays */ @@ -489,12 +489,12 @@ int test_ecx_sign_verify_raw_pub(void *data) if (err == 0) { PRINT_MSG("Verify with OpenSSL (%s)", types[i].name); err = test_digest_verify(pkey_ossl, osslLibCtx, buf, bufLen, NULL, - types[i].sig, types[i].sigLen, 0); + NULL, types[i].sig, types[i].sigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with WolfProvider (%s)", types[i].name); err = test_digest_verify(pkey_wolf, wpLibCtx, buf, bufLen, NULL, - types[i].sig, types[i].sigLen, 0); + NULL, types[i].sig, types[i].sigLen, 0, 0); } /* Verify bad signature with the public keys */ @@ -502,12 +502,14 @@ int test_ecx_sign_verify_raw_pub(void *data) if (err == 0) { PRINT_MSG("Verify bad signature with OpenSSL (%s)", types[i].name); err = test_digest_verify(pkey_ossl, osslLibCtx, buf, bufLen, NULL, - types[i].sig, types[i].sigLen, 0) != 1; + NULL, types[i].sig, types[i].sigLen, + 0, 0) != 1; } if (err == 0) { PRINT_MSG("Verify bad signature with WolfProvider (%s)", types[i].name); err = test_digest_verify(pkey_wolf, wpLibCtx, buf, bufLen, NULL, - types[i].sig, types[i].sigLen, 0) != 1; + NULL, types[i].sig, types[i].sigLen, + 0, 0) != 1; } EVP_PKEY_free(pkey_der); diff --git a/test/test_pkey.c b/test/test_pkey.c index e0f7959c..e4ee6575 100644 --- a/test/test_pkey.c +++ b/test/test_pkey.c @@ -21,8 +21,8 @@ #include "unit.h" int test_digest_sign(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, unsigned char *data, - size_t len, const char *md, unsigned char *sig, size_t *sigLen, - int padMode) + size_t len, const char *md, const EVP_MD *mgf1Md, unsigned char *sig, + size_t *sigLen, int padMode, int saltlen) { int err; EVP_MD_CTX *mdCtx = NULL; @@ -37,7 +37,12 @@ int test_digest_sign(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, unsigned char *data, err = EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, padMode) <= 0; } if ((err == 0) && padMode == RSA_PKCS1_PSS_PADDING) { - err = EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, -1) <= 0; + err = EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, saltlen) <= 0; + } + if ((err == 0) && mgf1Md != NULL && + (padMode == RSA_PKCS1_PSS_PADDING || + padMode == RSA_PKCS1_OAEP_PADDING)) { + err = EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, mgf1Md) <= 0; } if (err == 0) { err = EVP_DigestSign(mdCtx, sig, sigLen, data, len) != 1; @@ -52,8 +57,8 @@ int test_digest_sign(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, unsigned char *data, } int test_digest_verify(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, - unsigned char *data, size_t len, const char *md, unsigned char *sig, - size_t sigLen, int padMode) + unsigned char *data, size_t len, const char *md, const EVP_MD *mgf1Md, + unsigned char *sig, size_t sigLen, int padMode, int saltlen) { int err; EVP_MD_CTX *mdCtx = NULL; @@ -68,7 +73,12 @@ int test_digest_verify(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, err = EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, padMode) <= 0; } if ((err == 0) && padMode == RSA_PKCS1_PSS_PADDING) { - err = EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, -1) < 0; + err = EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, saltlen) <= 0; + } + if ((err == 0) && mgf1Md != NULL && + (padMode == RSA_PKCS1_PSS_PADDING || + padMode == RSA_PKCS1_OAEP_PADDING)) { + err = EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, mgf1Md) <= 0; } if (err == 0) { err = EVP_DigestVerify(mdCtx, sig, sigLen, data, len) != 1; @@ -107,7 +117,9 @@ int test_pkey_sign(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, unsigned char *hash, if ((err == 0) && padMode == RSA_PKCS1_PSS_PADDING) { err = EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) < 0; } - if ((err == 0) && padMode == RSA_PKCS1_PSS_PADDING && rsaMgf1Md != NULL) { + if ((err == 0) && rsaMgf1Md != NULL && + (padMode == RSA_PKCS1_PSS_PADDING || + padMode == RSA_PKCS1_OAEP_PADDING)) { err = EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, rsaMgf1Md) <= 0; } if (err == 0) { @@ -144,7 +156,9 @@ int test_pkey_verify(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, unsigned char *hash, if ((err == 0) && padMode == RSA_PKCS1_PSS_PADDING) { err = EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1) < 0; } - if ((err == 0) && padMode == RSA_PKCS1_PSS_PADDING && rsaMgf1Md != NULL) { + if ((err == 0) && rsaMgf1Md != NULL && + (padMode == RSA_PKCS1_PSS_PADDING || + padMode == RSA_PKCS1_OAEP_PADDING)) { err = EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, rsaMgf1Md) <= 0; } if (err == 0) { diff --git a/test/test_rsa.c b/test/test_rsa.c index 2335dc9e..f84638f5 100644 --- a/test/test_rsa.c +++ b/test/test_rsa.c @@ -352,7 +352,7 @@ static const unsigned char rsa_key_der_2048_pkcs8[] = { }; static int test_rsa_sign_verify_pad(int padMode, const EVP_MD *md, - const EVP_MD *mgf1Md) + const EVP_MD *mgf1Md, int saltlen) { int err; int res; @@ -367,10 +367,12 @@ static int test_rsa_sign_verify_pad(int padMode, const EVP_MD *md, size_t bufLen = 20; unsigned char *buf = NULL; const unsigned char *p = rsa_key_der_2048; + const char *md_name = NULL; PRINT_MSG("Load RSA key"); pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p, sizeof(rsa_key_der_2048)); err = pkey == NULL; + if (err == 0) { rsaKey = EVP_PKEY_get0_RSA(pkey); err = rsaKey == NULL; @@ -393,7 +395,7 @@ static int test_rsa_sign_verify_pad(int padMode, const EVP_MD *md, if (err == 0) { err = RAND_bytes(buf, (int)bufLen) == 0; } - if (err == 0 && padMode == RSA_NO_PADDING) { + if (err == 0 && padMode == RSA_NO_PADDING) { /* Set the MSB to 0 so there's no chance the number is too large for the * RSA modulus. */ buf[0] = 0; @@ -432,46 +434,50 @@ static int test_rsa_sign_verify_pad(int padMode, const EVP_MD *md, padMode, md, mgf1Md); } -#ifdef WP_HAVE_SHA256 +#if defined(WP_HAVE_SHA256) || defined(WP_HAVE_SHA384) || \ + defined(WP_HAVE_SHA512) + md_name = EVP_MD_name(md); + /* OpenSSL doesn't allow RSA signatures with no padding. */ if ((err == 0) && (padMode != RSA_NO_PADDING)) { PRINT_MSG("Test creating/verifying a signature"); PRINT_MSG("Sign with OpenSSL"); - err = test_digest_sign(pkey, osslLibCtx, buf, bufLen, "SHA-256", rsaSig, - &rsaSigLen, padMode); + err = test_digest_sign(pkey, osslLibCtx, buf, bufLen, md_name, mgf1Md, + rsaSig, &rsaSigLen, padMode, saltlen); } if ((err == 0) && (padMode != RSA_NO_PADDING)) { PRINT_MSG("Verify with wolfprovider"); - err = test_digest_verify(pkey, wpLibCtx, buf, bufLen, "SHA-256", rsaSig, - rsaSigLen, padMode); + err = test_digest_verify(pkey, wpLibCtx, buf, bufLen, md_name, mgf1Md, + rsaSig, rsaSigLen, padMode, saltlen); } if ((err == 0) && (padMode != RSA_NO_PADDING)) { PRINT_MSG("Verify bad signature with wolfprovider"); rsaSig[1] ^= 0x80; - res = test_digest_verify(pkey, wpLibCtx, buf, bufLen, "SHA-256", rsaSig, - rsaSigLen, padMode); + res = test_digest_verify(pkey, wpLibCtx, buf, bufLen, md_name, mgf1Md, + rsaSig, rsaSigLen, padMode, saltlen); if (res != 1) err = 1; } if ((err == 0) && (padMode != RSA_NO_PADDING)) { PRINT_MSG("Sign with wolfprovider"); rsaSigLen = RSA_size(rsaKey); - err = test_digest_sign(pkey, wpLibCtx, buf, bufLen, "SHA-256", rsaSig, - &rsaSigLen, padMode); + err = test_digest_sign(pkey, wpLibCtx, buf, bufLen, md_name, mgf1Md, + rsaSig, &rsaSigLen, padMode, saltlen); } if ((err == 0) && (padMode != RSA_NO_PADDING)) { PRINT_MSG("Verify with OpenSSL"); - err = test_digest_verify(pkey, osslLibCtx, buf, bufLen, "SHA-256", - rsaSig, rsaSigLen, padMode); + err = test_digest_verify(pkey, osslLibCtx, buf, bufLen, md_name, mgf1Md, + rsaSig, rsaSigLen, padMode, saltlen); } #endif EVP_PKEY_free(pkey); - - if (rsaSig) + if (rsaSig) { OPENSSL_free(rsaSig); - if (buf) + } + if (buf) { OPENSSL_free(buf); + } return err; } @@ -593,18 +599,18 @@ int test_rsa_sign_sha1(void *data) if (err == 0) { PRINT_MSG("Sign with OpenSSL"); err = test_digest_sign(pkey, osslLibCtx, buf, sizeof(buf), "SHA-1", - rsaSig, &rsaSigLen, 0); + NULL, rsaSig, &rsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Verify with wolfprovider"); err = test_digest_verify(pkey, wpLibCtx, buf, sizeof(buf), "SHA-1", - rsaSig, rsaSigLen, 0); + NULL, rsaSig, rsaSigLen, 0, 0); } if (err == 0) { PRINT_MSG("Sign with wolfprovider"); rsaSigLen = RSA_size(rsaKey); err = test_digest_sign(pkey, wpLibCtx, buf, sizeof(buf), "SHA-1", - rsaSig, &rsaSigLen, 0) != 1; + NULL, rsaSig, &rsaSigLen, 0, 0) != 1; } EVP_PKEY_free(pkey); @@ -619,7 +625,7 @@ int test_rsa_sign_verify_pkcs1(void *data) { (void)data; - return test_rsa_sign_verify_pad(RSA_PKCS1_PADDING, NULL, NULL); + return test_rsa_sign_verify_pad(RSA_PKCS1_PADDING, NULL, NULL, 0); } int test_rsa_sign_verify_recover_pkcs1(void *data) @@ -635,56 +641,254 @@ int test_rsa_sign_verify_pss(void *data) (void)data; - /* Use SHA-1 (default) for MD and MGF1 MD. */ - err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, NULL, NULL) == 1; +#ifndef HAVE_FIPS + /* Use SHA-1 for MD and MGF1 MD. */ + err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha1(), + EVP_sha1(), 0) == 1; +#endif #ifdef WP_HAVE_SHA256 if (err == 0) { /* Use SHA-256 for MD and MGF1 MD. */ err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha256(), - EVP_sha256()) == 1; + EVP_sha256(), 0) == 1; + } +#endif +#ifdef WP_HAVE_SHA384 + if (err == 0) { + /* Use SHA-384 for MD and MGF1 MD. */ + err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha384(), + EVP_sha384(), 0) == 1; } #endif -#if defined(WP_HAVE_SHA384) && defined(WP_AHVE_SHA512) +#ifdef WP_HAVE_SHA512 + if (err == 0) { + /* Use SHA-512 for MD and MGF1 MD. */ + err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha512(), + EVP_sha512(), 0) == 1; + } +#endif +#if defined(WP_HAVE_SHA384) && defined(WP_HAVE_SHA512) if (err == 0) { /* Use SHA-384 for MD and SHA-512 for MGF1 MD. */ err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha384(), - EVP_sha512()) == 1; + EVP_sha512(), 0) == 1; } #endif return err; } -int test_rsa_sign_verify_x931(void *data) +int test_rsa_pss_salt(void *data) { + int err = 0; + + (void)data; + + if (err == 0) { + PRINT_MSG("Salt length = 0 (no salt)"); + err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha256(), + EVP_sha256(), 0) == 1; + } + if (err == 0) { + PRINT_MSG("Salt length = maximum"); + err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha256(), + EVP_sha256(), RSA_PSS_SALTLEN_MAX) == 1; + } + if (err == 0) { + PRINT_MSG("Salt length = digest length"); + err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha256(), + EVP_sha256(), RSA_PSS_SALTLEN_DIGEST) == 1; + } + if (err == 0) { + PRINT_MSG("Salt length = auto"); + err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha256(), + EVP_sha256(), RSA_PSS_SALTLEN_AUTO) == 1; + } +#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX + if (err == 0) { + PRINT_MSG("Salt length = auto maximum"); + err = test_rsa_sign_verify_pad(RSA_PKCS1_PSS_PADDING, EVP_sha256(), + EVP_sha256(), RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) == 1; + } +#endif + return err; +} + +static int test_rsa_pss_restrict_params(OSSL_LIB_CTX *libCtx) +{ + int err = 0; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pkeyCtx = NULL; + EVP_MD_CTX *mdCtx = NULL; + + /* Restrict RSA-PSS to: SHA-512 for MD and MGF1, and a salt length of + * 32 bytes*/ + + pkeyCtx = EVP_PKEY_CTX_new_from_name(libCtx, "RSA-PSS", NULL); + if (pkeyCtx == NULL) { + PRINT_ERR_MSG("Failed to create RSA-PSS key context"); + err = 1; + } + if (err == 0) { + err = EVP_PKEY_keygen_init(pkeyCtx) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_keygen_bits(pkeyCtx, 2048) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_pss_keygen_md(pkeyCtx, EVP_sha512()) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(pkeyCtx, + EVP_sha512()) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(pkeyCtx, 32) <= 0; + } + if (err == 0) { + err = EVP_PKEY_keygen(pkeyCtx, &pkey) <= 0; + } + if (err == 0) { + err = (mdCtx = EVP_MD_CTX_new()) == NULL; + } + EVP_PKEY_CTX_free(pkeyCtx); + pkeyCtx = NULL; + + /* md should accept being set to sha512 but not sha256 */ + if (err == 0) { + err = EVP_DigestSignInit_ex(mdCtx, &pkeyCtx, "SHA256", libCtx, NULL, pkey, + NULL) != 0; + } + if (err == 0) { + err = EVP_DigestSignInit_ex(mdCtx, &pkeyCtx, "SHA512", libCtx, NULL, pkey, + NULL) != 1; + } + if (err == 0) { + PRINT_MSG("MD restriction verified"); + } + + /* mgf1 should accept being set to sha512 but not sha256 */ + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, EVP_sha512()) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, EVP_sha256()) > 0; + } + if (err == 0) { + PRINT_MSG("MGF1 restriction verified"); + } + + /* saltlen should accept being set to maximum but not 0 */ + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, + RSA_PSS_SALTLEN_MAX) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, 0) > 0; + } + if (err == 0) { + PRINT_MSG("Saltlen restriction verified"); + } + + EVP_MD_CTX_free(mdCtx); + EVP_PKEY_free(pkey); + mdCtx = NULL; + pkey = NULL; + + /* Test if salt length restricts digest */ + + pkeyCtx = EVP_PKEY_CTX_new_from_name(libCtx, "RSA-PSS", NULL); + if (pkeyCtx == NULL) { + PRINT_ERR_MSG("Failed to create RSA-PSS key context"); + err = 1; + } + if (err == 0) { + err = EVP_PKEY_keygen_init(pkeyCtx) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_keygen_bits(pkeyCtx, 2048) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_pss_keygen_md(pkeyCtx, EVP_sha256()) <= 0; + } + if (err == 0) { + err = EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(pkeyCtx, 32) <= 0; + } + if (err == 0) { + err = EVP_PKEY_keygen(pkeyCtx, &pkey) <= 0; + } + if (err == 0) { + err = (mdCtx = EVP_MD_CTX_new()) == NULL; + } + EVP_PKEY_CTX_free(pkeyCtx); + pkeyCtx = NULL; + + /* md should accept being set to sha256 but not sha512 */ + if (err == 0) { + err = EVP_DigestSignInit_ex(mdCtx, &pkeyCtx, "SHA512", libCtx, NULL, pkey, + NULL) != 0; + } + if (err == 0) { + err = EVP_DigestSignInit_ex(mdCtx, &pkeyCtx, "SHA256", libCtx, NULL, pkey, + NULL) != 1; + } + if (err == 0) { + PRINT_MSG("Restrictions affect all parameters"); + } + + EVP_MD_CTX_free(mdCtx); + EVP_PKEY_free(pkey); + + return err; +} + +int test_rsa_pss_restrictions(void *data) +{ + int err; + + (void)data; + + PRINT_MSG("Test OpenSSL"); + err = test_rsa_pss_restrict_params(osslLibCtx) == 1; + if (err == 0) { + PRINT_MSG("Test WolfProvider"); + err = test_rsa_pss_restrict_params(wpLibCtx) == 1; + } + + return err; +} + +int test_rsa_sign_verify_x931(void *data) +{ int err = 0; (void)data; #ifndef HAVE_FIPS - /* Use SHA-1 (default) for MD and MGF1 MD. */ - err = test_rsa_sign_verify_pad(RSA_X931_PADDING, EVP_sha1(), NULL) == 1; + /* Use SHA-1 for MD and MGF1 MD. */ + err = test_rsa_sign_verify_pad(RSA_X931_PADDING, EVP_sha1(), + EVP_sha1(), 0) == 1; #endif #ifdef WP_HAVE_SHA256 if (err == 0) { /* Use SHA-256 for MD. */ err = test_rsa_sign_verify_pad(RSA_X931_PADDING, EVP_sha256(), - NULL) == 1; + EVP_sha256(), 0) == 1; } #endif #ifdef WP_HAVE_SHA384 if (err == 0) { /* Use SHA-384 for MD. */ err = test_rsa_sign_verify_pad(RSA_X931_PADDING, EVP_sha384(), - NULL) == 1; + EVP_sha384(), 0) == 1; } #endif #ifdef WP_HAVE_SHA512 if (err == 0) { /* Use SHA-512 for MD. */ err = test_rsa_sign_verify_pad(RSA_X931_PADDING, EVP_sha512(), - NULL) == 1; + EVP_sha512(), 0) == 1; } #endif @@ -823,9 +1027,9 @@ int test_rsa_enc_dec_oaep(void *data) (void)data; - /* Use SHA-1 (default) for MD and MGF1 MD. */ + /* Use SHA-1 for MD and MGF1 MD. */ err = test_rsa_enc_dec(rsa_key_der_1024, sizeof(rsa_key_der_1024), - RSA_PKCS1_OAEP_PADDING, NULL, NULL) == 1; + RSA_PKCS1_OAEP_PADDING, EVP_sha1(), EVP_sha1()) == 1; #ifdef WP_HAVE_SHA256 if (err == 0) { /* Use SHA-256 for MD and MGF1 MD. */ @@ -1182,7 +1386,7 @@ int test_rsa_fromdata(void* data) const char *foo = "some string"; size_t foo_l = strlen(foo); const char bar[] = "some other string"; - + /* Permutations of the params field to test */ OSSL_PARAM params_none[] = { OSSL_PARAM_END diff --git a/test/unit.c b/test/unit.c index 9a7447f4..854831be 100644 --- a/test/unit.c +++ b/test/unit.c @@ -184,6 +184,8 @@ TEST_CASE test_case[] = { #ifndef WOLFPROV_QUICKTEST TEST_DECL(test_rsa_get_params, NULL), #endif + TEST_DECL(test_rsa_pss_salt, NULL), + TEST_DECL(test_rsa_pss_restrictions, NULL), TEST_DECL(test_rsa_load_key, NULL), TEST_DECL(test_rsa_load_cert, NULL), TEST_DECL(test_rsa_fromdata, NULL), diff --git a/test/unit.h b/test/unit.h index 0929b3b4..5579bf70 100644 --- a/test/unit.h +++ b/test/unit.h @@ -18,6 +18,7 @@ * along with wolfProvider. If not, see . */ + #ifndef UNIT_H #define UNIT_H @@ -218,12 +219,12 @@ int test_random(void *data); #endif int test_digest_sign(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, unsigned char *data, - size_t len, const char *md, unsigned char *sig, size_t *sigLen, - int padMode); + size_t len, const char *md, const EVP_MD *mgf1Md, unsigned char *sig, + size_t *sigLen, int padMode, int saltlen); int test_digest_verify(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, - unsigned char *data, size_t len, const char *md, unsigned char *sig, - size_t sigLen, int padMode); + unsigned char *data, size_t len, const char *md, const EVP_MD *mgf1Md, + unsigned char *sig, size_t sigLen, int padMode, int saltlen); int test_pkey_sign(EVP_PKEY *pkey, OSSL_LIB_CTX* libCtx, unsigned char *hash, size_t hashLen, unsigned char *sig, size_t *sigLen, int padMode, @@ -259,6 +260,8 @@ int test_rsa_enc_dec_nopad(void *data); int test_rsa_pkey_keygen(void *data); int test_rsa_pkey_invalid_key_size(void *data); int test_rsa_get_params(void *data); +int test_rsa_pss_salt(void *date); +int test_rsa_pss_restrictions(void *data); int test_rsa_load_key(void* data); int test_rsa_load_cert(void* data); @@ -332,7 +335,7 @@ int test_ecdh_p521_keygen(void *data); #endif /* WP_HAVE_EC_P521 */ #ifdef WP_HAVE_X25519 int test_ecdh_x25519_keygen(void *data); -#endif /* WP_HAVE_X2559 */ +#endif /* WP_HAVE_X25519 */ #ifdef WP_HAVE_X448 int test_ecdh_x448_keygen(void *data); #endif /* WP_HAVE_X448 */