From 330a7048c7151e3dbe5b1991187161fd2959bfd4 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 10 Sep 2018 12:18:25 +1000 Subject: [PATCH 1/3] Add more compatability APIs. d2i_ECDSA_SIG, i2d_ECDSA_SIG, EVP_DigestVerifyInit, EVP_DigestVerifyUpdate, EVP_DigestVerifyFinal, EVP_PKEY_id, PEM_read_bio_PUBKEY --- src/ssl.c | 222 +++++++++++++++++++++++++++++----------- tests/api.c | 101 +++++++++++++++++- wolfcrypt/src/evp.c | 166 ++++++++++++++++++++++++++++++ wolfssl/openssl/ecdsa.h | 16 ++- wolfssl/openssl/evp.h | 35 +++++-- wolfssl/openssl/pem.h | 7 +- 6 files changed, 473 insertions(+), 74 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index d448e6bbc..045f4aa2f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -27432,6 +27432,58 @@ int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen, return WOLFSSL_SUCCESS; } + +WOLFSSL_ECDSA_SIG *wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG **sig, + const unsigned char **pp, long len) +{ + WOLFSSL_ECDSA_SIG *s = NULL; + + if (pp == NULL) + return NULL; + + if (sig != NULL) + s = *sig; + if (s == NULL) { + s = wolfSSL_ECDSA_SIG_new(); + if (s == NULL) + return NULL; + } + + if (DecodeECC_DSA_Sig(*pp, (word32)len, (mp_int*)s->r->internal, + (mp_int*)s->s->internal) != MP_OKAY) { + if (sig == NULL || *sig == NULL) + wolfSSL_ECDSA_SIG_free(s); + return NULL; + } + + *pp += len; + if (sig != NULL) + *sig = s; + return s; +} + +int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, unsigned char **pp) +{ + word32 len; + + if (sig == NULL) + return 0; + + len = 2 + 2 + mp_leading_bit((mp_int*)sig->r->internal) + + mp_unsigned_bin_size((mp_int*)sig->r->internal) + + 2 + mp_leading_bit((mp_int*)sig->s->internal) + + mp_unsigned_bin_size((mp_int*)sig->s->internal); + if (pp != NULL) { + if (StoreECC_DSA_Sig(*pp, &len, (mp_int*)sig->r->internal, + (mp_int*)sig->s->internal) != MP_OKAY) { + len = 0; + } + else + *pp += len; + } + + return (int)len; +} /* End ECDSA_SIG */ /* Start ECDH */ @@ -27901,42 +27953,32 @@ int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x) #endif /* #ifndef NO_DSA */ - -WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, - WOLFSSL_EVP_PKEY** key, pem_password_cb* cb, void* pass) +static int pem_read_bio_key(WOLFSSL_BIO* bio, pem_password_cb* cb, void* pass, + int keyType, int* eccFlag, DerBuffer** der) { - WOLFSSL_EVP_PKEY* pkey = NULL; #ifdef WOLFSSL_SMALL_STACK - EncryptedInfo* info; + EncryptedInfo* info = NULL; #else EncryptedInfo info[1]; #endif /* WOLFSSL_SMALL_STACK */ pem_password_cb* localCb = cb; - DerBuffer* der = NULL; char* mem = NULL; int memSz; int ret; - int eccFlag = 0; - - WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey"); - - if (bio == NULL) { - return pkey; - } if ((ret = wolfSSL_BIO_pending(bio)) > 0) { memSz = ret; mem = (char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_OPENSSL); if (mem == NULL) { WOLFSSL_MSG("Memory error"); - return NULL; + ret = MEMORY_E; } - - if ((ret = wolfSSL_BIO_read(bio, mem, memSz)) <= 0) { - WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", ret); - XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL); - return NULL; + if (ret >= 0) { + if ((ret = wolfSSL_BIO_read(bio, mem, memSz)) <= 0) { + XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL); + ret = MEMORY_E; + } } } else if (bio->type == WOLFSSL_BIO_FILE) { @@ -27947,10 +27989,10 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, memSz = 0; if (tmp == NULL) { WOLFSSL_MSG("Memory error"); - return NULL; + ret = MEMORY_E; } - while ((sz = wolfSSL_BIO_read(bio, tmp, sz)) > 0) { + while (ret >= 0 && (sz = wolfSSL_BIO_read(bio, tmp, sz)) > 0) { if (memSz + sz < 0) { /* sanity check */ break; @@ -27960,7 +28002,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, if (mem == NULL) { WOLFSSL_MSG("Memory error"); XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL); - return NULL; + ret = MEMORY_E; + break; } XMEMCPY(mem + idx, tmp, sz); memSz += sz; @@ -27973,57 +28016,80 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, if (mem != NULL) { XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL); } - return NULL; + ret = BUFFER_E; } } else { WOLFSSL_MSG("No data to read from bio"); - return NULL; + ret = NOT_COMPILED_IN; } #ifdef WOLFSSL_SMALL_STACK - info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (info == NULL) { - WOLFSSL_MSG("Error getting memory for EncryptedInfo structure"); - XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL); - return NULL; + if (ret >= 0) { + info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (info == NULL) { + WOLFSSL_MSG("Error getting memory for EncryptedInfo structure"); + XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL); + ret = MEMORY_E; + } } #endif - XMEMSET(info, 0, sizeof(EncryptedInfo)); - info->passwd_cb = localCb; - info->passwd_userdata = pass; - ret = PemToDer((const unsigned char*)mem, memSz, PRIVATEKEY_TYPE, &der, - NULL, info, &eccFlag); + if (ret >= 0) { + XMEMSET(info, 0, sizeof(EncryptedInfo)); + info->passwd_cb = localCb; + info->passwd_userdata = pass; + ret = PemToDer((const unsigned char*)mem, memSz, keyType, der, + NULL, info, eccFlag); - if (ret < 0) { - WOLFSSL_MSG("Bad Pem To Der"); + if (ret < 0) { + WOLFSSL_MSG("Bad Pem To Der"); + } + else { + /* write left over data back to bio */ + if ((memSz - (int)info->consumed) > 0 && + bio->type != WOLFSSL_BIO_FILE) { + if (wolfSSL_BIO_write(bio, mem + (int)info->consumed, + memSz - (int)info->consumed) <= 0) { + WOLFSSL_MSG("Unable to advance bio read pointer"); + } + } + } } - else { + +#ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL); + + return ret; +} + +WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY** key, pem_password_cb* cb, void* pass) +{ + WOLFSSL_EVP_PKEY* pkey = NULL; + DerBuffer* der = NULL; + int eccFlag = 0; + + WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey"); + + if (bio == NULL) + return pkey; + + if (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE, &eccFlag, &der) >= 0) { int type; const unsigned char* ptr = der->buffer; - /* write left over data back to bio */ - if ((memSz - (int)info->consumed) > 0 && - bio->type != WOLFSSL_BIO_FILE) { - if (wolfSSL_BIO_write(bio, mem + (int)info->consumed, - memSz - (int)info->consumed) <= 0) { - WOLFSSL_MSG("Unable to advance bio read pointer"); - } - } - - if (eccFlag) { + if (eccFlag) type = EVP_PKEY_EC; - } - else { + else type = EVP_PKEY_RSA; - } /* handle case where reuse is attempted */ - if (key != NULL && *key != NULL) { + if (key != NULL && *key != NULL) pkey = *key; - } wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length); if (pkey == NULL) { @@ -28031,17 +28097,49 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, } } -#ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL); FreeDer(&der); - if (key != NULL) { + if (key != NULL && pkey != NULL) *key = pkey; + + WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", 0); + + return pkey; +} + +WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY **key, + pem_password_cb *cb, void *pass) +{ + WOLFSSL_EVP_PKEY* pkey = NULL; + DerBuffer* der = NULL; + int eccFlag = 0; + + WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY"); + + if (bio == NULL) + return pkey; + + if (pem_read_bio_key(bio, cb, pass, PUBLICKEY_TYPE, &eccFlag, &der) >= 0) { + unsigned char* ptr = der->buffer; + + /* handle case where reuse is attempted */ + if (key != NULL && *key != NULL) + pkey = *key; + + wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length); + if (pkey == NULL) { + WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY"); + } } + FreeDer(&der); + + if (key != NULL && pkey != NULL) + *key = pkey; + + WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", 0); + return pkey; } @@ -28108,6 +28206,12 @@ int wolfSSL_EVP_PKEY_type(int type) } +int wolfSSL_EVP_PKEY_id(const EVP_PKEY *pkey) +{ + return pkey->type; +} + + int wolfSSL_EVP_PKEY_base_id(const EVP_PKEY *pkey) { return EVP_PKEY_type(pkey->type); diff --git a/tests/api.c b/tests/api.c index dc5779a42..72e0b936f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -313,6 +313,9 @@ #ifndef NO_DES3 #include #endif +#ifdef HAVE_ECC + #include +#endif #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \ @@ -1293,6 +1296,40 @@ static void test_wolfSSL_EC(void) } #endif +# if defined(OPENSSL_EXTRA) +static void test_wolfSSL_ECDSA_SIG(void) +{ +#ifdef HAVE_ECC + WOLFSSL_ECDSA_SIG* sig = NULL; + WOLFSSL_ECDSA_SIG* sig2 = NULL; + const unsigned char* cp; + unsigned char* p; + unsigned char outSig[8]; + unsigned char sigData[8] = + { 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01 }; + + AssertNull(wolfSSL_d2i_ECDSA_SIG(NULL, NULL, sizeof(sigData))); + cp = sigData; + AssertNotNull((sig = wolfSSL_d2i_ECDSA_SIG(NULL, &cp, sizeof(sigData)))); + AssertIntEQ((cp == sigData + 8), 1); + cp = sigData; + AssertNull(wolfSSL_d2i_ECDSA_SIG(&sig, NULL, sizeof(sigData))); + AssertNotNull((sig2 = wolfSSL_d2i_ECDSA_SIG(&sig, &cp, sizeof(sigData)))); + AssertIntEQ((sig == sig2), 1); + cp = outSig; + + p = outSig; + AssertIntEQ(wolfSSL_i2d_ECDSA_SIG(NULL, &p), 0); + AssertIntEQ(wolfSSL_i2d_ECDSA_SIG(NULL, NULL), 0); + AssertIntEQ(wolfSSL_i2d_ECDSA_SIG(sig, NULL), 8); + AssertIntEQ(wolfSSL_i2d_ECDSA_SIG(sig, &p), sizeof(sigData)); + AssertIntEQ((p == outSig + 8), 1); + AssertIntEQ(XMEMCMP(sigData, outSig, 8), 0); + + wolfSSL_ECDSA_SIG_free(sig); +#endif /* HAVE_ECC */ +} +#endif /* OPENSSL_EXTRA */ #include /*----------------------------------------------------------------------------* @@ -16477,9 +16514,9 @@ static void test_wolfSSL_PEM_PrivateKey(void) printf(resultFmt, passed); - (void)server_key; (void)bio; (void)pkey; + (void)server_key; #endif /* OPENSSL_EXTRA && !NO_CERTS && !NO_RSA && USE_CERT_BUFFERS_2048 */ } @@ -16513,6 +16550,50 @@ static void test_wolfSSL_PEM_RSAPrivateKey(void) } +static void test_wolfSSL_PEM_PUBKEY(void) +{ +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) + BIO* bio = NULL; + EVP_PKEY* pkey = NULL; + + /* test creating new EVP_PKEY with bad arg */ + AssertNull((pkey = PEM_read_bio_PUBKEY(NULL, NULL, NULL, NULL))); + + /* test loading ECC key using BIO */ +#if defined(HAVE_ECC) && !defined(NO_FILESYSTEM) + { + XFILE file; + const char* fname = "./certs/ecc-client-keyPub.pem"; + size_t sz; + byte* buf; + + file = XFOPEN(fname, "rb"); + AssertTrue((file != XBADFILE)); + XFSEEK(file, 0, XSEEK_END); + sz = XFTELL(file); + XREWIND(file); + AssertNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)); + if (buf) + AssertIntEQ(XFREAD(buf, 1, sz, file), sz); + XFCLOSE(file); + + /* Test using BIO new mem and loading PEM private key */ + AssertNotNull(bio = BIO_new_mem_buf(buf, (int)sz)); + AssertNotNull((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL))); + XFREE(buf, NULL, DYNAMIC_TYPE_FILE); + BIO_free(bio); + bio = NULL; + EVP_PKEY_free(pkey); + pkey = NULL; + } +#endif + + (void)bio; + (void)pkey; +#endif +} + + static void test_wolfSSL_tmp_dh(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ @@ -16678,6 +16759,13 @@ static void test_wolfSSL_EVP_MD_hmac_signing(void) AssertIntEQ(XMEMCMP(testResult, check, sizeof(testResult)), 0); AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, key), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, + (unsigned int)XSTRLEN(testData)), + 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, testResult, checkSz), 1); + wolfSSL_EVP_MD_CTX_init(&mdCtx); AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), NULL, key), 1); @@ -16691,6 +16779,15 @@ static void test_wolfSSL_EVP_MD_hmac_signing(void) AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1); AssertIntEQ((int)checkSz,(int)sizeof(testResult)); AssertIntEQ(XMEMCMP(testResult, check, sizeof(testResult)), 0); + + AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, key), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, 4), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData + 4, + (unsigned int)XSTRLEN(testData) - 4), + 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, testResult, checkSz), 1); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); wolfSSL_EVP_PKEY_free(key); @@ -20855,6 +20952,7 @@ void ApiTest(void) test_wolfSSL_private_keys(); test_wolfSSL_PEM_PrivateKey(); test_wolfSSL_PEM_RSAPrivateKey(); + test_wolfSSL_PEM_PUBKEY(); test_wolfSSL_tmp_dh(); test_wolfSSL_ctrl(); test_wolfSSL_EVP_PKEY_new_mac_key(); @@ -21079,6 +21177,7 @@ void ApiTest(void) /*wolfSSS_EVP_get_cipherbynid test*/ test_wolfSSL_EVP_get_cipherbynid(); test_wolfSSL_EC(); + test_wolfSSL_ECDSA_SIG(); #endif #ifdef HAVE_HASHDRBG diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index a2bfaa1d9..6d4c8377a 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1290,6 +1290,172 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, ForceZero(digest, sizeof(digest)); return ret; } + +int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx, + WOLFSSL_EVP_PKEY_CTX **pctx, + const WOLFSSL_EVP_MD *type, + WOLFSSL_ENGINE *e, + WOLFSSL_EVP_PKEY *pkey) +{ + int hashType; + const unsigned char* key; + size_t keySz; + + /* Unused parameters */ + (void)pctx; + (void)e; + + WOLFSSL_ENTER("EVP_DigestVerifyInit"); + + if (ctx == NULL || type == NULL || pkey == NULL) + return BAD_FUNC_ARG; + +#ifdef WOLFSSL_ASYNC_CRYPT + /* compile-time validation of ASYNC_CTX_SIZE */ + typedef char async_test[WC_ASYNC_DEV_SIZE >= sizeof(WC_ASYNC_DEV) ? + 1 : -1]; + (void)sizeof(async_test); +#endif + + if (XSTRNCMP(type, "SHA256", 6) == 0) { + hashType = WC_SHA256; + } +#ifdef WOLFSSL_SHA224 + else if (XSTRNCMP(type, "SHA224", 6) == 0) { + hashType = WC_SHA224; + } +#endif +#ifdef WOLFSSL_SHA384 + else if (XSTRNCMP(type, "SHA384", 6) == 0) { + hashType = WC_SHA384; + } +#endif +#ifdef WOLFSSL_SHA512 + else if (XSTRNCMP(type, "SHA512", 6) == 0) { + hashType = WC_SHA512; + } +#endif +#ifndef NO_MD5 + else if (XSTRNCMP(type, "MD5", 3) == 0) { + hashType = WC_MD5; + } +#endif +#ifndef NO_SHA + /* has to be last since would pick or 224, 256, 384, or 512 too */ + else if (XSTRNCMP(type, "SHA", 3) == 0) { + hashType = WC_SHA; + } +#endif /* NO_SHA */ + else + return BAD_FUNC_ARG; + + key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz); + + if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; + + if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0) + return WOLFSSL_FAILURE; + + ctx->macType = NID_hmac & 0xFF; + + return WOLFSSL_SUCCESS; +} + + +int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, + const void *d, size_t cnt) +{ + WOLFSSL_ENTER("EVP_DigestVerifyUpdate"); + + if (ctx->macType != (NID_hmac & 0xFF)) + return WOLFSSL_FAILURE; + + if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, (word32)cnt) != 0) + return WOLFSSL_FAILURE; + + return WOLFSSL_SUCCESS; +} + + +int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, + const unsigned char *sig, size_t siglen) +{ + unsigned char digest[WC_MAX_DIGEST_SIZE]; + Hmac hmacCopy; + size_t hashLen; + int ret; + + WOLFSSL_ENTER("EVP_DigestVerifyFinal"); + + if (ctx == NULL || sig == NULL) + return WOLFSSL_FAILURE; + + if (ctx->macType != (NID_hmac & 0xFF)) + return WOLFSSL_FAILURE; + + switch (ctx->hash.hmac.macType) { + #ifndef NO_MD5 + case WC_MD5: + hashLen = WC_MD5_DIGEST_SIZE; + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + hashLen = WC_SHA_DIGEST_SIZE; + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + hashLen = WC_SHA224_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SHA224 */ + + #ifndef NO_SHA256 + case WC_SHA256: + hashLen = WC_SHA256_DIGEST_SIZE; + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + hashLen = WC_SHA384_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SHA384 */ + case WC_SHA512: + hashLen = WC_SHA512_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef HAVE_BLAKE2 + case BLAKE2B_ID: + hashLen = BLAKE2B_OUTBYTES; + break; + #endif /* HAVE_BLAKE2 */ + + default: + return 0; + } + + if (siglen != hashLen) + return WOLFSSL_FAILURE; + + XMEMCPY(&hmacCopy, &ctx->hash.hmac, sizeof(hmacCopy)); + ret = wc_HmacFinal(&hmacCopy, digest) == 0; + if (ret == 1) { + if (XMEMCMP(sig, digest, siglen) == 0) + ret = WOLFSSL_SUCCESS; + else + ret = WOLFSSL_FAILURE; + } + + ForceZero(&hmacCopy, sizeof(hmacCopy)); + ForceZero(digest, sizeof(digest)); + return ret; +} #endif /* WOLFSSL_EVP_INCLUDED */ #if defined(OPENSSL_EXTRA) && !defined(NO_PWDBASED) && !defined(NO_SHA) diff --git a/wolfssl/openssl/ecdsa.h b/wolfssl/openssl/ecdsa.h index 8983c9211..23d4cd1c8 100644 --- a/wolfssl/openssl/ecdsa.h +++ b/wolfssl/openssl/ecdsa.h @@ -53,10 +53,18 @@ WOLFSSL_API int wolfSSL_ECDSA_do_verify(const unsigned char *dgst, const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *eckey); -#define ECDSA_SIG_free wolfSSL_ECDSA_SIG_free -#define ECDSA_SIG_new wolfSSL_ECDSA_SIG_new -#define ECDSA_do_sign wolfSSL_ECDSA_do_sign -#define ECDSA_do_verify wolfSSL_ECDSA_do_verify +WOLFSSL_API WOLFSSL_ECDSA_SIG *wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG **sig, + const unsigned char **pp, + long len); +WOLFSSL_API int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, + unsigned char **pp); + +#define ECDSA_SIG_free wolfSSL_ECDSA_SIG_free +#define ECDSA_SIG_new wolfSSL_ECDSA_SIG_new +#define ECDSA_do_sign wolfSSL_ECDSA_do_sign +#define ECDSA_do_verify wolfSSL_ECDSA_do_verify +#define d2i_ECDSA_SIG wolfSSL_d2i_ECDSA_SIG +#define i2d_ECDSA_SIG wolfSSL_i2d_ECDSA_SIG #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index a054f0473..d5259a550 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -269,6 +269,18 @@ WOLFSSL_API int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, WOLFSSL_API int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen); +WOLFSSL_API int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx, + WOLFSSL_EVP_PKEY_CTX **pctx, + const WOLFSSL_EVP_MD *type, + WOLFSSL_ENGINE *e, + WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, + const void *d, size_t cnt); +WOLFSSL_API int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen); + + WOLFSSL_API int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER*, const WOLFSSL_EVP_MD*, const unsigned char*, const unsigned char*, int, int, unsigned char*, @@ -364,6 +376,7 @@ WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_EVP_PKEY_new(void); WOLFSSL_API void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY*); WOLFSSL_API int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_PKEY_type(int type); +WOLFSSL_API int wolfSSL_EVP_PKEY_id(const EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_PKEY_base_id(const EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, WOLFSSL_EVP_PKEY *pkey); @@ -479,15 +492,18 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_MD_CTX_type wolfSSL_EVP_MD_CTX_type #define EVP_MD_type wolfSSL_EVP_MD_type -#define EVP_DigestInit wolfSSL_EVP_DigestInit -#define EVP_DigestInit_ex wolfSSL_EVP_DigestInit_ex -#define EVP_DigestUpdate wolfSSL_EVP_DigestUpdate -#define EVP_DigestFinal wolfSSL_EVP_DigestFinal -#define EVP_DigestFinal_ex wolfSSL_EVP_DigestFinal_ex -#define EVP_DigestSignInit wolfSSL_EVP_DigestSignInit -#define EVP_DigestSignUpdate wolfSSL_EVP_DigestSignUpdate -#define EVP_DigestSignFinal wolfSSL_EVP_DigestSignFinal -#define EVP_BytesToKey wolfSSL_EVP_BytesToKey +#define EVP_DigestInit wolfSSL_EVP_DigestInit +#define EVP_DigestInit_ex wolfSSL_EVP_DigestInit_ex +#define EVP_DigestUpdate wolfSSL_EVP_DigestUpdate +#define EVP_DigestFinal wolfSSL_EVP_DigestFinal +#define EVP_DigestFinal_ex wolfSSL_EVP_DigestFinal_ex +#define EVP_DigestSignInit wolfSSL_EVP_DigestSignInit +#define EVP_DigestSignUpdate wolfSSL_EVP_DigestSignUpdate +#define EVP_DigestSignFinal wolfSSL_EVP_DigestSignFinal +#define EVP_DigestVerifyInit wolfSSL_EVP_DigestVerifyInit +#define EVP_DigestVerifyUpdate wolfSSL_EVP_DigestVerifyUpdate +#define EVP_DigestVerifyFinal wolfSSL_EVP_DigestVerifyFinal +#define EVP_BytesToKey wolfSSL_EVP_BytesToKey #define EVP_get_cipherbyname wolfSSL_EVP_get_cipherbyname #define EVP_get_digestbyname wolfSSL_EVP_get_digestbyname @@ -549,6 +565,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_PKEY_size wolfSSL_EVP_PKEY_size #define EVP_PKEY_type wolfSSL_EVP_PKEY_type #define EVP_PKEY_base_id wolfSSL_EVP_PKEY_base_id +#define EVP_PKEY_id wolfSSL_EVP_PKEY_id #define EVP_SignFinal wolfSSL_EVP_SignFinal #define EVP_SignInit wolfSSL_EVP_SignInit #define EVP_SignUpdate wolfSSL_EVP_SignUpdate diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 20e96e024..9d9f5a496 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -119,6 +119,10 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, pem_password_cb* cb, void* arg); WOLFSSL_API +WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio, + WOLFSSL_EVP_PKEY **key, + pem_password_cb *cb, void *pass); +WOLFSSL_API int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key, const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len, @@ -127,7 +131,7 @@ int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key, #if !defined(NO_FILESYSTEM) WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, - pem_password_cb *cb, void *u); + pem_password_cb *cb, void *u); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_X509(FILE *fp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); @@ -157,6 +161,7 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PrivateKey(FILE *fp, WOLFSSL_EVP_PKEY **x, /* EVP_KEY */ #define PEM_read_bio_PrivateKey wolfSSL_PEM_read_bio_PrivateKey #define PEM_read_PUBKEY wolfSSL_PEM_read_PUBKEY +#define PEM_read_bio_PUBKEY wolfSSL_PEM_read_bio_PUBKEY #ifdef __cplusplus } /* extern "C" */ From df20daa1ae08faca9cc739a0986f6c08cd52cef7 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 12 Sep 2018 15:25:43 +1000 Subject: [PATCH 2/3] Support RSA and ECC in wolfSSL_DigestSign/Verify* --- src/ssl.c | 49 ++++- tests/api.c | 144 ++++++++++++ wolfcrypt/src/asn.c | 4 +- wolfcrypt/src/evp.c | 496 +++++++++++++++++++++++------------------- wolfssl/openssl/ec.h | 6 + wolfssl/openssl/evp.h | 6 +- 6 files changed, 479 insertions(+), 226 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 045f4aa2f..ad438e50c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6657,6 +6657,21 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out, unsigned char** in, if (out != NULL) { *out = pkey; } + + pkey->ownEcc = 1; + pkey->ecc = wolfSSL_EC_KEY_new(); + if (pkey->ecc == NULL) { + wolfSSL_EVP_PKEY_free(pkey); + return NULL; + } + + if (wolfSSL_EC_KEY_LoadDer_ex(pkey->ecc, + (const unsigned char*)pkey->pkey.ptr, + pkey->pkey_sz, WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1) { + wolfSSL_EVP_PKEY_free(pkey); + return NULL; + } + return pkey; } } @@ -12769,6 +12784,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) if ((out == NULL) || (in == NULL)) return WOLFSSL_FAILURE; WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_copy_ex"); XMEMCPY(out, in, sizeof(WOLFSSL_EVP_MD_CTX)); + if (in->pctx != NULL) { + out->pctx = wolfSSL_EVP_PKEY_CTX_new(in->pctx->pkey, NULL); + if (out->pctx == NULL) + return WOLFSSL_FAILURE; + } return WOLFSSL_SUCCESS; } @@ -12952,6 +12972,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx) { WOLFSSL_ENTER("EVP_MD_CTX_cleanup"); + if (ctx->pctx != NULL) + wolfSSL_EVP_PKEY_CTX_free(ctx->pctx); ForceZero(ctx, sizeof(*ctx)); ctx->macType = 0xFF; return 1; @@ -28518,8 +28540,15 @@ int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz #ifdef HAVE_ECC /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */ -int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, - const unsigned char* derBuf, int derSz) +int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, + int derSz) +{ + return wolfSSL_EC_KEY_LoadDer_ex(key, derBuf, derSz, + WOLFSSL_EC_KEY_LOAD_PRIVATE); +} + +int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, + int derSz, int opt) { word32 idx = 0; int ret; @@ -28531,9 +28560,21 @@ int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, return WOLFSSL_FATAL_ERROR; } - ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal, derSz); + if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) { + ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal, + derSz); + } + else { + ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal, + derSz); + } if (ret < 0) { - WOLFSSL_MSG("wc_EccPrivateKeyDecode failed"); + if (opt == WOLFSSL_RSA_LOAD_PRIVATE) { + WOLFSSL_MSG("wc_EccPrivateKeyDecode failed"); + } + else { + WOLFSSL_MSG("wc_EccPublicKeyDecode failed"); + } return WOLFSSL_FATAL_ERROR; } diff --git a/tests/api.c b/tests/api.c index 72e0b936f..66ed2adb1 100644 --- a/tests/api.c +++ b/tests/api.c @@ -16796,6 +16796,148 @@ static void test_wolfSSL_EVP_MD_hmac_signing(void) } +static void test_wolfSSL_EVP_MD_rsa_signing(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048) + WOLFSSL_EVP_PKEY* privKey; + WOLFSSL_EVP_PKEY* pubKey; + const char testData[] = "Hi There"; + WOLFSSL_EVP_MD_CTX mdCtx; + size_t checkSz = -1; + int sz = 2048 / 8; + const unsigned char* cp; + unsigned char* p; + unsigned char check[2048/8]; + + printf(testingFmt, "wolfSSL_EVP_MD_rsa_signing()"); + + cp = client_key_der_2048; + AssertNotNull((privKey = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &cp, + sizeof_client_key_der_2048))); + p = (unsigned char *)client_keypub_der_2048; + AssertNotNull((pubKey = wolfSSL_d2i_PUBKEY(NULL, &p, + sizeof_client_keypub_der_2048))); + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, privKey), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, + (unsigned int)XSTRLEN(testData)), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1); + AssertIntEQ((int)checkSz, sz); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1); + AssertIntEQ((int)checkSz,sz); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, pubKey), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, + (unsigned int)XSTRLEN(testData)), + 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, privKey), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, 4), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1); + AssertIntEQ((int)checkSz, sz); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1); + AssertIntEQ((int)checkSz, sz); + AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData + 4, + (unsigned int)XSTRLEN(testData) - 4), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1); + AssertIntEQ((int)checkSz, sz); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, pubKey), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, 4), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData + 4, + (unsigned int)XSTRLEN(testData) - 4), + 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + + wolfSSL_EVP_PKEY_free(pubKey); + wolfSSL_EVP_PKEY_free(privKey); + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA */ +} + + +static void test_wolfSSL_EVP_MD_ecc_signing(void) +{ +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) + WOLFSSL_EVP_PKEY* privKey; + WOLFSSL_EVP_PKEY* pubKey; + const char testData[] = "Hi There"; + WOLFSSL_EVP_MD_CTX mdCtx; + size_t checkSz = -1; + const unsigned char* cp; + unsigned char* p; + unsigned char check[2048/8]; + + printf(testingFmt, "wolfSSL_EVP_MD_ecc_signing()"); + + cp = ecc_clikey_der_256; + AssertNotNull((privKey = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL, &cp, + sizeof_ecc_clikey_der_256))); + p = (unsigned char *)ecc_clikeypub_der_256; + AssertNotNull((pubKey = wolfSSL_d2i_PUBKEY(NULL, &p, + sizeof_ecc_clikeypub_der_256))); + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, privKey), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, + (unsigned int)XSTRLEN(testData)), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, pubKey), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, + (unsigned int)XSTRLEN(testData)), + 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + AssertIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, privKey), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData, 4), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, NULL, &checkSz), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, testData + 4, + (unsigned int)XSTRLEN(testData) - 4), 1); + AssertIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, check, &checkSz), 1); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + + wolfSSL_EVP_MD_CTX_init(&mdCtx); + AssertIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, pubKey), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData, 4), 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, testData + 4, + (unsigned int)XSTRLEN(testData) - 4), + 1); + AssertIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, check, checkSz), 1); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); + + wolfSSL_EVP_PKEY_free(pubKey); + wolfSSL_EVP_PKEY_free(privKey); + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA */ +} + + static void test_wolfSSL_CTX_add_extra_chain_cert(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ @@ -20957,6 +21099,8 @@ void ApiTest(void) test_wolfSSL_ctrl(); test_wolfSSL_EVP_PKEY_new_mac_key(); test_wolfSSL_EVP_MD_hmac_signing(); + test_wolfSSL_EVP_MD_rsa_signing(); + test_wolfSSL_EVP_MD_ecc_signing(); test_wolfSSL_CTX_add_extra_chain_cert(); #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) test_wolfSSL_ERR_peek_last_error_line(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 139ae039d..13e942463 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -12895,7 +12895,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, } /* key header */ - ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL); + ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL); if (ret != 0) return ret; @@ -12905,6 +12905,8 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, return ASN_ECC_KEY_E; } + *inOutIdx += length; + return 0; } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 6d4c8377a..e3a7366f2 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1124,110 +1124,137 @@ const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey, return (const unsigned char*)pkey->pkey.ptr; } - -int wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx, - WOLFSSL_EVP_PKEY_CTX **pctx, - const WOLFSSL_EVP_MD *type, - WOLFSSL_ENGINE *e, - WOLFSSL_EVP_PKEY *pkey) +/* Initialize an EVP_DigestSign/Verify operation. + * Initialize a digest for RSA and ECC keys, or HMAC for HMAC key. + */ +static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx, + WOLFSSL_EVP_PKEY_CTX **pctx, + const WOLFSSL_EVP_MD *type, + WOLFSSL_ENGINE *e, + WOLFSSL_EVP_PKEY *pkey) { - int hashType; - const unsigned char* key; - size_t keySz; + if (pkey->type == EVP_PKEY_HMAC) { + int hashType; + const unsigned char* key; + size_t keySz; - /* Unused parameters */ - (void)pctx; - (void)e; + if (XSTRNCMP(type, "SHA256", 6) == 0) { + hashType = WC_SHA256; + } + #ifdef WOLFSSL_SHA224 + else if (XSTRNCMP(type, "SHA224", 6) == 0) { + hashType = WC_SHA224; + } + #endif + #ifdef WOLFSSL_SHA384 + else if (XSTRNCMP(type, "SHA384", 6) == 0) { + hashType = WC_SHA384; + } + #endif + #ifdef WOLFSSL_SHA512 + else if (XSTRNCMP(type, "SHA512", 6) == 0) { + hashType = WC_SHA512; + } + #endif + #ifndef NO_MD5 + else if (XSTRNCMP(type, "MD5", 3) == 0) { + hashType = WC_MD5; + } + #endif + #ifndef NO_SHA + /* has to be last since would pick or 224, 256, 384, or 512 too */ + else if (XSTRNCMP(type, "SHA", 3) == 0) { + hashType = WC_SHA; + } + #endif /* NO_SHA */ + else + return BAD_FUNC_ARG; - WOLFSSL_ENTER("EVP_DigestSignInit"); + key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz); - if (ctx == NULL || type == NULL || pkey == NULL) - return BAD_FUNC_ARG; + if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0) + return WOLFSSL_FAILURE; -#ifdef WOLFSSL_ASYNC_CRYPT - /* compile-time validation of ASYNC_CTX_SIZE */ - typedef char async_test[WC_ASYNC_DEV_SIZE >= sizeof(WC_ASYNC_DEV) ? - 1 : -1]; - (void)sizeof(async_test); -#endif + if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0) + return WOLFSSL_FAILURE; - if (XSTRNCMP(type, "SHA256", 6) == 0) { - hashType = WC_SHA256; + ctx->macType = NID_hmac & 0xFF; } -#ifdef WOLFSSL_SHA224 - else if (XSTRNCMP(type, "SHA224", 6) == 0) { - hashType = WC_SHA224; + else { + int ret; + + if (ctx->pctx == NULL) + ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e); + if (ctx->pctx == NULL) + return WOLFSSL_FAILURE; + + ret = wolfSSL_EVP_DigestInit(ctx, type); + if (ret == WOLFSSL_SUCCESS && pctx != NULL) + *pctx = ctx->pctx; + return ret; } -#endif -#ifdef WOLFSSL_SHA384 - else if (XSTRNCMP(type, "SHA384", 6) == 0) { - hashType = WC_SHA384; + + return WOLFSSL_SUCCESS; +} + +/* Update an EVP_DigestSign/Verify operation. + * Update a digest for RSA and ECC keys, or HMAC for HMAC key. + */ +static int wolfssl_evp_digest_pk_update(WOLFSSL_EVP_MD_CTX *ctx, + const void *d, unsigned int cnt) +{ + if (ctx->pctx == NULL) { + if (ctx->macType != (NID_hmac & 0xFF)) + return WOLFSSL_FAILURE; + + if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0) + return WOLFSSL_FAILURE; + + return WOLFSSL_SUCCESS; } -#endif -#ifdef WOLFSSL_SHA512 - else if (XSTRNCMP(type, "SHA512", 6) == 0) { - hashType = WC_SHA512; - } -#endif -#ifndef NO_MD5 - else if (XSTRNCMP(type, "MD5", 3) == 0) { - hashType = WC_MD5; - } -#endif -#ifndef NO_SHA - /* has to be last since would pick or 224, 256, 384, or 512 too */ - else if (XSTRNCMP(type, "SHA", 3) == 0) { - hashType = WC_SHA; - } -#endif /* NO_SHA */ else - return BAD_FUNC_ARG; - - key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz); - - if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0) - return WOLFSSL_FAILURE; - - if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0) - return WOLFSSL_FAILURE; - - ctx->macType = NID_hmac & 0xFF; - - return WOLFSSL_SUCCESS; + return wolfSSL_EVP_DigestUpdate(ctx, d, cnt); } - -int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, - const void *d, unsigned int cnt) +/* Finalize an EVP_DigestSign/Verify operation - common part only. + * Finalize a digest for RSA and ECC keys, or HMAC for HMAC key. + * Copies the digest so that you can keep updating. + */ +static int wolfssl_evp_digest_pk_final(WOLFSSL_EVP_MD_CTX *ctx, + unsigned char *md, unsigned int* mdlen) { - WOLFSSL_ENTER("EVP_DigestSignFinal"); + int ret; - if (ctx->macType != (NID_hmac & 0xFF)) - return WOLFSSL_FAILURE; + if (ctx->pctx == NULL) { + Hmac hmacCopy; - if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0) - return WOLFSSL_FAILURE; + if (ctx->macType != (NID_hmac & 0xFF)) + return WOLFSSL_FAILURE; - return WOLFSSL_SUCCESS; + XMEMCPY(&hmacCopy, &ctx->hash.hmac, sizeof(hmacCopy)); + ret = wc_HmacFinal(&hmacCopy, md) == 0; + + ForceZero(&hmacCopy, sizeof(hmacCopy)); + return ret; + } + else { + WOLFSSL_EVP_MD_CTX ctxCopy; + + if (wolfSSL_EVP_MD_CTX_copy_ex(&ctxCopy, ctx) != WOLFSSL_SUCCESS) + return WOLFSSL_FAILURE; + + ret = wolfSSL_EVP_DigestFinal(&ctxCopy, md, mdlen); + wolfSSL_EVP_MD_CTX_cleanup(&ctxCopy); + return ret; + } } - -int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, - unsigned char *sig, size_t *siglen) +/* Get the length of the mac based on the digest algorithm. */ +static int wolfssl_mac_len(unsigned char macType) { - unsigned char digest[WC_MAX_DIGEST_SIZE]; - Hmac hmacCopy; - int hashLen, ret; + int hashLen; - WOLFSSL_ENTER("EVP_DigestSignFinal"); - - if (ctx == NULL || siglen == NULL) - return WOLFSSL_FAILURE; - - if (ctx->macType != (NID_hmac & 0xFF)) - return WOLFSSL_FAILURE; - - switch (ctx->hash.hmac.macType) { + switch (macType) { #ifndef NO_MD5 case WC_MD5: hashLen = WC_MD5_DIGEST_SIZE; @@ -1252,12 +1279,12 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, break; #endif /* !NO_SHA256 */ - #ifdef WOLFSSL_SHA512 #ifdef WOLFSSL_SHA384 case WC_SHA384: hashLen = WC_SHA384_DIGEST_SIZE; break; #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 case WC_SHA512: hashLen = WC_SHA512_DIGEST_SIZE; break; @@ -1270,23 +1297,127 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, #endif /* HAVE_BLAKE2 */ default: - return 0; + hashLen = 0; } - if (sig == NULL) { - *siglen = hashLen; - return WOLFSSL_SUCCESS; + return hashLen; +} + +int wolfSSL_EVP_DigestSignInit(WOLFSSL_EVP_MD_CTX *ctx, + WOLFSSL_EVP_PKEY_CTX **pctx, + const WOLFSSL_EVP_MD *type, + WOLFSSL_ENGINE *e, + WOLFSSL_EVP_PKEY *pkey) +{ + WOLFSSL_ENTER("EVP_DigestSignInit"); + + if (ctx == NULL || type == NULL || pkey == NULL) + return BAD_FUNC_ARG; + + return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey); +} + + +int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d, + unsigned int cnt) +{ + WOLFSSL_ENTER("EVP_DigestSignUpdate"); + + if (ctx == NULL || d == NULL) + return BAD_FUNC_ARG; + + return wolfssl_evp_digest_pk_update(ctx, d, cnt); +} + +int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, + size_t *siglen) +{ + unsigned char digest[WC_MAX_DIGEST_SIZE]; + unsigned int hashLen; + int ret = WOLFSSL_FAILURE; + + WOLFSSL_ENTER("EVP_DigestSignFinal"); + + if (ctx == NULL || siglen == NULL) + return WOLFSSL_FAILURE; + + /* Return the maximum size of the signaure when sig is NULL. */ + if (ctx->pctx == NULL) { + if (ctx->macType != (NID_hmac & 0xFF)) + return WOLFSSL_FAILURE; + + hashLen = wolfssl_mac_len(ctx->hash.hmac.macType); + + if (sig == NULL) { + *siglen = hashLen; + return WOLFSSL_SUCCESS; + } } +#if !defined(NO_RSA) && !defined(HAVE_USER_RSA) + else if (ctx->pctx->pkey->type == EVP_PKEY_RSA) { + if (sig == NULL) { + *siglen = wolfSSL_RSA_size(ctx->pctx->pkey->rsa); + return WOLFSSL_SUCCESS; + } + } +#endif +#ifdef HAVE_ECC + else if (ctx->pctx->pkey->type == EVP_PKEY_EC) { + if (sig == NULL) { + /* SEQ + INT + INT */ + *siglen = ecc_sets[ctx->pctx->pkey->ecc->group->curve_idx].size * 2 + + 8; + return WOLFSSL_SUCCESS; + } + } +#endif - if ((int)(*siglen) > hashLen) - *siglen = hashLen; + if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0) + return WOLFSSL_FAILURE; + + if (ctx->pctx == NULL) { + /* Copy the HMAC result as signature. */ + if ((unsigned int)(*siglen) > hashLen) + *siglen = hashLen; + /* May be a truncated signature. */ - XMEMCPY(&hmacCopy, &ctx->hash.hmac, sizeof(hmacCopy)); - ret = wc_HmacFinal(&hmacCopy, digest) == 0; - if (ret == 1) XMEMCPY(sig, digest, *siglen); + ret = WOLFSSL_SUCCESS; + } + else { + /* Sign the digest. */ + switch (ctx->pctx->pkey->type) { + #if !defined(NO_RSA) && !defined(HAVE_USER_RSA) + case EVP_PKEY_RSA: { + unsigned int sigSz; + int nid = md2nid(ctx->macType); + if (nid < 0) break; + ret = wolfSSL_RSA_sign(nid, digest, hashLen, sig, &sigSz, + ctx->pctx->pkey->rsa); + if (ret >= 0) + *siglen = sigSz; + break; + } + #endif /* NO_RSA */ + + #ifdef HAVE_ECC + case EVP_PKEY_EC: { + WOLFSSL_ECDSA_SIG *ecdsaSig; + ecdsaSig = wolfSSL_ECDSA_do_sign(digest, hashLen, + ctx->pctx->pkey->ecc); + if (ecdsaSig == NULL) + break; + *siglen = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig); + wolfSSL_ECDSA_SIG_free(ecdsaSig); + ret = WOLFSSL_SUCCESS; + break; + } + #endif + default: + break; + } + } - ForceZero(&hmacCopy, sizeof(hmacCopy)); ForceZero(digest, sizeof(digest)); return ret; } @@ -1297,84 +1428,24 @@ int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx, WOLFSSL_ENGINE *e, WOLFSSL_EVP_PKEY *pkey) { - int hashType; - const unsigned char* key; - size_t keySz; - - /* Unused parameters */ - (void)pctx; - (void)e; - WOLFSSL_ENTER("EVP_DigestVerifyInit"); if (ctx == NULL || type == NULL || pkey == NULL) return BAD_FUNC_ARG; -#ifdef WOLFSSL_ASYNC_CRYPT - /* compile-time validation of ASYNC_CTX_SIZE */ - typedef char async_test[WC_ASYNC_DEV_SIZE >= sizeof(WC_ASYNC_DEV) ? - 1 : -1]; - (void)sizeof(async_test); -#endif - - if (XSTRNCMP(type, "SHA256", 6) == 0) { - hashType = WC_SHA256; - } -#ifdef WOLFSSL_SHA224 - else if (XSTRNCMP(type, "SHA224", 6) == 0) { - hashType = WC_SHA224; - } -#endif -#ifdef WOLFSSL_SHA384 - else if (XSTRNCMP(type, "SHA384", 6) == 0) { - hashType = WC_SHA384; - } -#endif -#ifdef WOLFSSL_SHA512 - else if (XSTRNCMP(type, "SHA512", 6) == 0) { - hashType = WC_SHA512; - } -#endif -#ifndef NO_MD5 - else if (XSTRNCMP(type, "MD5", 3) == 0) { - hashType = WC_MD5; - } -#endif -#ifndef NO_SHA - /* has to be last since would pick or 224, 256, 384, or 512 too */ - else if (XSTRNCMP(type, "SHA", 3) == 0) { - hashType = WC_SHA; - } -#endif /* NO_SHA */ - else - return BAD_FUNC_ARG; - - key = wolfSSL_EVP_PKEY_get0_hmac(pkey, &keySz); - - if (wc_HmacInit(&ctx->hash.hmac, NULL, INVALID_DEVID) != 0) - return WOLFSSL_FAILURE; - - if (wc_HmacSetKey(&ctx->hash.hmac, hashType, key, (word32)keySz) != 0) - return WOLFSSL_FAILURE; - - ctx->macType = NID_hmac & 0xFF; - - return WOLFSSL_SUCCESS; + return wolfSSL_evp_digest_pk_init(ctx, pctx, type, e, pkey); } -int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, - const void *d, size_t cnt) +int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d, + size_t cnt) { WOLFSSL_ENTER("EVP_DigestVerifyUpdate"); - if (ctx->macType != (NID_hmac & 0xFF)) - return WOLFSSL_FAILURE; + if (ctx == NULL || d == NULL) + return BAD_FUNC_ARG; - if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, (word32)cnt) != 0) - return WOLFSSL_FAILURE; - - return WOLFSSL_SUCCESS; + return wolfssl_evp_digest_pk_update(ctx, d, (unsigned int)cnt); } @@ -1382,79 +1453,66 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen) { unsigned char digest[WC_MAX_DIGEST_SIZE]; - Hmac hmacCopy; - size_t hashLen; - int ret; + unsigned int hashLen; WOLFSSL_ENTER("EVP_DigestVerifyFinal"); if (ctx == NULL || sig == NULL) return WOLFSSL_FAILURE; - if (ctx->macType != (NID_hmac & 0xFF)) - return WOLFSSL_FAILURE; + if (ctx->pctx == NULL) { + if (ctx->macType != (NID_hmac & 0xFF)) + return WOLFSSL_FAILURE; - switch (ctx->hash.hmac.macType) { - #ifndef NO_MD5 - case WC_MD5: - hashLen = WC_MD5_DIGEST_SIZE; - break; - #endif /* !NO_MD5 */ + hashLen = wolfssl_mac_len(ctx->hash.hmac.macType); - #ifndef NO_SHA - case WC_SHA: - hashLen = WC_SHA_DIGEST_SIZE; - break; - #endif /* !NO_SHA */ - - #ifdef WOLFSSL_SHA224 - case WC_SHA224: - hashLen = WC_SHA224_DIGEST_SIZE; - break; - #endif /* WOLFSSL_SHA224 */ - - #ifndef NO_SHA256 - case WC_SHA256: - hashLen = WC_SHA256_DIGEST_SIZE; - break; - #endif /* !NO_SHA256 */ - - #ifdef WOLFSSL_SHA512 - #ifdef WOLFSSL_SHA384 - case WC_SHA384: - hashLen = WC_SHA384_DIGEST_SIZE; - break; - #endif /* WOLFSSL_SHA384 */ - case WC_SHA512: - hashLen = WC_SHA512_DIGEST_SIZE; - break; - #endif /* WOLFSSL_SHA512 */ - - #ifdef HAVE_BLAKE2 - case BLAKE2B_ID: - hashLen = BLAKE2B_OUTBYTES; - break; - #endif /* HAVE_BLAKE2 */ - - default: - return 0; + if (siglen > hashLen) + return WOLFSSL_FAILURE; + /* May be a truncated signature. */ } - if (siglen != hashLen) + if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0) return WOLFSSL_FAILURE; - XMEMCPY(&hmacCopy, &ctx->hash.hmac, sizeof(hmacCopy)); - ret = wc_HmacFinal(&hmacCopy, digest) == 0; - if (ret == 1) { + if (ctx->pctx == NULL) { + /* Check HMAC result matches the signature. */ if (XMEMCMP(sig, digest, siglen) == 0) - ret = WOLFSSL_SUCCESS; - else - ret = WOLFSSL_FAILURE; + return WOLFSSL_SUCCESS; + return WOLFSSL_FAILURE; + } + else { + /* Verify the signature with the digest. */ + switch (ctx->pctx->pkey->type) { + #if !defined(NO_RSA) && !defined(HAVE_USER_RSA) + case EVP_PKEY_RSA: { + int nid = md2nid(ctx->macType); + if (nid < 0) + return WOLFSSL_FAILURE; + return wolfSSL_RSA_verify(nid, digest, hashLen, sig, + (unsigned int)siglen, + ctx->pctx->pkey->rsa); + } + #endif /* NO_RSA */ + + #ifdef HAVE_ECC + case EVP_PKEY_EC: { + int ret; + WOLFSSL_ECDSA_SIG *ecdsaSig; + ecdsaSig = wolfSSL_d2i_ECDSA_SIG(NULL, &sig, (long)siglen); + if (ecdsaSig == NULL) + return WOLFSSL_FAILURE; + ret = wolfSSL_ECDSA_do_verify(digest, hashLen, ecdsaSig, + ctx->pctx->pkey->ecc); + wolfSSL_ECDSA_SIG_free(ecdsaSig); + return ret; + } + #endif + default: + break; + } } - ForceZero(&hmacCopy, sizeof(hmacCopy)); - ForceZero(digest, sizeof(digest)); - return ret; + return WOLFSSL_FAILURE; } #endif /* WOLFSSL_EVP_INCLUDED */ diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 03bb9c5f4..e0b514704 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -101,6 +101,9 @@ struct WOLFSSL_EC_KEY { char exSet; /* external set from internal ? */ }; +#define WOLFSSL_EC_KEY_LOAD_PRIVATE 1 +#define WOLFSSL_EC_KEY_LOAD_PUBLIC 2 + WOLFSSL_API int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *curve, const WOLFSSL_EC_POINT *p, @@ -112,6 +115,9 @@ WOLFSSL_API int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* der, int derSz); WOLFSSL_API +int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, + const unsigned char* der, int derSz, int opt); +WOLFSSL_API void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key); WOLFSSL_API WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key); diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index d5259a550..7024ad571 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -126,6 +126,7 @@ typedef union { #endif } WOLFSSL_Hasher; +typedef struct WOLFSSL_EVP_PKEY_CTX WOLFSSL_EVP_PKEY_CTX; typedef struct WOLFSSL_EVP_MD_CTX { union { @@ -133,6 +134,7 @@ typedef struct WOLFSSL_EVP_MD_CTX { Hmac hmac; } hash; unsigned char macType; + WOLFSSL_EVP_PKEY_CTX *pctx; } WOLFSSL_EVP_MD_CTX; @@ -219,11 +221,11 @@ typedef struct WOLFSSL_EVP_CIPHER_CTX { int lastUsed; } WOLFSSL_EVP_CIPHER_CTX; -typedef struct WOLFSSL_EVP_PKEY_CTX { +struct WOLFSSL_EVP_PKEY_CTX { WOLFSSL_EVP_PKEY *pkey; int op; /* operation */ int padding; -} WOLFSSL_EVP_PKEY_CTX; +}; typedef int WOLFSSL_ENGINE ; typedef WOLFSSL_ENGINE ENGINE; From 0275366fb6d17477b019b6346938a496be80ac20 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 13 Sep 2018 08:47:09 +1000 Subject: [PATCH 3/3] Fixes from code review Document how length of ECDSA signature calculated. Check parameter not NULL before use. Formatting fix. Also, disable RSA test of EVP_DigestSign/Verify* when HAVE_USER_RSA. --- src/ssl.c | 26 +++++++++++++++++++------- tests/api.c | 7 ++++--- wolfcrypt/src/evp.c | 3 ++- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index ad438e50c..a44d2aeb0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -27491,11 +27491,19 @@ int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, unsigned char **pp) if (sig == NULL) return 0; - len = 2 + 2 + mp_leading_bit((mp_int*)sig->r->internal) + - mp_unsigned_bin_size((mp_int*)sig->r->internal) + - 2 + mp_leading_bit((mp_int*)sig->s->internal) + - mp_unsigned_bin_size((mp_int*)sig->s->internal); - if (pp != NULL) { + /* ASN.1: SEQ + INT + INT + * ASN.1 Integer must be a positive value - prepend zero if number has + * top bit set. + */ + len = 2 + mp_leading_bit((mp_int*)sig->r->internal) + + mp_unsigned_bin_size((mp_int*)sig->r->internal) + + 2 + mp_leading_bit((mp_int*)sig->s->internal) + + mp_unsigned_bin_size((mp_int*)sig->s->internal); + /* Two bytes required for length if ASN.1 SEQ data greater than 127 bytes + * and less than 256 bytes. + */ + len = 1 + ((len > 127) ? 2 : 1) + len; + if (pp != NULL && *pp != NULL) { if (StoreECC_DSA_Sig(*pp, &len, (mp_int*)sig->r->internal, (mp_int*)sig->s->internal) != MP_OKAY) { len = 0; @@ -28230,13 +28238,17 @@ int wolfSSL_EVP_PKEY_type(int type) int wolfSSL_EVP_PKEY_id(const EVP_PKEY *pkey) { - return pkey->type; + if (pkey != NULL) + return pkey->type; + return 0; } int wolfSSL_EVP_PKEY_base_id(const EVP_PKEY *pkey) { - return EVP_PKEY_type(pkey->type); + if (pkey == NULL) + return NID_undef; + return wolfSSL_EVP_PKEY_type(pkey->type); } diff --git a/tests/api.c b/tests/api.c index 66ed2adb1..26bd420ef 100644 --- a/tests/api.c +++ b/tests/api.c @@ -16798,7 +16798,8 @@ static void test_wolfSSL_EVP_MD_hmac_signing(void) static void test_wolfSSL_EVP_MD_rsa_signing(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048) +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) && \ + defined(USE_CERT_BUFFERS_2048) WOLFSSL_EVP_PKEY* privKey; WOLFSSL_EVP_PKEY* pubKey; const char testData[] = "Hi There"; @@ -16866,7 +16867,7 @@ static void test_wolfSSL_EVP_MD_rsa_signing(void) wolfSSL_EVP_PKEY_free(privKey); printf(resultFmt, passed); -#endif /* OPENSSL_EXTRA */ +#endif } @@ -16934,7 +16935,7 @@ static void test_wolfSSL_EVP_MD_ecc_signing(void) wolfSSL_EVP_PKEY_free(privKey); printf(resultFmt, passed); -#endif /* OPENSSL_EXTRA */ +#endif } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index e3a7366f2..4900d0e67 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1391,7 +1391,8 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, case EVP_PKEY_RSA: { unsigned int sigSz; int nid = md2nid(ctx->macType); - if (nid < 0) break; + if (nid < 0) + break; ret = wolfSSL_RSA_sign(nid, digest, hashLen, sig, &sigSz, ctx->pctx->pkey->rsa); if (ret >= 0)