forked from wolfSSL/wolfssl
Add support for EVP_PKEY_sign/verify functionality (#5056)
* Fix wolfSSL_RSA_public_decrypt() return value to match Openssl * Add support for EVP_PKEY_verify_init() and EVP_PKEY_verify() * wpa_supplicant SAE public key functionality requires this function. * Add DSA support for EVP_PKEY_sign/verify() * Add ECDSA support for EVP_PKEY_sign/verify() * Add tests for EVP_PKEY_sign_verify() * Fix "siglen = keySz" at error cases * Fix wolfSSL_DSA_do_sign() usage 1. Check wolfSSL_BN_num_bytes() return value 2. Check siglen size 3. Double the siglen * Check return code of wolfSSL_i2d_ECDSA_SIG() in wolfSSL_EVP_DigestSignFinal() * Add size calculations to `wolfSSL_EVP_PKEY_sign` * Add size checks to wolfSSL_EVP_PKEY_sign before writing out signature * Use wc_ecc_sig_size() to calculate ECC signature size Signed-off-by: Masashi Honma <masashi.honma@gmail.com> Co-authored-by: Juliusz Sosinowicz <juliusz@wolfssl.com>
This commit is contained in:
18
src/ssl.c
18
src/ssl.c
@ -28632,6 +28632,8 @@ int wolfSSL_RSA_sign_ex(int type, const unsigned char* m,
|
|||||||
unsigned int mLen, unsigned char* sigRet,
|
unsigned int mLen, unsigned char* sigRet,
|
||||||
unsigned int* sigLen, WOLFSSL_RSA* rsa, int flag)
|
unsigned int* sigLen, WOLFSSL_RSA* rsa, int flag)
|
||||||
{
|
{
|
||||||
|
if (sigLen != NULL)
|
||||||
|
*sigLen = RSA_MAX_SIZE / CHAR_BIT; /* No size checking in this API */
|
||||||
return wolfSSL_RSA_sign_generic_padding(type, m, mLen, sigRet, sigLen,
|
return wolfSSL_RSA_sign_generic_padding(type, m, mLen, sigRet, sigLen,
|
||||||
rsa, flag, RSA_PKCS1_PADDING);
|
rsa, flag, RSA_PKCS1_PADDING);
|
||||||
}
|
}
|
||||||
@ -28710,6 +28712,10 @@ int wolfSSL_RSA_sign_generic_padding(int type, const unsigned char* m,
|
|||||||
if (outLen == 0) {
|
if (outLen == 0) {
|
||||||
WOLFSSL_MSG("Bad RSA size");
|
WOLFSSL_MSG("Bad RSA size");
|
||||||
}
|
}
|
||||||
|
else if (outLen > *sigLen) {
|
||||||
|
WOLFSSL_MSG("Output buffer too small");
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
else if (wc_InitRng(tmpRNG) == 0) {
|
else if (wc_InitRng(tmpRNG) == 0) {
|
||||||
rng = tmpRNG;
|
rng = tmpRNG;
|
||||||
initTmpRng = 1;
|
initTmpRng = 1;
|
||||||
@ -28842,7 +28848,7 @@ int wolfSSL_RSA_verify_ex(int type, const unsigned char* m,
|
|||||||
int ret = WOLFSSL_FAILURE;
|
int ret = WOLFSSL_FAILURE;
|
||||||
unsigned char *sigRet = NULL;
|
unsigned char *sigRet = NULL;
|
||||||
unsigned char *sigDec = NULL;
|
unsigned char *sigDec = NULL;
|
||||||
unsigned int len = 0;
|
unsigned int len = sigLen;
|
||||||
int verLen;
|
int verLen;
|
||||||
#if (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && \
|
#if (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && \
|
||||||
FIPS_VERSION_GE(5,1))) && !defined(HAVE_SELFTEST)
|
FIPS_VERSION_GE(5,1))) && !defined(HAVE_SELFTEST)
|
||||||
@ -43113,7 +43119,7 @@ int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from,
|
|||||||
|
|
||||||
if (rsa == NULL || rsa->internal == NULL || from == NULL) {
|
if (rsa == NULL || rsa->internal == NULL || from == NULL) {
|
||||||
WOLFSSL_MSG("Bad function arguments");
|
WOLFSSL_MSG("Bad function arguments");
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
|
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
|
||||||
@ -43133,7 +43139,7 @@ int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WOLFSSL_MSG("RSA_public_decrypt unsupported padding");
|
WOLFSSL_MSG("RSA_public_decrypt unsupported padding");
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -43142,7 +43148,7 @@ int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from,
|
|||||||
|
|
||||||
if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
|
if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) {
|
||||||
WOLFSSL_MSG("SetRsaInternal failed");
|
WOLFSSL_MSG("SetRsaInternal failed");
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43159,14 +43165,14 @@ int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WOLFSSL_MSG("RSA_public_decrypt pad type not supported in FIPS");
|
WOLFSSL_MSG("RSA_public_decrypt pad type not supported in FIPS");
|
||||||
ret = WOLFSSL_FAILURE;
|
ret = WOLFSSL_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WOLFSSL_LEAVE("RSA_public_decrypt", ret);
|
WOLFSSL_LEAVE("RSA_public_decrypt", ret);
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
ret = WOLFSSL_FAILURE;
|
ret = WOLFSSL_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
190
tests/api.c
190
tests/api.c
@ -47011,73 +47011,163 @@ static void test_wolfSSL_EVP_PKEY_encrypt(void)
|
|||||||
printf(resultFmt, passed);
|
printf(resultFmt, passed);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static void test_wolfSSL_EVP_PKEY_sign(void)
|
static void test_wolfSSL_EVP_PKEY_sign_verify(void)
|
||||||
{
|
{
|
||||||
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
|
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||||
!defined(HAVE_FAST_RSA) && !defined(HAVE_SELFTEST)
|
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
|
||||||
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
|
WOLFSSL_DSA* dsa = NULL;
|
||||||
WOLFSSL_RSA* rsa = NULL;
|
#endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
|
||||||
WOLFSSL_EVP_PKEY* pkey = NULL;
|
WOLFSSL_EVP_PKEY* pkey = NULL;
|
||||||
WOLFSSL_EVP_PKEY_CTX* ctx = NULL;
|
WOLFSSL_EVP_PKEY_CTX* ctx = NULL;
|
||||||
|
WOLFSSL_EVP_PKEY_CTX* ctx_verify = NULL;
|
||||||
const char* in = "What is easy to do is easy not to do.";
|
const char* in = "What is easy to do is easy not to do.";
|
||||||
size_t inlen = XSTRLEN(in);
|
size_t inlen = XSTRLEN(in);
|
||||||
byte hash[SHA256_DIGEST_LENGTH] = {0};
|
byte hash[SHA256_DIGEST_LENGTH] = {0};
|
||||||
SHA256_CTX c;
|
SHA256_CTX c;
|
||||||
byte* sig = NULL;
|
byte* sig = NULL;
|
||||||
byte* sigVerify = NULL;
|
byte* sigVerify = NULL;
|
||||||
size_t siglen = 0;
|
size_t siglen;
|
||||||
size_t rsaKeySz = 2048/8; /* Bytes */
|
size_t siglenOnlyLen;
|
||||||
|
size_t keySz = 2048/8; /* Bytes */
|
||||||
printf(testingFmt, "wolfSSL_EVP_PKEY_sign()");
|
int encs[3] = {0};
|
||||||
sig = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
|
||||||
AssertNotNull(sig);
|
!defined(HAVE_FAST_RSA) && !defined(HAVE_SELFTEST)
|
||||||
XMEMSET(sig, 0, rsaKeySz);
|
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
|
||||||
AssertNotNull(sigVerify = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
|
encs[0] = EVP_PKEY_RSA;
|
||||||
XMEMSET(sigVerify, 0, rsaKeySz);
|
#endif
|
||||||
|
#endif
|
||||||
/* Generate hash */
|
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
|
||||||
SHA256_Init(&c);
|
encs[1] = EVP_PKEY_DSA;
|
||||||
SHA256_Update(&c, in, inlen);
|
#endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
|
||||||
SHA256_Final(hash, &c);
|
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
|
||||||
#ifdef WOLFSSL_SMALL_STACK_CACHE
|
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
|
||||||
/* workaround for small stack cache case */
|
encs[2] = EVP_PKEY_EC;
|
||||||
wc_Sha256Free((wc_Sha256*)&c);
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL));
|
printf(testingFmt, "wolfSSL_EVP_PKEY_sign_verify()");
|
||||||
AssertNotNull(pkey = wolfSSL_EVP_PKEY_new());
|
AssertNotNull(sig =
|
||||||
AssertIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS);
|
(byte*)XMALLOC(keySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
|
||||||
AssertNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
|
AssertNotNull(sigVerify =
|
||||||
AssertIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
|
(byte*)XMALLOC(keySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
|
||||||
AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING),
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (encs[i] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
siglen = keySz;
|
||||||
|
XMEMSET(sig, 0, keySz);
|
||||||
|
XMEMSET(sigVerify, 0, keySz);
|
||||||
|
|
||||||
|
/* Generate hash */
|
||||||
|
SHA256_Init(&c);
|
||||||
|
SHA256_Update(&c, in, inlen);
|
||||||
|
SHA256_Final(hash, &c);
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK_CACHE
|
||||||
|
/* workaround for small stack cache case */
|
||||||
|
wc_Sha256Free((wc_Sha256*)&c);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Generate key */
|
||||||
|
AssertNotNull(pkey = EVP_PKEY_new());
|
||||||
|
switch (encs[i]) {
|
||||||
|
case EVP_PKEY_RSA:
|
||||||
|
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
|
||||||
|
!defined(HAVE_FAST_RSA) && !defined(HAVE_SELFTEST)
|
||||||
|
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
|
||||||
|
{
|
||||||
|
WOLFSSL_RSA* rsa = NULL;
|
||||||
|
AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL));
|
||||||
|
AssertIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_DSA:
|
||||||
|
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
|
||||||
|
AssertNotNull(dsa = DSA_new());
|
||||||
|
AssertIntEQ(DSA_generate_parameters_ex(dsa, 2048,
|
||||||
|
NULL, 0, NULL, NULL, NULL), 1);
|
||||||
|
AssertIntEQ(DSA_generate_key(dsa), 1);
|
||||||
|
AssertIntEQ(EVP_PKEY_set1_DSA(pkey, dsa), WOLFSSL_SUCCESS);
|
||||||
|
#endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
|
||||||
|
break;
|
||||||
|
case EVP_PKEY_EC:
|
||||||
|
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
|
||||||
|
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
|
||||||
|
{
|
||||||
|
WOLFSSL_EC_KEY* ecKey = NULL;
|
||||||
|
AssertNotNull(ecKey = EC_KEY_new());
|
||||||
|
AssertIntEQ(EC_KEY_generate_key(ecKey), 1);
|
||||||
|
AssertIntEQ(
|
||||||
|
EVP_PKEY_assign_EC_KEY(pkey, ecKey), WOLFSSL_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AssertNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
|
||||||
|
AssertIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
|
||||||
|
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
|
||||||
|
!defined(HAVE_FAST_RSA) && !defined(HAVE_SELFTEST)
|
||||||
|
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
|
||||||
|
if (encs[i] == EVP_PKEY_RSA)
|
||||||
|
AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check returning only length */
|
||||||
|
AssertIntEQ(EVP_PKEY_sign(ctx, NULL, &siglenOnlyLen, hash,
|
||||||
|
SHA256_DIGEST_LENGTH), WOLFSSL_SUCCESS);
|
||||||
|
AssertIntGT(siglenOnlyLen, 0);
|
||||||
|
/* Sign data */
|
||||||
|
AssertIntEQ(EVP_PKEY_sign(ctx, sig, &siglen, hash,
|
||||||
|
SHA256_DIGEST_LENGTH), WOLFSSL_SUCCESS);
|
||||||
|
AssertIntGE(siglenOnlyLen, siglen);
|
||||||
|
|
||||||
|
/* Verify signature */
|
||||||
|
AssertNotNull(ctx_verify = EVP_PKEY_CTX_new(pkey, NULL));
|
||||||
|
AssertIntEQ(EVP_PKEY_verify_init(ctx_verify), WOLFSSL_SUCCESS);
|
||||||
|
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
|
||||||
|
!defined(HAVE_FAST_RSA) && !defined(HAVE_SELFTEST)
|
||||||
|
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
|
||||||
|
if (encs[i] == EVP_PKEY_RSA)
|
||||||
|
AssertIntEQ(
|
||||||
|
EVP_PKEY_CTX_set_rsa_padding(ctx_verify, RSA_PKCS1_PADDING),
|
||||||
WOLFSSL_SUCCESS);
|
WOLFSSL_SUCCESS);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
AssertIntEQ(EVP_PKEY_verify(
|
||||||
|
ctx_verify, sig, siglen, hash, SHA256_DIGEST_LENGTH),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
XMEMSET(hash, 0, SHA256_DIGEST_LENGTH);
|
||||||
|
AssertIntEQ(EVP_PKEY_verify(
|
||||||
|
ctx_verify, sig, siglen, hash, SHA256_DIGEST_LENGTH),
|
||||||
|
WOLFSSL_FAILURE);
|
||||||
|
EVP_PKEY_CTX_free(ctx_verify);
|
||||||
|
|
||||||
/* Sign data */
|
/* error cases */
|
||||||
AssertIntEQ(EVP_PKEY_sign(ctx, sig, &siglen, hash, SHA256_DIGEST_LENGTH),
|
siglen = keySz; /* Reset because sig size may vary slightly */
|
||||||
WOLFSSL_SUCCESS);
|
AssertIntNE(EVP_PKEY_sign_init(NULL), WOLFSSL_SUCCESS);
|
||||||
/* Verify signature.
|
AssertIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
|
||||||
EVP_PKEY_verify() doesn't exist yet, so use RSA_public_decrypt(). */
|
AssertIntNE(EVP_PKEY_sign(NULL, sig, &siglen, (byte*)in, inlen),
|
||||||
AssertIntEQ(RSA_public_decrypt((int)siglen, sig, sigVerify,
|
WOLFSSL_SUCCESS);
|
||||||
rsa, RSA_PKCS1_PADDING), SHA256_DIGEST_LENGTH);
|
AssertIntEQ(EVP_PKEY_sign(ctx, sig, &siglen, (byte*)in, inlen),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
|
||||||
AssertIntEQ(XMEMCMP(hash, sigVerify, SHA256_DIGEST_LENGTH), 0);
|
EVP_PKEY_free(pkey);
|
||||||
/* error cases */
|
#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)
|
||||||
|
DSA_free(dsa);
|
||||||
|
dsa = NULL;
|
||||||
|
#endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
AssertIntNE(EVP_PKEY_sign_init(NULL), WOLFSSL_SUCCESS);
|
|
||||||
ctx->pkey->type = EVP_PKEY_RSA;
|
|
||||||
AssertIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS);
|
|
||||||
AssertIntNE(EVP_PKEY_sign(NULL, sig, &siglen, (byte*)in, inlen),
|
|
||||||
WOLFSSL_SUCCESS);
|
|
||||||
AssertIntEQ(EVP_PKEY_sign(ctx, sig, &siglen, (byte*)in, inlen),
|
|
||||||
WOLFSSL_SUCCESS);
|
|
||||||
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
EVP_PKEY_CTX_free(ctx);
|
|
||||||
XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
XFREE(sigVerify, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(sigVerify, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
|
|
||||||
printf(resultFmt, passed);
|
printf(resultFmt, passed);
|
||||||
#endif
|
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_EVP_PKEY_rsa(void)
|
static void test_EVP_PKEY_rsa(void)
|
||||||
@ -53919,7 +54009,7 @@ void ApiTest(void)
|
|||||||
/* OpenSSL EVP_PKEY API tests */
|
/* OpenSSL EVP_PKEY API tests */
|
||||||
test_EVP_PKEY_rsa();
|
test_EVP_PKEY_rsa();
|
||||||
test_wolfSSL_EVP_PKEY_encrypt();
|
test_wolfSSL_EVP_PKEY_encrypt();
|
||||||
test_wolfSSL_EVP_PKEY_sign();
|
test_wolfSSL_EVP_PKEY_sign_verify();
|
||||||
test_EVP_PKEY_ec();
|
test_EVP_PKEY_ec();
|
||||||
test_EVP_PKEY_cmp();
|
test_EVP_PKEY_cmp();
|
||||||
/* OpenSSL error API tests */
|
/* OpenSSL error API tests */
|
||||||
|
@ -1859,13 +1859,27 @@ int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
switch (ctx->pkey->type) {
|
switch (ctx->pkey->type) {
|
||||||
|
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||||
case EVP_PKEY_RSA:
|
case EVP_PKEY_RSA:
|
||||||
ctx->op = EVP_PKEY_OP_SIGN;
|
ctx->op = EVP_PKEY_OP_SIGN;
|
||||||
ret = WOLFSSL_SUCCESS;
|
ret = WOLFSSL_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
#endif /* NO_RSA */
|
||||||
|
|
||||||
|
#ifndef NO_DSA
|
||||||
|
case EVP_PKEY_DSA:
|
||||||
|
ctx->op = EVP_PKEY_OP_SIGN;
|
||||||
|
ret = WOLFSSL_SUCCESS;
|
||||||
|
break;
|
||||||
|
#endif /* NO_DSA */
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
case EVP_PKEY_EC:
|
case EVP_PKEY_EC:
|
||||||
WOLFSSL_MSG("not implemented");
|
ctx->op = EVP_PKEY_OP_SIGN;
|
||||||
FALL_THROUGH;
|
ret = WOLFSSL_SUCCESS;
|
||||||
|
break;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = -2;
|
ret = -2;
|
||||||
}
|
}
|
||||||
@ -1882,41 +1896,208 @@ int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx)
|
|||||||
int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig,
|
int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig,
|
||||||
size_t *siglen, const unsigned char *tbs, size_t tbslen)
|
size_t *siglen, const unsigned char *tbs, size_t tbslen)
|
||||||
{
|
{
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
WOLFSSL_MSG("wolfSSL_EVP_PKEY_sign");
|
WOLFSSL_MSG("wolfSSL_EVP_PKEY_sign");
|
||||||
|
|
||||||
if (!ctx || ctx->op != EVP_PKEY_OP_SIGN || !ctx->pkey)
|
if (!ctx || ctx->op != EVP_PKEY_OP_SIGN || !ctx->pkey || !siglen)
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
|
|
||||||
(void)sig;
|
(void)sig;
|
||||||
(void)siglen;
|
(void)siglen;
|
||||||
(void)tbs;
|
(void)tbs;
|
||||||
(void)tbslen;
|
(void)tbslen;
|
||||||
(void)len;
|
|
||||||
|
|
||||||
switch (ctx->pkey->type) {
|
switch (ctx->pkey->type) {
|
||||||
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||||
case EVP_PKEY_RSA:
|
case EVP_PKEY_RSA: {
|
||||||
len = wolfSSL_RSA_private_encrypt((int)tbslen, tbs, sig,
|
int len;
|
||||||
ctx->pkey->rsa, ctx->padding);
|
unsigned int usiglen = (unsigned int)*siglen;
|
||||||
if (len < 0)
|
if (!sig) {
|
||||||
break;
|
if (!ctx->pkey->rsa)
|
||||||
else {
|
return WOLFSSL_FAILURE;
|
||||||
*siglen = len;
|
len = wc_RsaEncryptSize((RsaKey*)ctx->pkey->rsa->internal);
|
||||||
|
if (len < 0)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
*siglen = (size_t)len;
|
||||||
return WOLFSSL_SUCCESS;
|
return WOLFSSL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
/* wolfSSL_RSA_sign_generic_padding performs a check that the output
|
||||||
|
* sig buffer is large enough */
|
||||||
|
if (wolfSSL_RSA_sign_generic_padding(WC_HASH_TYPE_NONE, tbs,
|
||||||
|
(unsigned int)tbslen, sig, &usiglen, ctx->pkey->rsa, 1, ctx->padding)
|
||||||
|
!= WOLFSSL_SUCCESS)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
*siglen = (size_t)usiglen;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
#endif /* NO_RSA */
|
#endif /* NO_RSA */
|
||||||
|
|
||||||
case EVP_PKEY_EC:
|
#ifndef NO_DSA
|
||||||
WOLFSSL_MSG("not implemented");
|
case EVP_PKEY_DSA: {
|
||||||
FALL_THROUGH;
|
int bytes;
|
||||||
|
int ret;
|
||||||
|
if (!ctx->pkey->dsa)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
bytes = wolfSSL_BN_num_bytes(ctx->pkey->dsa->q);
|
||||||
|
if (bytes == WOLFSSL_FAILURE)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
bytes *= 2;
|
||||||
|
if (!sig) {
|
||||||
|
*siglen = bytes;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
if ((int)*siglen < bytes)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
ret = wolfSSL_DSA_do_sign(tbs, sig, ctx->pkey->dsa);
|
||||||
|
/* wolfSSL_DSA_do_sign() can return WOLFSSL_FATAL_ERROR */
|
||||||
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
|
return ret;
|
||||||
|
if (bytes == WOLFSSL_FAILURE)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
*siglen = bytes;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* NO_DSA */
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
case EVP_PKEY_EC: {
|
||||||
|
int ret;
|
||||||
|
WOLFSSL_ECDSA_SIG *ecdsaSig;
|
||||||
|
if (!sig) {
|
||||||
|
WOLFSSL_EC_KEY *key = ctx->pkey->ecc;
|
||||||
|
ecc_key* eckey;
|
||||||
|
if (!key)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
/* set internal key if not done */
|
||||||
|
if (key->inSet == 0 && SetECKeyInternal(key) != WOLFSSL_SUCCESS)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
eckey = (ecc_key*)ctx->pkey->ecc->internal;
|
||||||
|
if (!eckey)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
ret = wc_ecc_sig_size(eckey);
|
||||||
|
if (ret == 0)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
*siglen = ret;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
ecdsaSig = wolfSSL_ECDSA_do_sign(tbs, (int)tbslen, ctx->pkey->ecc);
|
||||||
|
if (ecdsaSig == NULL)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, NULL);
|
||||||
|
if (ret == 0 || ret > (int)*siglen) {
|
||||||
|
wolfSSL_ECDSA_SIG_free(ecdsaSig);
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig);
|
||||||
|
wolfSSL_ECDSA_SIG_free(ecdsaSig);
|
||||||
|
if (ret == 0)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
*siglen = ret;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* wolfSSL_EVP_PKEY_verify_init - initializes a public key algorithm context for
|
||||||
|
* a verification operation.
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. In particular
|
||||||
|
* a return value of -2 indicates the operation is not supported by the public
|
||||||
|
* key algorithm.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int wolfSSL_EVP_PKEY_verify_init(WOLFSSL_EVP_PKEY_CTX *ctx)
|
||||||
|
{
|
||||||
|
WOLFSSL_MSG("wolfSSL_EVP_PKEY_verify_init");
|
||||||
|
|
||||||
|
if (!ctx || !ctx->pkey)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
|
||||||
|
switch (ctx->pkey->type) {
|
||||||
|
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||||
|
case EVP_PKEY_RSA:
|
||||||
|
ctx->op = EVP_PKEY_OP_VERIFY;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
#endif /* NO_RSA */
|
||||||
|
|
||||||
|
#ifndef NO_DSA
|
||||||
|
case EVP_PKEY_DSA:
|
||||||
|
ctx->op = EVP_PKEY_OP_VERIFY;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
#endif /* NO_DSA */
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
case EVP_PKEY_EC:
|
||||||
|
ctx->op = EVP_PKEY_OP_VERIFY;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* wolfSSL_EVP_PKEY_verify - verifies a signature using ctx
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. In particular
|
||||||
|
* a return value of -2 indicates the operation is not supported by the public
|
||||||
|
* key algorithm.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int wolfSSL_EVP_PKEY_verify(WOLFSSL_EVP_PKEY_CTX *ctx, const unsigned char *sig,
|
||||||
|
size_t siglen, const unsigned char *tbs,
|
||||||
|
size_t tbslen)
|
||||||
|
{
|
||||||
|
WOLFSSL_MSG("wolfSSL_EVP_PKEY_verify");
|
||||||
|
|
||||||
|
if (!ctx || ctx->op != EVP_PKEY_OP_VERIFY || !ctx->pkey)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
|
||||||
|
switch (ctx->pkey->type) {
|
||||||
|
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||||
|
case EVP_PKEY_RSA:
|
||||||
|
return wolfSSL_RSA_verify_ex(WC_HASH_TYPE_NONE, tbs,
|
||||||
|
(unsigned int)tbslen, sig, (unsigned int)siglen, ctx->pkey->rsa,
|
||||||
|
ctx->padding);
|
||||||
|
#endif /* NO_RSA */
|
||||||
|
|
||||||
|
#ifndef NO_DSA
|
||||||
|
case EVP_PKEY_DSA: {
|
||||||
|
int dsacheck = 0;
|
||||||
|
if (wolfSSL_DSA_do_verify(tbs, (unsigned char *)sig, ctx->pkey->dsa,
|
||||||
|
&dsacheck) != WOLFSSL_SUCCESS || dsacheck != 1)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* NO_DSA */
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
case EVP_PKEY_EC: {
|
||||||
|
int ret;
|
||||||
|
WOLFSSL_ECDSA_SIG *ecdsaSig = wolfSSL_d2i_ECDSA_SIG(
|
||||||
|
NULL, (const unsigned char **)&sig, (long)siglen);
|
||||||
|
if (ecdsaSig == NULL)
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
ret = wolfSSL_ECDSA_do_verify(tbs, (int)tbslen, ecdsaSig,
|
||||||
|
ctx->pkey->ecc);
|
||||||
|
wolfSSL_ECDSA_SIG_free(ecdsaSig);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the size in bits for WOLFSSL_EVP_PKEY key
|
/* Get the size in bits for WOLFSSL_EVP_PKEY key
|
||||||
*
|
*
|
||||||
* pkey WOLFSSL_EVP_PKEY structure to get key size of
|
* pkey WOLFSSL_EVP_PKEY structure to get key size of
|
||||||
@ -2711,14 +2892,18 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret,
|
|||||||
}
|
}
|
||||||
#endif /* NO_RSA */
|
#endif /* NO_RSA */
|
||||||
#ifndef NO_DSA
|
#ifndef NO_DSA
|
||||||
case EVP_PKEY_DSA:
|
case EVP_PKEY_DSA: {
|
||||||
if (wolfSSL_DSA_do_sign(md, sigret, pkey->dsa) == WOLFSSL_SUCCESS) {
|
int bytes;
|
||||||
*siglen = wolfSSL_BN_num_bytes(pkey->dsa->q);
|
ret = wolfSSL_DSA_do_sign(md, sigret, pkey->dsa);
|
||||||
return WOLFSSL_SUCCESS;
|
/* wolfSSL_DSA_do_sign() can return WOLFSSL_FATAL_ERROR */
|
||||||
}
|
if (ret != WOLFSSL_SUCCESS)
|
||||||
else {
|
return ret;
|
||||||
|
bytes = wolfSSL_BN_num_bytes(pkey->dsa->q);
|
||||||
|
if (bytes == WOLFSSL_FAILURE || (int)*siglen < bytes * 2)
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
}
|
*siglen = bytes * 2;
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
case EVP_PKEY_EC:
|
case EVP_PKEY_EC:
|
||||||
WOLFSSL_MSG("not implemented");
|
WOLFSSL_MSG("not implemented");
|
||||||
@ -3170,7 +3355,7 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig,
|
|||||||
switch (ctx->pctx->pkey->type) {
|
switch (ctx->pctx->pkey->type) {
|
||||||
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||||
case EVP_PKEY_RSA: {
|
case EVP_PKEY_RSA: {
|
||||||
unsigned int sigSz;
|
unsigned int sigSz = (unsigned int)*siglen;
|
||||||
int nid;
|
int nid;
|
||||||
const WOLFSSL_EVP_MD *md = wolfSSL_EVP_MD_CTX_md(ctx);
|
const WOLFSSL_EVP_MD *md = wolfSSL_EVP_MD_CTX_md(ctx);
|
||||||
if (md == NULL)
|
if (md == NULL)
|
||||||
@ -3188,13 +3373,17 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig,
|
|||||||
|
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
case EVP_PKEY_EC: {
|
case EVP_PKEY_EC: {
|
||||||
|
int len;
|
||||||
WOLFSSL_ECDSA_SIG *ecdsaSig;
|
WOLFSSL_ECDSA_SIG *ecdsaSig;
|
||||||
ecdsaSig = wolfSSL_ECDSA_do_sign(digest, hashLen,
|
ecdsaSig = wolfSSL_ECDSA_do_sign(digest, hashLen,
|
||||||
ctx->pctx->pkey->ecc);
|
ctx->pctx->pkey->ecc);
|
||||||
if (ecdsaSig == NULL)
|
if (ecdsaSig == NULL)
|
||||||
break;
|
break;
|
||||||
*siglen = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig);
|
len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig);
|
||||||
wolfSSL_ECDSA_SIG_free(ecdsaSig);
|
wolfSSL_ECDSA_SIG_free(ecdsaSig);
|
||||||
|
if (len == 0)
|
||||||
|
break;
|
||||||
|
*siglen = len;
|
||||||
ret = WOLFSSL_SUCCESS;
|
ret = WOLFSSL_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -376,6 +376,7 @@ enum {
|
|||||||
#define NID_dsa EVP_PKEY_DSA
|
#define NID_dsa EVP_PKEY_DSA
|
||||||
|
|
||||||
#define EVP_PKEY_OP_SIGN (1 << 3)
|
#define EVP_PKEY_OP_SIGN (1 << 3)
|
||||||
|
#define EVP_PKEY_OP_VERIFY (1 << 5)
|
||||||
#define EVP_PKEY_OP_ENCRYPT (1 << 6)
|
#define EVP_PKEY_OP_ENCRYPT (1 << 6)
|
||||||
#define EVP_PKEY_OP_DECRYPT (1 << 7)
|
#define EVP_PKEY_OP_DECRYPT (1 << 7)
|
||||||
#define EVP_PKEY_OP_DERIVE (1 << 8)
|
#define EVP_PKEY_OP_DERIVE (1 << 8)
|
||||||
@ -593,6 +594,9 @@ WOLFSSL_API const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PK
|
|||||||
WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx);
|
WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx);
|
||||||
WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx,
|
WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx,
|
||||||
unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen);
|
unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen);
|
||||||
|
WOLFSSL_API int wolfSSL_EVP_PKEY_verify_init(WOLFSSL_EVP_PKEY_CTX *ctx);
|
||||||
|
WOLFSSL_API int wolfSSL_EVP_PKEY_verify(WOLFSSL_EVP_PKEY_CTX *ctx, const unsigned char *sig,
|
||||||
|
size_t siglen, const unsigned char *tbs, size_t tbslen);
|
||||||
WOLFSSL_API int wolfSSL_EVP_PKEY_paramgen_init(WOLFSSL_EVP_PKEY_CTX *ctx);
|
WOLFSSL_API int wolfSSL_EVP_PKEY_paramgen_init(WOLFSSL_EVP_PKEY_CTX *ctx);
|
||||||
WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(WOLFSSL_EVP_PKEY_CTX *ctx,
|
WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(WOLFSSL_EVP_PKEY_CTX *ctx,
|
||||||
int nid);
|
int nid);
|
||||||
@ -948,6 +952,8 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
|
|||||||
#define EVP_MD_CTX_copy_ex wolfSSL_EVP_MD_CTX_copy_ex
|
#define EVP_MD_CTX_copy_ex wolfSSL_EVP_MD_CTX_copy_ex
|
||||||
#define EVP_PKEY_sign_init wolfSSL_EVP_PKEY_sign_init
|
#define EVP_PKEY_sign_init wolfSSL_EVP_PKEY_sign_init
|
||||||
#define EVP_PKEY_sign wolfSSL_EVP_PKEY_sign
|
#define EVP_PKEY_sign wolfSSL_EVP_PKEY_sign
|
||||||
|
#define EVP_PKEY_verify_init wolfSSL_EVP_PKEY_verify_init
|
||||||
|
#define EVP_PKEY_verify wolfSSL_EVP_PKEY_verify
|
||||||
#define EVP_PKEY_paramgen_init wolfSSL_EVP_PKEY_paramgen_init
|
#define EVP_PKEY_paramgen_init wolfSSL_EVP_PKEY_paramgen_init
|
||||||
#define EVP_PKEY_CTX_set_ec_param_enc wolfSSL_EVP_PKEY_CTX_set_ec_param_enc
|
#define EVP_PKEY_CTX_set_ec_param_enc wolfSSL_EVP_PKEY_CTX_set_ec_param_enc
|
||||||
#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid
|
#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid
|
||||||
|
Reference in New Issue
Block a user