diff --git a/tests/api/test_evp_pkey.c b/tests/api/test_evp_pkey.c index 632af9eae4d..51c8b5cef02 100644 --- a/tests/api/test_evp_pkey.c +++ b/tests/api/test_evp_pkey.c @@ -2440,6 +2440,12 @@ int test_wolfSSL_EVP_MD_ecc_signing(void) (unsigned int)XSTRLEN(testData)), 1); checkSz = sizeof(check); ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1); + ExpectIntEQ((int)checkSz, wolfSSL_EVP_PKEY_size(privKey)); + /* A buffer too small for the signature is an error. */ + checkSz = 8; + ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 0); + ExpectIntEQ((int)checkSz, 8); + ExpectIntEQ(check[0], 0); checkSz = sizeof(check); ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1); ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx); @@ -2487,6 +2493,43 @@ int test_wolfSSL_EVP_MD_ecc_signing(void) return EXPECT_RESULT(); } +int test_wolfSSL_EVP_DigestSignFinal_ecc_size(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(NO_SHA256) && \ + defined(HAVE_ECC_BRAINPOOL) && \ + (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && \ + ECC_MIN_KEY_SZ <= 512 && FIPS_VERSION3_LT(6,0,0) + WOLFSSL_EC_KEY* ecKey = NULL; + WOLFSSL_EVP_PKEY* pkey = NULL; + WOLFSSL_EVP_MD_CTX mdCtx; + size_t sigSz = 0; + int ret; + + ExpectNotNull(ecKey = wolfSSL_EC_KEY_new_by_curve_name( + NID_brainpoolP512r1)); + ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1); + ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new()); + ExpectIntEQ(wolfSSL_EVP_PKEY_assign_EC_KEY(pkey, ecKey), WOLFSSL_SUCCESS); + if (EXPECT_FAIL()) { + wolfSSL_EC_KEY_free(ecKey); + } + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, pkey), 1); + ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &sigSz), 1); + /* r and s may need a leading zero and the SEQ length is two bytes. */ + ExpectIntEQ((int)sigSz, 137); + ExpectIntEQ((int)sigSz, wolfSSL_EVP_PKEY_size(pkey)); + ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx); + ExpectIntEQ(ret, 1); + + wolfSSL_EVP_PKEY_free(pkey); +#endif + return EXPECT_RESULT(); +} + int test_wolfSSL_EVP_DigestSign(void) { diff --git a/tests/api/test_evp_pkey.h b/tests/api/test_evp_pkey.h index 874391edb21..1db3107f3b6 100644 --- a/tests/api/test_evp_pkey.h +++ b/tests/api/test_evp_pkey.h @@ -65,6 +65,7 @@ int test_wolfSSL_EVP_PKEY_verify_dsa_len(void); int test_wolfSSL_EVP_MD_rsa_signing(void); int test_wc_RsaPSS_DigitalSignVerify(void); int test_wolfSSL_EVP_MD_ecc_signing(void); +int test_wolfSSL_EVP_DigestSignFinal_ecc_size(void); int test_wolfSSL_EVP_DigestSign(void); int test_wolfSSL_EVP_DigestSign_ecc(void); int test_wolfSSL_EVP_PKEY_encrypt(void); @@ -126,6 +127,7 @@ int test_wolfSSL_CTX_use_PrivateKey_pkcs8_repopulate(void); TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_rsa_signing), \ TEST_DECL_GROUP("evp_pkey", test_wc_RsaPSS_DigitalSignVerify), \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_ecc_signing), \ + TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_DigestSignFinal_ecc_size), \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_DigestSign), \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_DigestSign_ecc), \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_encrypt), \ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 3b212155b64..6164dff91f2 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -5225,9 +5225,17 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, #ifdef HAVE_ECC else if (ctx->pctx->pkey->type == WC_EVP_PKEY_EC) { if (sig == NULL) { - /* SEQ + INT + INT */ - *siglen = (size_t)ecc_sets[ctx->pctx->pkey->ecc->group->curve_idx]. - size * 2 + 8; + WOLFSSL_EC_KEY* key = ctx->pctx->pkey->ecc; + int sigSz; + + if (key == NULL || (key->inSet == 0 && + SetECKeyInternal(key) != WOLFSSL_SUCCESS)) { + return WOLFSSL_FAILURE; + } + sigSz = wc_ecc_sig_size((ecc_key*)key->internal); + if (sigSz <= 0) + return WOLFSSL_FAILURE; + *siglen = (size_t)sigSz; return WOLFSSL_SUCCESS; } } @@ -5277,8 +5285,10 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, NULL); if (len > 0 && (size_t)len <= *siglen) len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig); + else + len = 0; wolfSSL_ECDSA_SIG_free(ecdsaSig); - if (len == 0) + if (len <= 0) break; *siglen = (size_t)len; ret = WOLFSSL_SUCCESS;