From b4fd737fb13cce01973e8d60a1da80ad8b2a1298 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 21 May 2021 16:56:36 +0200 Subject: [PATCH 01/11] Bind 9.17.9 Support - Add `--enable-bind` configuration option - New compatibility API: - `RSA_get0_crt_params` - `RSA_set0_crt_params` - `RSA_get0_factors` - `RSA_set0_factors` - `RSA_test_flags` - `HMAC_CTX_get_md` - `EVP_MD_block_size` - `EC_KEY_check_key` - `o2i_ECPublicKey` - `DH_get0_key` - `DH_set0_key` - Calling `EVP_MD_CTX_cleanup` on an uninitialized `EVP_MD_CTX` structure is no longer an error - `DH_generate_parameters` and `DH_generate_parameters_ex` has been implemented --- configure.ac | 23 ++- src/ssl.c | 313 ++++++++++++++++++++++++++++++++++--- tests/api.c | 80 ++++++++-- wolfcrypt/src/evp.c | 15 ++ wolfssl/openssl/crypto.h | 28 ++-- wolfssl/openssl/dh.h | 6 +- wolfssl/openssl/ec.h | 6 + wolfssl/openssl/evp.h | 1 + wolfssl/openssl/hmac.h | 23 +-- wolfssl/openssl/opensslv.h | 2 +- wolfssl/openssl/rsa.h | 15 ++ wolfssl/ssl.h | 7 +- 12 files changed, 460 insertions(+), 59 deletions(-) diff --git a/configure.ac b/configure.ac index 1fa58e4f6..eb73ae170 100644 --- a/configure.ac +++ b/configure.ac @@ -770,6 +770,7 @@ AC_ARG_ENABLE([mcast], # List of open source project defines using our openssl compatibility layer: +# bind dns (--enable-bind) WOLFSSL_BIND # openssh (--enable-openssh) WOLFSSL_OPENSSH # openvpn (--enable-openvpn) WOLFSSL_OPENVPN # nginix (--enable-nginx) WOLFSSL_NGINX @@ -790,6 +791,12 @@ AC_ARG_ENABLE([mcast], # web server (--enable-webserver) HAVE_WEBSERVER +# Bind DNS compatibility Build +AC_ARG_ENABLE([bind], + [AS_HELP_STRING([--enable-bind],[Enable Bind DNS compatibility build (default: disabled)])], + [ENABLED_BIND=$enableval], + [ENABLED_BIND=no]) + # OpenSSH compatibility Build AC_ARG_ENABLE([openssh], [AS_HELP_STRING([--enable-openssh],[Enable OpenSSH compatibility build (default: disabled)])], @@ -934,7 +941,7 @@ AC_ARG_ENABLE([opensslall], [ ENABLED_OPENSSLALL=$enableval ], [ ENABLED_OPENSSLALL=no ] ) -if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || test "$ENABLED_HAPROXY" = "yes" +if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || test "$ENABLED_HAPROXY" = "yes" || test "$ENABLED_BIND" = "yes" then ENABLED_OPENSSLALL="yes" fi @@ -1878,6 +1885,11 @@ AC_ARG_ENABLE([keygen], [ ENABLED_KEYGEN=no ] ) +if test "$ENABLED_BIND" = "yes" +then + ENABLED_KEYGEN=yes +fi + if test "$ENABLED_KEYGEN" = "yes" then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KEY_GEN" @@ -1890,7 +1902,7 @@ AC_ARG_ENABLE([certgen], [ ENABLED_CERTGEN=$enableval ], [ ENABLED_CERTGEN=no ] ) -if test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_OPENSSH" = "yes" +if test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_BIND" = "yes" then ENABLED_CERTGEN=yes fi @@ -4361,6 +4373,13 @@ then fi fi +if test "$ENABLED_BIND" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_BIND" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DWOLFSSL_DES_ECB" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA224 -DWOLFSSL_SHA384 -DWOLFSSL_SHA512" +fi + if test "$ENABLED_OPENVPN" = "yes" then ENABLED_SUPPORTED_CURVES="yes" diff --git a/src/ssl.c b/src/ssl.c index 8559c6f8f..30c95c840 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -30810,7 +30810,7 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh) /* return code compliant with OpenSSL : * size of shared secret if success, -1 if error */ -int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub, +int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub, WOLFSSL_DH* dh) { int ret = WOLFSSL_FATAL_ERROR; @@ -32004,6 +32004,101 @@ cleanup: return ret; } +void wolfSSL_RSA_get0_crt_params(const WOLFSSL_RSA *r, + const WOLFSSL_BIGNUM **dmp1, const WOLFSSL_BIGNUM **dmq1, + const WOLFSSL_BIGNUM **iqmp) +{ + WOLFSSL_ENTER("wolfSSL_RSA_get0_crt_params"); + + if (r != NULL) { + if (dmp1 != NULL) + *dmp1 = r->dmp1; + if (dmq1 != NULL) + *dmq1 = r->dmq1; + if (iqmp != NULL) + *iqmp = r->iqmp; + } else { + if (dmp1 != NULL) + *dmp1 = NULL; + if (dmq1 != NULL) + *dmq1 = NULL; + if (iqmp != NULL) + *iqmp = NULL; + } +} + +int wolfSSL_RSA_set0_crt_params(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *dmp1, + WOLFSSL_BIGNUM *dmq1, WOLFSSL_BIGNUM *iqmp) +{ + WOLFSSL_ENTER("wolfSSL_RSA_set0_crt_params"); + + /* If a param is null in r then it must be non-null in the + * corresponding user input. */ + if (r == NULL || (r->dmp1 == NULL && dmp1 == NULL) || + (r->dmq1 == NULL && dmq1 == NULL) || + (r->iqmp == NULL && iqmp == NULL)) { + WOLFSSL_MSG("Bad parameters"); + return WOLFSSL_FAILURE; + } + + if (dmp1 != NULL) { + wolfSSL_BN_clear_free(r->dmp1); + r->dmp1 = dmp1; + } + if (dmq1 != NULL) { + wolfSSL_BN_clear_free(r->dmq1); + r->dmq1 = dmq1; + } + if (iqmp != NULL) { + wolfSSL_BN_clear_free(r->iqmp); + r->iqmp = iqmp; + } + + return WOLFSSL_SUCCESS; +} + +void wolfSSL_RSA_get0_factors(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **p, + const WOLFSSL_BIGNUM **q) +{ + WOLFSSL_ENTER("wolfSSL_RSA_get0_factors"); + + if (r != NULL) { + if (p != NULL) + *p = r->p; + if (q != NULL) + *q = r->q; + } else { + if (p != NULL) + *p = NULL; + if (q != NULL) + *q = NULL; + } +} + +int wolfSSL_RSA_set0_factors(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *p, WOLFSSL_BIGNUM *q) +{ + WOLFSSL_ENTER("wolfSSL_RSA_set0_factors"); + + /* If a param is null in r then it must be non-null in the + * corresponding user input. */ + if (r == NULL || (r->p == NULL && p == NULL) || + (r->q == NULL && q == NULL)) { + WOLFSSL_MSG("Bad parameters"); + return WOLFSSL_FAILURE; + } + + if (p != NULL) { + wolfSSL_BN_clear_free(r->p); + r->p = p; + } + if (q != NULL) { + wolfSSL_BN_clear_free(r->q); + r->q = q; + } + + return WOLFSSL_SUCCESS; +} + void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n, const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d) { @@ -32613,6 +32708,61 @@ size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx) return (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType); } +const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx) +{ + if (!ctx) { + return NULL; + } + + return wolfSSL_macType2EVP_md(ctx->type); +} + +#ifndef NO_DES3 + +void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, + unsigned char* iv, int len) +{ + (void)len; + + WOLFSSL_MSG("wolfSSL_3des_iv"); + + if (ctx == NULL || iv == NULL) { + WOLFSSL_MSG("Bad function argument"); + return; + } + + if (doset) + wc_Des3_SetIV(&ctx->cipher.des3, iv); /* OpenSSL compat, no ret */ + else + XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE); +} + +#endif /* NO_DES3 */ + + +#ifndef NO_AES + +void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, + unsigned char* iv, int len) +{ + (void)len; + + WOLFSSL_MSG("wolfSSL_aes_ctr_iv"); + + if (ctx == NULL || iv == NULL) { + WOLFSSL_MSG("Bad function argument"); + return; + } + + if (doset) + (void)wc_AesSetIV(&ctx->cipher.aes, iv); /* OpenSSL compat, no ret */ + else + XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE); +} + +#endif /* NO_AES */ + + /* Free the dynamically allocated data. * * p Pointer to dynamically allocated memory. @@ -34171,6 +34321,26 @@ int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, return WOLFSSL_SUCCESS; } + +int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key) +{ + WOLFSSL_ENTER("wolfSSL_EC_KEY_check_key"); + + if (key == NULL || key->internal == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (key->inSet == 0) { + if (SetECKeyInternal((WOLFSSL_EC_KEY*)key) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECKeyInternal failed"); + return WOLFSSL_FAILURE; + } + } + + return wc_ecc_check_key((ecc_key*)key->internal) == 0 ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} /* End EC_KEY */ int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key) @@ -34816,6 +34986,31 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, return wolfSSL_ECPoint_d2i((unsigned char*)buf, (unsigned int)len, group, p); } + +WOLFSSL_EC_KEY *wolfSSL_o2i_ECPublicKey(WOLFSSL_EC_KEY **a, const unsigned char **in, + long len) +{ + WOLFSSL_EC_KEY* ret; + + WOLFSSL_ENTER("wolfSSL_o2i_ECPublicKey"); + + if (!a || !*a || !(*a)->group || !in || !*in || len <= 0) { + WOLFSSL_MSG("wolfSSL_o2i_ECPublicKey Bad arguments"); + return NULL; + } + + ret = *a; + + if (wolfSSL_EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_EC_POINT_oct2point error"); + return NULL; + } + + *in += len; + return ret; +} + int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) { size_t len; @@ -37708,6 +37903,11 @@ void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags) } } +int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *r, int flags) +{ + return r ? r->meth->flags & flags : 0; +} + #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa) { @@ -43379,35 +43579,78 @@ int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1, return WOLFSSL_FAILURE; } -#ifndef NO_WOLFSSL_STUB +void wolfSSL_CRYPTO_cleanup_all_ex_data(void) +{ + WOLFSSL_ENTER("CRYPTO_cleanup_all_ex_data"); +} + WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator, void (*callback) (int, int, void *), void *cb_arg) { - (void)prime_len; - (void)generator; + WOLFSSL_DH* dh; + + WOLFSSL_ENTER("wolfSSL_DH_generate_parameters"); (void)callback; (void)cb_arg; - WOLFSSL_ENTER("wolfSSL_DH_generate_parameters"); - WOLFSSL_STUB("DH_generate_parameters"); - return NULL; + if ((dh = wolfSSL_DH_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_DH_new error"); + return NULL; + } + + if (wolfSSL_DH_generate_parameters_ex(dh, prime_len, generator, NULL) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_DH_generate_parameters_ex error"); + wolfSSL_DH_free(dh); + return NULL; + } + + return dh; } -#endif -#ifndef NO_WOLFSSL_STUB int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generator, void (*callback) (int, int, void *)) { - (void)prime_len; - (void)generator; - (void)callback; - (void)dh; - WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex"); - WOLFSSL_STUB("DH_generate_parameters_ex"); + DhKey* key; - return -1; + WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex"); + (void)callback; + + if (dh == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("No RNG to use"); + return WOLFSSL_FAILURE; + } + + if (dh->inSet == 0) { + if (SetDhInternal(dh) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Unable to set internal DH structure"); + return WOLFSSL_FAILURE; + } + } + + key = (DhKey*)dh->internal; + if (mp_set_int(&key->g, generator) != MP_OKAY) { + WOLFSSL_MSG("Unable to set generator"); + return WOLFSSL_FAILURE; + } + + if (wc_DhGenerateParams(&globalRNG, prime_len, key) != 0) { + WOLFSSL_MSG("wc_DhGenerateParams error"); + return WOLFSSL_FAILURE; + } + + if (SetDhExternal(dh) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetDhExternal error"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; } -#endif void wolfSSL_ERR_load_crypto_strings(void) { @@ -52237,12 +52480,46 @@ WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx, } return (WOLFSSL_STRING*) wolfSSL_lh_retrieve(db->data, value); } -#endif /******************************************************************************* * END OF TXT_DB API ******************************************************************************/ +void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, + const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key) +{ + WOLFSSL_ENTER("wolfSSL_DH_get0_key"); + + if (dh != NULL) { + if (pub_key != NULL) + *pub_key = dh->pub_key; + if (priv_key != NULL) + *priv_key = dh->priv_key; + } +} + +int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key, + WOLFSSL_BIGNUM *priv_key) +{ + WOLFSSL_ENTER("wolfSSL_DH_set0_key"); + + if (dh == NULL) + return WOLFSSL_FAILURE; + + if (pub_key != NULL) { + wolfSSL_BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + + if (priv_key != NULL) { + wolfSSL_BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return SetDhInternal(dh); +} +#endif + /******************************************************************************* * START OF CONF API ******************************************************************************/ diff --git a/tests/api.c b/tests/api.c index b59736b4a..0c545006a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2570,8 +2570,13 @@ static void test_EC_i2d(void) tmp = buf; AssertNotNull(d2i_ECPrivateKey(©, &tmp, len)); - XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buf = NULL; + + AssertIntGT((len = i2o_ECPublicKey(key, &buf)), 0); + AssertNotNull(o2i_ECPublicKey(©, (const unsigned char **)&buf, len)); + AssertIntEQ(EC_KEY_check_key(key), 1); + EC_KEY_free(key); EC_KEY_free(copy); #endif /* HAVE_ECC */ @@ -29123,6 +29128,8 @@ static void test_wolfSSL_EVP_MD_size(void) AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA256"), 1); AssertIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA256_DIGEST_SIZE); + AssertIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA256_BLOCK_SIZE); + AssertIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA256_DIGEST_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA256_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); @@ -29132,6 +29139,8 @@ static void test_wolfSSL_EVP_MD_size(void) wolfSSL_EVP_MD_CTX_init(&mdCtx); AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "MD5"), 1); + AssertIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_MD5_DIGEST_SIZE); + AssertIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_MD5_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_MD5_DIGEST_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_MD5_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); @@ -29142,6 +29151,8 @@ static void test_wolfSSL_EVP_MD_size(void) wolfSSL_EVP_MD_CTX_init(&mdCtx); AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA224"), 1); + AssertIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA224_DIGEST_SIZE); + AssertIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA224_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA224_DIGEST_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA224_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); @@ -29152,6 +29163,8 @@ static void test_wolfSSL_EVP_MD_size(void) wolfSSL_EVP_MD_CTX_init(&mdCtx); AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA384"), 1); + AssertIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA384_DIGEST_SIZE); + AssertIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA384_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA384_DIGEST_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA384_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); @@ -29162,6 +29175,8 @@ static void test_wolfSSL_EVP_MD_size(void) wolfSSL_EVP_MD_CTX_init(&mdCtx); AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA512"), 1); + AssertIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA512_DIGEST_SIZE); + AssertIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA512_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA512_DIGEST_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA512_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); @@ -29172,6 +29187,8 @@ static void test_wolfSSL_EVP_MD_size(void) wolfSSL_EVP_MD_CTX_init(&mdCtx); AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA"), 1); + AssertIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA_DIGEST_SIZE); + AssertIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA_DIGEST_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); @@ -29179,6 +29196,8 @@ static void test_wolfSSL_EVP_MD_size(void) wolfSSL_EVP_MD_CTX_init(&mdCtx); AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA1"), 1); + AssertIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA_DIGEST_SIZE); + AssertIntEQ(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), WC_SHA_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA_DIGEST_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA_BLOCK_SIZE); AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); @@ -29189,7 +29208,8 @@ static void test_wolfSSL_EVP_MD_size(void) AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, ""), BAD_FUNC_ARG); AssertIntEQ(wolfSSL_EVP_MD_size(wolfSSL_EVP_MD_CTX_md(&mdCtx)), BAD_FUNC_ARG); AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), BAD_FUNC_ARG); - AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 0); + /* Cleanup is valid on uninit'ed struct */ + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); printf(resultFmt, passed); @@ -34079,6 +34099,7 @@ static void test_openssl_hmac(const WOLFSSL_EVP_MD* md, int md_len) AssertIntEQ(HMAC_Final(hmac, hash, &len), SSL_SUCCESS); AssertIntEQ(len, md_len); AssertIntEQ(HMAC_size(hmac), md_len); + AssertStrEQ(HMAC_CTX_get_md(hmac), md); HMAC_cleanup(hmac); HMAC_CTX_free(hmac); @@ -35676,6 +35697,11 @@ static void test_wolfSSL_RSA(void) const BIGNUM *n; const BIGNUM *e; const BIGNUM *d; + const BIGNUM *p; + const BIGNUM *q; + const BIGNUM *dmp1; + const BIGNUM *dmq1; + const BIGNUM *iqmp; printf(testingFmt, "wolfSSL_RSA()"); @@ -35685,6 +35711,7 @@ static void test_wolfSSL_RSA(void) /* sanity check */ AssertIntEQ(RSA_bits(NULL), 0); + /* key */ AssertIntEQ(RSA_bits(rsa), 2048); RSA_get0_key(rsa, &n, &e, &d); AssertPtrEq(rsa->n, n); @@ -35698,6 +35725,29 @@ static void test_wolfSSL_RSA(void) AssertPtrEq(rsa->e, e); AssertPtrEq(rsa->d, d); + /* crt_params */ + RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); + AssertPtrEq(rsa->dmp1, dmp1); + AssertPtrEq(rsa->dmq1, dmq1); + AssertPtrEq(rsa->iqmp, iqmp); + AssertNotNull(dmp1 = BN_new()); + AssertNotNull(dmq1 = BN_new()); + AssertNotNull(iqmp = BN_new()); + AssertIntEQ(RSA_set0_crt_params(rsa, (BIGNUM*)dmp1, (BIGNUM*)dmq1, (BIGNUM*)iqmp), 1); + AssertPtrEq(rsa->dmp1, dmp1); + AssertPtrEq(rsa->dmq1, dmq1); + AssertPtrEq(rsa->iqmp, iqmp); + + /* factors */ + RSA_get0_factors(rsa, &p, &q); + AssertPtrEq(rsa->p, p); + AssertPtrEq(rsa->q, q); + AssertNotNull(p = BN_new()); + AssertNotNull(q = BN_new()); + AssertIntEQ(RSA_set0_factors(rsa, (BIGNUM*)p, (BIGNUM*)q), 1); + AssertPtrEq(rsa->p, p); + AssertPtrEq(rsa->q, q); + AssertIntEQ(BN_hex2bn(&rsa->n, "1FFFFF"), 1); AssertIntEQ(RSA_bits(rsa), 21); RSA_free(rsa); @@ -35901,6 +35951,7 @@ static void test_wolfSSL_RSA_meth(void) AssertPtrEq(RSA_get_method(rsa), rsa_meth); AssertIntEQ(RSA_flags(rsa), RSA_METHOD_FLAG_NO_CHECK); RSA_set_flags(rsa, RSA_FLAG_CACHE_PUBLIC); + AssertIntNE(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0); AssertIntEQ(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC); /* rsa_meth is freed here */ @@ -37990,7 +38041,7 @@ static void test_wolfSSL_EC_KEY_dup(void) /* Valid cases */ AssertNotNull(dupKey = wolfSSL_EC_KEY_dup(ecKey)); - AssertIntEQ(wc_ecc_check_key((ecc_key*)dupKey->internal), 0); + AssertIntEQ(EC_KEY_check_key(dupKey), 1); /* Compare pubkey */ srcKey = (ecc_key*)ecKey->internal; @@ -39218,7 +39269,7 @@ static void test_wolfSSL_EVP_DigestFinal_ex(void) wolfSSL_EVP_MD_CTX_init(&mdCtx); AssertIntEQ(wolfSSL_EVP_DigestFinal_ex(&mdCtx, md, &s), 0); - AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 0); + AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1); #else @@ -45815,17 +45866,21 @@ static void test_wolfSSL_set_psk_use_session_callback(void) #endif } -static void test_wolfSSL_DH_get0_pqg(void) +static void test_wolfSSL_DH(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_DH) DH *dh = NULL; BIGNUM* p; BIGNUM* q; BIGNUM* g; + BIGNUM* pub; + BIGNUM* priv; (void)dh; (void)p; (void)q; (void)g; + (void)pub; + (void)priv; #if defined(OPENSSL_ALL) #if !defined(HAVE_FIPS) || \ @@ -45852,14 +45907,22 @@ static void test_wolfSSL_DH_get0_pqg(void) DH_get0_pqg(dh, (const BIGNUM**)&p, (const BIGNUM**)&q, (const BIGNUM**) &g); - AssertPtrEq(p, dh->p); AssertPtrEq(q, dh->q); AssertPtrEq(g, dh->g); + DH_get0_key(dh, (const BIGNUM**)&pub, (const BIGNUM**)&priv); + AssertPtrEq(pub, dh->pub_key); + AssertPtrEq(priv, dh->priv_key); + AssertNotNull(pub = BN_new()); + AssertNotNull(priv = BN_new()); + AssertIntEQ(DH_set0_key(dh, pub, priv), 1); + AssertPtrEq(pub, dh->pub_key); + AssertPtrEq(priv, dh->priv_key); + DH_free(dh); #endif #endif - printf(testingFmt, "test_wolfSSL_DH_get0_pqg"); + printf(testingFmt, "test_wolfSSL_DH"); dh = wolfSSL_DH_new(); AssertNotNull(dh); @@ -45982,7 +46045,6 @@ void ApiTest(void) test_SetTmpEC_DHE_Sz(); test_wolfSSL_CTX_get0_privatekey(); test_wolfSSL_dtls_set_mtu(); - test_wolfSSL_DH_get0_pqg(); #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \ defined(HAVE_IO_TESTS_DEPENDENCIES) test_wolfSSL_read_write(); @@ -46417,7 +46479,7 @@ void ApiTest(void) test_CONF_CTX_FILE(); test_CONF_CTX_CMDLINE(); test_wolfSSL_CRYPTO_get_ex_new_index(); - test_wolfSSL_DH_get0_pqg(); + test_wolfSSL_DH(); /*wolfcrypt */ printf("\n-----------------wolfcrypt unit tests------------------\n"); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index db7c286a2..8f4f9866b 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -2354,6 +2354,18 @@ static enum wc_HashType wolfSSL_EVP_md2macType(const WOLFSSL_EVP_MD *md) return WC_HASH_TYPE_NONE; } +static const WOLFSSL_EVP_MD* wolfSSL_macType2EVP_md(enum wc_HashType type) +{ + const struct s_ent *ent ; + + for( ent = md_tbl; ent->name != NULL; ent++) { + if(ent->macType == type) { + return ent->name; + } + } + return NULL; +} + /* Finalize structure for signing * * ctx WOLFSSL_EVP_MD_CTX structure to finalize @@ -4212,6 +4224,9 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif break; case WC_HASH_TYPE_NONE: + /* Not an error since an unused struct could be free'd or + * reset. */ + break; case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD4: case WC_HASH_TYPE_MD5_SHA: diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 06128fe7f..13b4794a0 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -26,6 +26,20 @@ #include +typedef struct WOLFSSL_INIT_SETTINGS { + char* appname; +} WOLFSSL_INIT_SETTINGS; +typedef WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; + +typedef struct WOLFSSL_CRYPTO_THREADID { + int dummy; +}WOLFSSL_CRYPTO_THREADID; +typedef struct crypto_threadid_st CRYPTO_THREADID; + +typedef struct CRYPTO_EX_DATA CRYPTO_EX_DATA; +typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int idx, + long argl, void* argp); + #include #include @@ -33,12 +47,6 @@ #include "prefix_crypto.h" #endif -typedef struct WOLFSSL_INIT_SETTINGS { - char* appname; -} WOLFSSL_INIT_SETTINGS; - -typedef WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; - WOLFSSL_API const char* wolfSSLeay_version(int type); WOLFSSL_API unsigned long wolfSSLeay(void); WOLFSSL_API unsigned long wolfSSL_OpenSSL_version_num(void); @@ -52,11 +60,6 @@ WOLFSSL_API unsigned char *wolfSSL_OPENSSL_hexstr2buf(const char *str, long *len WOLFSSL_API int wolfSSL_OPENSSL_init_crypto(word64 opts, const OPENSSL_INIT_SETTINGS *settings); #endif -typedef struct WOLFSSL_CRYPTO_THREADID { - int dummy; -}WOLFSSL_CRYPTO_THREADID; -typedef struct crypto_threadid_st CRYPTO_THREADID; - #define crypto_threadid_st WOLFSSL_CRYPTO_THREADID #define CRYPTO_THREADID WOLFSSL_CRYPTO_THREADID @@ -102,9 +105,6 @@ typedef struct crypto_threadid_st CRYPTO_THREADID; #define CRYPTO_set_mem_ex_functions wolfSSL_CRYPTO_set_mem_ex_functions #define FIPS_mode wolfSSL_FIPS_mode #define FIPS_mode_set wolfSSL_FIPS_mode_set -typedef struct CRYPTO_EX_DATA CRYPTO_EX_DATA; -typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int idx, - long argl, void* argp); #define CRYPTO_THREADID_set_callback wolfSSL_THREADID_set_callback #define CRYPTO_THREADID_set_numeric wolfSSL_THREADID_set_numeric #define CRYPTO_THREADID_current wolfSSL_THREADID_current diff --git a/wolfssl/openssl/dh.h b/wolfssl/openssl/dh.h index 0970f366f..b63b6c2d1 100644 --- a/wolfssl/openssl/dh.h +++ b/wolfssl/openssl/dh.h @@ -64,7 +64,7 @@ WOLFSSL_API WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh); WOLFSSL_API int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes); WOLFSSL_API int wolfSSL_DH_size(WOLFSSL_DH*); WOLFSSL_API int wolfSSL_DH_generate_key(WOLFSSL_DH*); -WOLFSSL_API int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* pub, +WOLFSSL_API int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* pub, WOLFSSL_DH*); WOLFSSL_API int wolfSSL_DH_LoadDer(WOLFSSL_DH*, const unsigned char*, int sz); WOLFSSL_API int wolfSSL_DH_set0_pqg(WOLFSSL_DH*, WOLFSSL_BIGNUM*, @@ -80,10 +80,10 @@ WOLFSSL_API int wolfSSL_DH_set0_pqg(WOLFSSL_DH*, WOLFSSL_BIGNUM*, #define DH_size wolfSSL_DH_size #define DH_generate_key wolfSSL_DH_generate_key #define DH_compute_key wolfSSL_DH_compute_key -#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L #define DH_set0_pqg wolfSSL_DH_set0_pqg -#endif #define DH_get0_pqg wolfSSL_DH_get0_pqg +#define DH_get0_key wolfSSL_DH_get0_key +#define DH_set0_key wolfSSL_DH_set0_key #define DH_bits(x) (BN_num_bits(x->p)) #define DH_GENERATOR_2 2 diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index abf47ef5f..28741cc89 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -157,6 +157,9 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p, const unsigned char *buf, size_t len, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +WOLFSSL_EC_KEY *wolfSSL_o2i_ECPublicKey(WOLFSSL_EC_KEY **a, const unsigned char **in, + long len); +WOLFSSL_API int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out); WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY **key, const unsigned char **in, @@ -207,6 +210,7 @@ void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag); WOLFSSL_API int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, const WOLFSSL_EC_POINT *pub); +WOLFSSL_API int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key); WOLFSSL_API int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key); WOLFSSL_API int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, int digestSz, unsigned char *sig, @@ -299,6 +303,7 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_KEY_generate_key wolfSSL_EC_KEY_generate_key #define EC_KEY_set_asn1_flag wolfSSL_EC_KEY_set_asn1_flag #define EC_KEY_set_public_key wolfSSL_EC_KEY_set_public_key +#define EC_KEY_check_key wolfSSL_EC_KEY_check_key #define ECDSA_size wolfSSL_ECDSA_size #define ECDSA_sign wolfSSL_ECDSA_sign @@ -341,6 +346,7 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_POINT_oct2point wolfSSL_EC_POINT_oct2point #define EC_POINT_point2bn wolfSSL_EC_POINT_point2bn #define EC_POINT_is_on_curve wolfSSL_EC_POINT_is_on_curve +#define o2i_ECPublicKey wolfSSL_o2i_ECPublicKey #define i2o_ECPublicKey wolfSSL_i2o_ECPublicKey #define i2d_EC_PUBKEY wolfSSL_i2o_ECPublicKey #define d2i_ECPrivateKey wolfSSL_d2i_ECPrivateKey diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 44e4c3362..0261a1391 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -785,6 +785,7 @@ typedef WOLFSSL_ASN1_PCTX ASN1_PCTX; #define EVP_MD_CTX_type wolfSSL_EVP_MD_CTX_type #define EVP_MD_CTX_size wolfSSL_EVP_MD_CTX_size #define EVP_MD_CTX_block_size wolfSSL_EVP_MD_CTX_block_size +#define EVP_MD_block_size wolfSSL_EVP_MD_block_size #define EVP_MD_type wolfSSL_EVP_MD_type #ifndef NO_WOLFSSL_STUB #define EVP_MD_CTX_set_flags(...) diff --git a/wolfssl/openssl/hmac.h b/wolfssl/openssl/hmac.h index 8158afa9a..99b39be7f 100644 --- a/wolfssl/openssl/hmac.h +++ b/wolfssl/openssl/hmac.h @@ -35,9 +35,17 @@ #include "prefix_hmac.h" #endif +#include + +typedef struct WOLFSSL_HMAC_CTX { + Hmac hmac; + int type; + word32 save_ipad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/ + word32 save_opad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; +} WOLFSSL_HMAC_CTX; + #include #include -#include #ifdef __cplusplus extern "C" { @@ -49,22 +57,13 @@ WOLFSSL_API unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const unsigned char* d, int n, unsigned char* md, unsigned int* md_len); - -typedef struct WOLFSSL_HMAC_CTX { - Hmac hmac; - int type; - word32 save_ipad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/ - word32 save_opad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; -} WOLFSSL_HMAC_CTX; - - WOLFSSL_API WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void); WOLFSSL_API int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx); WOLFSSL_API int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, WOLFSSL_HMAC_CTX* src); WOLFSSL_LOCAL int wolfSSL_HmacCopy(Hmac* des, Hmac* src); WOLFSSL_API int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, - int keylen, const EVP_MD* type); + int keylen, const WOLFSSL_EVP_MD* type); WOLFSSL_API int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen, const EVP_MD* type, WOLFSSL_ENGINE* e); WOLFSSL_API int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, @@ -75,6 +74,7 @@ WOLFSSL_API int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx); WOLFSSL_API void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx); WOLFSSL_API void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx); WOLFSSL_API size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx); +WOLFSSL_API const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx); typedef struct WOLFSSL_HMAC_CTX HMAC_CTX; @@ -92,6 +92,7 @@ typedef struct WOLFSSL_HMAC_CTX HMAC_CTX; #define HMAC_Final wolfSSL_HMAC_Final #define HMAC_cleanup wolfSSL_HMAC_cleanup #define HMAC_size wolfSSL_HMAC_size +#define HMAC_CTX_get_md wolfSSL_HMAC_CTX_get_md #ifdef __cplusplus diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h index b509793cf..fb2fc0b81 100644 --- a/wolfssl/openssl/opensslv.h +++ b/wolfssl/openssl/opensslv.h @@ -30,7 +30,7 @@ defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x10100000L) ||\ defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x10001040L) /* valid version */ -#elif defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIBEST) +#elif defined(WOLFSSL_APACHE_HTTPD) || defined(HAVE_LIBEST) || defined(WOLFSSL_BIND) /* For Apache httpd, Use 1.1.0 compatibility */ #define OPENSSL_VERSION_NUMBER 0x10100000L #elif defined(WOLFSSL_QT) diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index c1bf4437f..25594f167 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -144,12 +144,22 @@ WOLFSSL_API int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *met WOLFSSL_API const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa); WOLFSSL_API const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_default_method(void); +WOLFSSL_API void wolfSSL_RSA_get0_crt_params(const WOLFSSL_RSA *r, + const WOLFSSL_BIGNUM **dmp1, + const WOLFSSL_BIGNUM **dmq1, + const WOLFSSL_BIGNUM **iqmp); +WOLFSSL_API int wolfSSL_RSA_set0_crt_params(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *dmp1, + WOLFSSL_BIGNUM *dmq1, WOLFSSL_BIGNUM *iqmp); +WOLFSSL_API void wolfSSL_RSA_get0_factors(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **p, + const WOLFSSL_BIGNUM **q); +WOLFSSL_API int wolfSSL_RSA_set0_factors(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *p, WOLFSSL_BIGNUM *q); WOLFSSL_API void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n, const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d); WOLFSSL_API int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, WOLFSSL_BIGNUM *d); WOLFSSL_API int wolfSSL_RSA_flags(const WOLFSSL_RSA *r); WOLFSSL_API void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags); +WOLFSSL_API int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *r, int flags); WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa); @@ -194,10 +204,15 @@ WOLFSSL_API int wolfSSL_RSA_set_ex_data_with_cleanup( #define RSA_get_default_method wolfSSL_RSA_get_default_method #define RSA_get_method wolfSSL_RSA_get_method #define RSA_set_method wolfSSL_RSA_set_method +#define RSA_get0_crt_params wolfSSL_RSA_get0_crt_params +#define RSA_set0_crt_params wolfSSL_RSA_set0_crt_params +#define RSA_get0_factors wolfSSL_RSA_get0_factors +#define RSA_set0_factors wolfSSL_RSA_set0_factors #define RSA_get0_key wolfSSL_RSA_get0_key #define RSA_set0_key wolfSSL_RSA_set0_key #define RSA_flags wolfSSL_RSA_flags #define RSA_set_flags wolfSSL_RSA_set_flags +#define RSA_test_flags wolfSSL_RSA_test_flags #define RSAPublicKey_dup wolfSSL_RSAPublicKey_dup #define RSA_get_ex_data wolfSSL_RSA_get_ex_data diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 87e1a623d..77a73fb06 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -4234,7 +4234,12 @@ WOLFSSL_API void *wolfSSL_OPENSSL_memdup(const void *data, WOLFSSL_API void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len); WOLFSSL_API void wolfSSL_ERR_load_BIO_strings(void); WOLFSSL_API void wolfSSL_DH_get0_pqg(const WOLFSSL_DH* dh, -const WOLFSSL_BIGNUM** p, const WOLFSSL_BIGNUM** q, const WOLFSSL_BIGNUM** g); + const WOLFSSL_BIGNUM** p, const WOLFSSL_BIGNUM** q, + const WOLFSSL_BIGNUM** g); +WOLFSSL_API void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, + const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key); +WOLFSSL_API int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key, + WOLFSSL_BIGNUM *priv_key); #endif #if defined(HAVE_OCSP) && !defined(NO_ASN_TIME) From 06ebcca913363d88f0fa777ff542de05795cc8f4 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 1 Jun 2021 17:36:03 +0200 Subject: [PATCH 02/11] Code review and mp_int memory leak fixes --- configure.ac | 3 +++ src/ssl.c | 28 ++++++++++++++++------------ tests/api.c | 9 +++++++-- wolfcrypt/src/ecc.c | 5 +++++ wolfcrypt/src/evp.c | 8 ++++---- wolfssl/openssl/crypto.h | 4 ++-- 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index eb73ae170..5f6a226c9 100644 --- a/configure.ac +++ b/configure.ac @@ -4378,6 +4378,9 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_BIND" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DWOLFSSL_DES_ECB" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA224 -DWOLFSSL_SHA384 -DWOLFSSL_SHA512" + ENABLED_SHA224="yes" + ENABLED_SHA384="yes" + ENABLED_SHA512="yes" fi if test "$ENABLED_OPENVPN" = "yes" diff --git a/src/ssl.c b/src/ssl.c index 30c95c840..f7e33db4a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -30146,6 +30146,9 @@ int SetDhInternal(WOLFSSL_DH* dh) } #endif /* WOLFSSL_SMALL_STACK */ + /* Free so that mp_init's don't leak */ + wc_FreeDhKey((DhKey*)dh->internal); + #ifdef WOLFSSL_DH_EXTRA privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv_key); pubSz = wolfSSL_BN_bn2bin(dh->pub_key, pub_key); @@ -43615,6 +43618,7 @@ int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generat WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex"); (void)callback; + (void)generator; if (dh == NULL) { WOLFSSL_MSG("Bad parameter"); @@ -43626,23 +43630,21 @@ int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generat return WOLFSSL_FAILURE; } - if (dh->inSet == 0) { - if (SetDhInternal(dh) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Unable to set internal DH structure"); - return WOLFSSL_FAILURE; - } - } + /* Don't need SetDhInternal call since we are generating + * parameters ourselves */ key = (DhKey*)dh->internal; - if (mp_set_int(&key->g, generator) != MP_OKAY) { - WOLFSSL_MSG("Unable to set generator"); - return WOLFSSL_FAILURE; - } + + /* Free so that mp_init's don't leak */ + wc_FreeDhKey(key); if (wc_DhGenerateParams(&globalRNG, prime_len, key) != 0) { WOLFSSL_MSG("wc_DhGenerateParams error"); return WOLFSSL_FAILURE; } + dh->inSet = 1; + + WOLFSSL_MSG("wolfSSL does not support using a custom generator."); if (SetDhExternal(dh) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("SetDhExternal error"); @@ -52491,9 +52493,11 @@ void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, WOLFSSL_ENTER("wolfSSL_DH_get0_key"); if (dh != NULL) { - if (pub_key != NULL) + if (pub_key != NULL && dh->pub_key != NULL && + wolfSSL_BN_is_zero(dh->pub_key) != WOLFSSL_SUCCESS) *pub_key = dh->pub_key; - if (priv_key != NULL) + if (priv_key != NULL && dh->priv_key != NULL && + wolfSSL_BN_is_zero(dh->priv_key) != WOLFSSL_SUCCESS) *priv_key = dh->priv_key; } } diff --git a/tests/api.c b/tests/api.c index 0c545006a..c0f46ab35 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2574,8 +2574,10 @@ static void test_EC_i2d(void) buf = NULL; AssertIntGT((len = i2o_ECPublicKey(key, &buf)), 0); - AssertNotNull(o2i_ECPublicKey(©, (const unsigned char **)&buf, len)); + tmp = buf; + AssertNotNull(o2i_ECPublicKey(©, &tmp, len)); AssertIntEQ(EC_KEY_check_key(key), 1); + XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL); EC_KEY_free(key); EC_KEY_free(copy); @@ -45900,7 +45902,7 @@ static void test_wolfSSL_DH(void) AssertNotNull(dh = d2i_DHparams(NULL, &pt, len)); AssertNotNull(dh->p); - AssertNotNull(dh->p); + AssertNotNull(dh->g); AssertTrue(pt != buf); AssertIntEQ(DH_generate_key(dh), WOLFSSL_SUCCESS); @@ -45920,6 +45922,9 @@ static void test_wolfSSL_DH(void) AssertPtrEq(priv, dh->priv_key); DH_free(dh); + + AssertNotNull(dh = DH_generate_parameters(2048, 2, NULL, NULL)); + DH_free(dh); #endif #endif printf(testingFmt, "test_wolfSSL_DH"); diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 83256a893..3085ac91e 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -7390,6 +7390,11 @@ int wc_ecc_import_point_der_ex(const byte* in, word32 inLen, return ECC_BAD_ARG_E; } + /* clear if previously allocated */ + mp_clear(point->x); + mp_clear(point->y); + mp_clear(point->z); + /* init point */ #ifdef ALT_ECC_SIZE point->x = (mp_int*)&point->xyz[0]; diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 8f4f9866b..96134c4d9 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -2345,8 +2345,8 @@ static enum wc_HashType wolfSSL_EVP_md2macType(const WOLFSSL_EVP_MD *md) const struct s_ent *ent ; if (md != NULL) { - for( ent = md_tbl; ent->name != NULL; ent++) { - if(XSTRNCMP((const char *)md, ent->name, XSTRLEN(ent->name)+1) == 0) { + for (ent = md_tbl; ent->name != NULL; ent++) { + if (XSTRNCMP((const char *)md, ent->name, XSTRLEN(ent->name)+1) == 0) { return ent->macType; } } @@ -2358,8 +2358,8 @@ static const WOLFSSL_EVP_MD* wolfSSL_macType2EVP_md(enum wc_HashType type) { const struct s_ent *ent ; - for( ent = md_tbl; ent->name != NULL; ent++) { - if(ent->macType == type) { + for (ent = md_tbl; ent->name != NULL; ent++) { + if (ent->macType == type) { return ent->name; } } diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 13b4794a0..b9ee29fe7 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -33,11 +33,11 @@ typedef WOLFSSL_INIT_SETTINGS OPENSSL_INIT_SETTINGS; typedef struct WOLFSSL_CRYPTO_THREADID { int dummy; -}WOLFSSL_CRYPTO_THREADID; +} WOLFSSL_CRYPTO_THREADID; typedef struct crypto_threadid_st CRYPTO_THREADID; typedef struct CRYPTO_EX_DATA CRYPTO_EX_DATA; -typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int idx, +typedef void (CRYPTO_free_func)(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx, long argl, void* argp); #include From 69948b364855170eaf46af3af4e52b3aaaf254c9 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 7 Jun 2021 15:37:58 +0200 Subject: [PATCH 03/11] WIP --- src/ssl.c | 39 +++++-- wolfcrypt/src/evp.c | 255 ++++++++++++++++++++++++-------------------- 2 files changed, 169 insertions(+), 125 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index f7e33db4a..cade505f7 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -32057,7 +32057,8 @@ int wolfSSL_RSA_set0_crt_params(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *dmp1, r->iqmp = iqmp; } - return WOLFSSL_SUCCESS; + return SetRsaInternal(r) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } void wolfSSL_RSA_get0_factors(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **p, @@ -32099,7 +32100,8 @@ int wolfSSL_RSA_set0_factors(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *p, WOLFSSL_BIGNUM * r->q = q; } - return WOLFSSL_SUCCESS; + return SetRsaInternal(r) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n, @@ -33842,7 +33844,8 @@ int SetECKeyInternal(WOLFSSL_EC_KEY* eckey) } /* private key */ - key->type = ECC_PRIVATEKEY; + if (!mp_iszero(&key->k)) + key->type = ECC_PRIVATEKEY; } eckey->inSet = 1; @@ -37908,7 +37911,7 @@ void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags) int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *r, int flags) { - return r ? r->meth->flags & flags : 0; + return r && r->meth ? r->meth->flags & flags : 0; } #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) @@ -38014,7 +38017,8 @@ int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, r->d = d; } - return 1; + return SetRsaInternal(r) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } #endif /* OPENSSL_EXTRA */ #endif /* NO_RSA */ @@ -38141,6 +38145,15 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal, derSz); } + if (ret < 0 && opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) { + /* Might be in PKCS8 format so let's try */ + idx = 0; + ret = ToTraditionalInline(derBuf, &idx, (word32)derSz); + if (ret > 0) { + ret = wc_EccPrivateKeyDecode(derBuf, &idx, + (ecc_key*)key->internal, derSz); + } + } if (ret < 0) { if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) { WOLFSSL_MSG("wc_EccPrivateKeyDecode failed"); @@ -48134,14 +48147,18 @@ int SetRsaInternal(WOLFSSL_RSA* rsa) key = (RsaKey*)rsa->internal; - if (SetIndividualInternal(rsa->n, &key->n) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa n key error"); - return WOLFSSL_FATAL_ERROR; + if (rsa->n != NULL) { + if (SetIndividualInternal(rsa->n, &key->n) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("rsa n key error"); + return WOLFSSL_FATAL_ERROR; + } } - if (SetIndividualInternal(rsa->e, &key->e) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa e key error"); - return WOLFSSL_FATAL_ERROR; + if (rsa->e != NULL) { + if (SetIndividualInternal(rsa->e, &key->e) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("rsa e key error"); + return WOLFSSL_FATAL_ERROR; + } } /* public key */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 96134c4d9..c7631828f 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -6060,48 +6060,123 @@ const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) } #ifndef NO_RSA -WOLFSSL_RSA* wolfSSL_EVP_PKEY_get0_RSA(WOLFSSL_EVP_PKEY *pkey) +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) +static int PopulateRSAEvpPkeyDer(WOLFSSL_EVP_PKEY *pkey) { - if (!pkey) { - return NULL; - } - return pkey->rsa; -} + int ret = 0; + int derSz = 0; + word32 pkcs8Sz = 0; + byte* derBuf = NULL; + RsaKey* rsa = NULL; + WOLFSSL_RSA *key = NULL; -WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key) -{ - WOLFSSL_RSA* local; - - WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA"); - - if (key == NULL) { - return NULL; + if (pkey == NULL || pkey->rsa == NULL || pkey->rsa->internal == NULL) { + WOLFSSL_MSG("bad parameter"); + return WOLFSSL_FAILURE; } - local = wolfSSL_RSA_new(); - if (local == NULL) { - WOLFSSL_MSG("Error creating a new WOLFSSL_RSA structure"); - return NULL; - } + key = pkey->rsa; + rsa = (RsaKey*)pkey->rsa->internal; - if (key->type == EVP_PKEY_RSA) { - if (wolfSSL_RSA_LoadDer(local, (const unsigned char*)key->pkey.ptr, - key->pkey_sz) != SSL_SUCCESS) { - /* now try public key */ - if (wolfSSL_RSA_LoadDer_ex(local, - (const unsigned char*)key->pkey.ptr, key->pkey_sz, - WOLFSSL_RSA_LOAD_PUBLIC) != SSL_SUCCESS) { - wolfSSL_RSA_free(local); - local = NULL; + /* Get DER size */ + if (rsa->type == RSA_PRIVATE) { + ret = wc_RsaKeyToDer(rsa, NULL, 0); + if (ret > 0) { + derSz = ret; + #ifdef HAVE_PKCS8 + if (key->pkcs8HeaderSz) { + ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, NULL, derSz, + RSAk, NULL, 0); + if (ret == LENGTH_ONLY_E) + ret = 0; } + #endif } } else { - WOLFSSL_MSG("WOLFSSL_EVP_PKEY does not hold an RSA key"); - wolfSSL_RSA_free(local); - local = NULL; + ret = wc_RsaKeyToPublicDer(rsa, NULL, 0); + if (ret > 0) + derSz = ret; } - return local; + + if (derSz == 0 || ret < 0) { + WOLFSSL_MSG("Error getting RSA DER size"); + return WOLFSSL_FAILURE; + } + + derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, + pkey->heap, DYNAMIC_TYPE_DER); + if (derBuf == NULL) { + WOLFSSL_MSG("EVP_PKEY_set1_RSA malloc failed"); + return WOLFSSL_FAILURE; + } + /* Old pointer is invalid from this point on */ + pkey->pkey.ptr = (char*)derBuf; + + if (rsa->type == RSA_PRIVATE) { + ret = wc_RsaKeyToDer(rsa, derBuf, derSz); + if (ret > 0) { + derSz = ret; + #ifdef HAVE_PKCS8 + if (key->pkcs8HeaderSz) { + byte* keyBuf = derBuf; + int keySz = derSz; + derSz = pkcs8Sz; + /* Need new buffer for PKCS8 since we can't + * do this in-place */ + derBuf = (byte*)XMALLOC(pkcs8Sz, pkey->heap, + DYNAMIC_TYPE_DER); + if (derBuf != NULL) { + ret = wc_CreatePKCS8Key(derBuf, (word32*)&derSz, keyBuf, + keySz, RSAk, NULL, 0); + XFREE(keyBuf, pkey->heap, DYNAMIC_TYPE_DER); + pkey->pkey.ptr = (char*)derBuf; + } + else + ret = MEMORY_E; + } + #endif + } + } + else { + /* Public key to DER */ + ret = wc_RsaKeyToPublicDer(rsa, derBuf, derSz); + if (ret > 0) + derSz = ret; + } + + if (ret < 0) { + WOLFSSL_MSG("PopulateRSAEvpPkeyDer failed"); + return WOLFSSL_FAILURE; + } + else { + pkey->pkey_sz = derSz; + return WOLFSSL_SUCCESS; + } +} +#endif + +WOLFSSL_RSA* wolfSSL_EVP_PKEY_get0_RSA(WOLFSSL_EVP_PKEY *pkey) +{ + WOLFSSL_MSG("wolfSSL_EVP_PKEY_get0_RSA"); + + if (pkey == NULL) + return NULL; + + return pkey->rsa; +} + +WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* pkey) +{ + WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_RSA"); + + if (pkey == NULL || pkey->rsa == NULL) + return NULL; + + if (wolfSSL_RSA_up_ref(pkey->rsa) != WOLFSSL_SUCCESS) + return NULL; + + return pkey->rsa; } /* with set1 functions the pkey struct does not own the RSA structure @@ -6110,13 +6185,6 @@ WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key) */ int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key) { -#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA) - int ret; - int derSz = 0; - int pkcs8Sz = 0; - byte* derBuf = NULL; - RsaKey* rsa = NULL; -#endif WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_RSA"); if (pkey == NULL || key == NULL) return WOLFSSL_FAILURE; @@ -6140,82 +6208,12 @@ int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key) } } -#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA) - rsa = (RsaKey*)key->internal; - - /* Get DER size */ - derSz = 0; - if (rsa->type == RSA_PRIVATE) { - ret = wc_RsaKeyToDer(rsa, NULL, 0); - if (ret > 0) { - derSz = ret; - #ifdef HAVE_PKCS8 - if (key->pkcs8HeaderSz) { - ret = wc_CreatePKCS8Key(NULL, (word32*)&pkcs8Sz, NULL, derSz, - RSAk, NULL, 0); - if (ret == LENGTH_ONLY_E) ret = 0; - } - #endif - } - } - else { - ret = wc_RsaKeyToPublicDer(rsa, NULL, 0); - if (ret > 0) - derSz = ret; - } - - if (ret >= 0 && derSz >= 0) { - derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_DER); - if (derBuf == NULL) { - WOLFSSL_MSG("EVP_PKEY_set1_RSA malloc failed"); - return WOLFSSL_FAILURE; - } - - if (rsa->type == RSA_PRIVATE) { - ret = wc_RsaKeyToDer(rsa, derBuf, derSz); - if (ret > 0) { - derSz = ret; - #ifdef HAVE_PKCS8 - if (key->pkcs8HeaderSz) { - byte* keyBuf = derBuf; - int keySz = derSz; - derSz = pkcs8Sz; - derBuf = (byte*)XMALLOC(pkcs8Sz, pkey->heap, - DYNAMIC_TYPE_DER); - if (derBuf == NULL) - ret = MEMORY_E; - else { - ret = wc_CreatePKCS8Key(derBuf, (word32*)&derSz, keyBuf, - keySz, RSAk, NULL, 0); - } - XFREE(keyBuf, pkey->heap, DYNAMIC_TYPE_DER); - } - #endif - } - } - else { - /* Public key to DER */ - ret = wc_RsaKeyToPublicDer(rsa, derBuf, derSz); - if (ret > 0) - derSz = ret; - } - } - - if (ret < 0) { - if (rsa->type == RSA_PRIVATE) { - WOLFSSL_MSG("EVP_PKEY_set1_RSA private failed"); - } - else { - WOLFSSL_MSG("EVP_PKEY_set1_RSA public failed"); - } - if (derBuf) - XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_DER); +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) + if (PopulateRSAEvpPkeyDer(pkey) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("PopulateRSAEvpPkeyDer failed"); return WOLFSSL_FAILURE; } - - pkey->pkey.ptr = (char*)derBuf; - pkey->pkey_sz = derSz; -#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !HAVE_USER_RSA */ +#endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ #ifdef WC_RSA_BLINDING if (key->ownRng == 0) { @@ -6565,6 +6563,7 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key) /* try and populate public pkey_sz and pkey.ptr */ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) { +<<<<<<< master int derSz = 0; ecc_key* ecc; @@ -6588,11 +6587,24 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) } else { XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL); +======= + word32 derSz = 0; + byte* derBuf = NULL; + if (!pkey || !ecc) + return WOLFSSL_FAILURE; + if (ecc->type == ECC_PRIVATEKEY || ecc->type == ECC_PRIVATEKEY_ONLY) { + if (wc_EccKeyToPKCS8(ecc, NULL, &derSz) == LENGTH_ONLY_E) { + derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); + if (derBuf != NULL) { + if (wc_EccKeyToPKCS8(ecc, derBuf, &derSz) < 0) { + XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); +>>>>>>> WIP derBuf = NULL; } } } } +<<<<<<< master else { /* if not, the pkey will be traditional ecc key */ if ((derSz = wc_EccKeyDerSize(ecc, 1)) > 0) { @@ -6608,12 +6620,27 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) } else { XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL); +======= + else if (ecc->type == ECC_PUBLICKEY) { + if ((derSz = (word32)wc_EccPublicKeyDerSize(ecc, 1)) > 0) { + derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); + if (derBuf != NULL) { + if (wc_EccPublicKeyToDer(ecc, derBuf, derSz, 1) < 0) { + XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); +>>>>>>> WIP derBuf = NULL; } } } } - return WOLFSSL_FAILURE; + if (derBuf != NULL) { + pkey->pkey_sz = (int)derSz; + pkey->pkey.ptr = (char*)derBuf; + return WOLFSSL_SUCCESS; + } + else { + return WOLFSSL_FAILURE; + } } int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) From 763aa9b66ddec37db91152db6c420a645f13cf62 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 9 Jun 2021 19:09:46 +0200 Subject: [PATCH 04/11] Fix race condition with RsaKey When RsaKey is shared and RsaPublicEncryptEx is called simultaneously by multiple threads, the key->state may be incorrectly set in some threads. This side-steps the state logic when building for bind9. --- wolfcrypt/src/rsa.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 0799dfd7e..60dabae18 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -2930,7 +2930,7 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, byte* label, word32 labelSz, int saltLen, WC_RNG* rng) { - int ret, sz; + int ret, sz, state; if (in == NULL || inLen == 0 || out == NULL || key == NULL) { return BAD_FUNC_ARG; @@ -2954,7 +2954,17 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, return RSA_BUFFER_E; } - switch (key->state) { +#ifndef WOLFSSL_BIND + state = key->state; +#else + /* Bind9 shares the EVP_PKEY struct across multiple threads so let's just + * force a restart on each RsaPublicEncryptEx call for it. */ + state = RSA_STATE_NONE; +#ifdef WOLFSSL_ASYNC_CRYPT +#error wolfSSL does not handle building bind support with async crypto +#endif +#endif + switch (state) { case RSA_STATE_NONE: case RSA_STATE_ENCRYPT_PAD: #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \ From 553c930ecb3908bf2f4c89fa01bdcfed0cb091a6 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 10 Jun 2021 23:44:04 +0200 Subject: [PATCH 05/11] dot system test passed --- src/ssl.c | 25 +++++++++++++++++++++++++ src/wolfio.c | 12 ++++++++++++ wolfcrypt/src/evp.c | 14 ++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index cade505f7..61235df8c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -42164,6 +42164,31 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) return WOLFSSL_FAILURE; } + switch (pkey->type) { +#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) + case EVP_PKEY_RSA: + WOLFSSL_MSG("populating RSA key"); + if (PopulateRSAEvpPkeyDer(pkey) != WOLFSSL_SUCCESS) + return WOLFSSL_FAILURE; + break; +#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */ +#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \ + defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA) + case EVP_PKEY_DSA: + break; +#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */ +#ifdef HAVE_ECC + case EVP_PKEY_EC: + WOLFSSL_MSG("populating ECC key"); + if (ECC_populate_EVP_PKEY(pkey, (ecc_key*)pkey->ecc->internal) + != WOLFSSL_SUCCESS) + return WOLFSSL_FAILURE; + break; +#endif + default: + return WOLFSSL_FAILURE; + } + if (pkey->pkey.ptr != NULL) { /* ptr for WOLFSSL_EVP_PKEY struct is expected to be DER format */ return wolfSSL_CTX_use_PrivateKey_buffer(ctx, diff --git a/src/wolfio.c b/src/wolfio.c index 131e74122..5be99ed0a 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -167,6 +167,12 @@ int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx) if (recvd <= 0) { if (wolfSSL_BIO_supports_pending(ssl->biord) && wolfSSL_BIO_ctrl_pending(ssl->biord) == 0) { + if (ssl->biowr->type == WOLFSSL_BIO_BIO && + ssl->biowr->wrIdx != 0) { + /* Let's signal to the app layer that we have + * data pending that needs to be sent. */ + return WOLFSSL_CBIO_ERR_WANT_WRITE; + } return WOLFSSL_CBIO_ERR_WANT_READ; } else if (ssl->biord->type == WOLFSSL_BIO_SOCKET) { @@ -224,6 +230,12 @@ int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) #endif return sent; } + else if (ssl->biowr->type == WOLFSSL_BIO_BIO) { + if (sent == WOLFSSL_BIO_ERROR) { + WOLFSSL_MSG("\tWould Block"); + return WOLFSSL_CBIO_ERR_WANT_WRITE; + } + } /* If retry and write flags are set, return WANT_WRITE */ if ((ssl->biord->flags & WOLFSSL_BIO_FLAG_WRITE) && diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index c7631828f..55c3cd2fe 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -6593,6 +6593,7 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) if (!pkey || !ecc) return WOLFSSL_FAILURE; if (ecc->type == ECC_PRIVATEKEY || ecc->type == ECC_PRIVATEKEY_ONLY) { +#ifdef HAVE_PKCS8 if (wc_EccKeyToPKCS8(ecc, NULL, &derSz) == LENGTH_ONLY_E) { derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); if (derBuf != NULL) { @@ -6603,6 +6604,19 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) } } } +#else + derSz = (word32)wc_EccKeyDerSize(ecc, 1); + if (derSz > 0) { + derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); + if (derBuf != NULL) { + if (wc_EccKeyToDer(ecc, derBuf, derSz) < 0) { + XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); + derBuf = NULL; + } + } + } + +#endif /* HAVE_PKCS8 */ } <<<<<<< master else { From 142ff6d88530ace35d7e3d89a3add6fc37d9684f Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 15 Jun 2021 17:13:29 +0200 Subject: [PATCH 06/11] Bind 9.11.22 --- configure.ac | 4 +- src/ssl.c | 290 ++++++++++++++++++++++++++++++++++++++-- tests/api.c | 50 ++++++- wolfcrypt/src/asn.c | 4 +- wolfcrypt/src/dsa.c | 6 + wolfcrypt/src/evp.c | 40 ++++-- wolfssl/openssl/dsa.h | 30 ++++- wolfssl/openssl/rsa.h | 2 + wolfssl/openssl/ssl.h | 3 + wolfssl/ssl.h | 4 + wolfssl/wolfcrypt/asn.h | 4 +- 11 files changed, 408 insertions(+), 29 deletions(-) diff --git a/configure.ac b/configure.ac index 5f6a226c9..684232f3a 100644 --- a/configure.ac +++ b/configure.ac @@ -2005,7 +2005,7 @@ AC_ARG_ENABLE([dsa], [ ENABLED_DSA=no ] ) -if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_NGINX" = "yes" || test "$ENABLED_WPAS" = "yes" || test "$ENABLED_QT" = "yes" +if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_NGINX" = "yes" || test "$ENABLED_WPAS" = "yes" || test "$ENABLED_QT" = "yes" || test "$ENABLED_BIND" = "yes" then ENABLED_DSA="yes" fi @@ -4375,7 +4375,7 @@ fi if test "$ENABLED_BIND" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_BIND" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_BIND -DWOLFSSL_DSA_768_MODULUS" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DWOLFSSL_DES_ECB" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA224 -DWOLFSSL_SHA384 -DWOLFSSL_SHA512" ENABLED_SHA224="yes" diff --git a/src/ssl.c b/src/ssl.c index 61235df8c..ad0dc49d1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -31428,6 +31428,68 @@ int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, return ret; } +void wolfSSL_DSA_get0_pqg(const WOLFSSL_DSA *d, const WOLFSSL_BIGNUM **p, + const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g) +{ + WOLFSSL_ENTER("wolfSSL_DSA_get0_pqg"); + if (d != NULL) { + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; + } +} + +int wolfSSL_DSA_set0_pqg(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *p, + WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g) +{ + WOLFSSL_ENTER("wolfSSL_DSA_set0_pqg"); + if (d == NULL || p == NULL || q == NULL || g == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + wolfSSL_BN_free(d->p); + wolfSSL_BN_free(d->q); + wolfSSL_BN_free(d->g); + d->p = p; + d->q = q; + d->g = g; + return WOLFSSL_SUCCESS; +} + +void wolfSSL_DSA_get0_key(const WOLFSSL_DSA *d, + const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key) +{ + WOLFSSL_ENTER("wolfSSL_DSA_get0_key"); + if (d != NULL) { + if (pub_key != NULL) + *pub_key = d->pub_key; + if (priv_key != NULL) + *priv_key = d->priv_key; + } +} + +int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key, + WOLFSSL_BIGNUM *priv_key) +{ + WOLFSSL_ENTER("wolfSSL_DSA_set0_key"); + + /* The private key may be NULL */ + if (pub_key == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + wolfSSL_BN_free(d->pub_key); + wolfSSL_BN_free(d->priv_key); + d->pub_key = pub_key; + d->priv_key = priv_key; + + return WOLFSSL_SUCCESS; +} + WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void) { WOLFSSL_DSA_SIG* sig; @@ -31438,6 +31500,34 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void) return sig; } +/** + * Same as wolfSSL_DSA_SIG_new but also initializes the internal bignums as well. + * @return New WOLFSSL_DSA_SIG with r and s created as well + */ +static WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new_bn(void) +{ + WOLFSSL_DSA_SIG* ret; + + if ((ret = wolfSSL_DSA_SIG_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_DSA_SIG_new error"); + return NULL; + } + + if ((ret->r = wolfSSL_BN_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_BN_new error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } + + if ((ret->s = wolfSSL_BN_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_BN_new error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } + + return ret; +} + void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig) { WOLFSSL_ENTER("wolfSSL_DSA_SIG_free"); @@ -31452,6 +31542,158 @@ void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig) } } +void wolfSSL_DSA_SIG_get0(const WOLFSSL_DSA_SIG *sig, + const WOLFSSL_BIGNUM **r, const WOLFSSL_BIGNUM **s) +{ + WOLFSSL_ENTER("wolfSSL_DSA_SIG_get0"); + if (sig != NULL) { + *r = sig->r; + *s = sig->s; + } +} + +int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r, + WOLFSSL_BIGNUM *s) +{ + WOLFSSL_ENTER("wolfSSL_DSA_SIG_set0"); + if (r == NULL || s == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + wolfSSL_BN_clear_free(sig->r); + wolfSSL_BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + + return WOLFSSL_SUCCESS; +} + +/** + * + * @param sig The input signature to encode + * @param out The output buffer. If *out is NULL then a new buffer is + * allocated. Otherwise the output is written to the buffer. + * @return length on success and -1 on error + */ +int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out) +{ + /* Space for sequence + two asn ints */ + byte buf[MAX_SEQ_SZ + 2*(ASN_TAG_SZ + MAX_LENGTH_SZ + DSA_HALF_SIZE)]; + word32 bufLen = sizeof(buf); + + WOLFSSL_ENTER("wolfSSL_i2d_DSA_SIG"); + + if (sig == NULL || sig->r == NULL || sig->s == NULL || + out == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return WOLFSSL_FATAL_ERROR; + } + + if (StoreECC_DSA_Sig(buf, &bufLen, + (mp_int*)sig->r->internal, (mp_int*)sig->s->internal) != 0) { + WOLFSSL_MSG("StoreECC_DSA_Sig error"); + return WOLFSSL_FATAL_ERROR; + } + + if (*out == NULL) { + byte* tmp = (byte*)XMALLOC(bufLen, NULL, DYNAMIC_TYPE_ASN1); + if (tmp == NULL) { + WOLFSSL_MSG("malloc error"); + return WOLFSSL_FATAL_ERROR; + } + *out = tmp; + } + + XMEMCPY(*out, buf, bufLen); + + return (int)bufLen; +} + +/** + * This parses a DER encoded ASN.1 structure. The ASN.1 encoding is: + * ASN1_SEQUENCE + * ASN1_INTEGER (DSA r) + * ASN1_INTEGER (DSA s) + * Alternatively, if the input is DSA_SIG_SIZE in length then this + * API interprets this as two unsigned binary numbers. + * @param sig If non-null then free'd first and then newly created + * WOLFSSL_DSA_SIG is assigned + * @param pp Input buffer that is moved forward on success + * @param length Length of input buffer + * @return Newly created WOLFSSL_DSA_SIG on success or NULL on failure + */ +WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig, + const unsigned char **pp, long length) +{ + WOLFSSL_DSA_SIG* ret; + mp_int* r; + mp_int* s; + + WOLFSSL_ENTER("wolfSSL_d2i_DSA_SIG"); + + if (pp == NULL || *pp == NULL || length < 0) { + WOLFSSL_MSG("Bad function arguments"); + return NULL; + } + + if ((ret = wolfSSL_DSA_SIG_new_bn()) == NULL) { + WOLFSSL_MSG("wolfSSL_DSA_SIG_new_bn error"); + return NULL; + } + + r = (mp_int*)ret->r->internal; + s = (mp_int*)ret->s->internal; + + if (length == DSA_SIG_SIZE) { + /* Two raw numbers of DSA_HALF_SIZE size each */ + if (mp_read_unsigned_bin(r, *pp, DSA_HALF_SIZE) != 0) { + WOLFSSL_MSG("r mp_read_unsigned_bin error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } + + if (mp_read_unsigned_bin(s, *pp + DSA_HALF_SIZE, DSA_HALF_SIZE) != 0) { + WOLFSSL_MSG("s mp_read_unsigned_bin error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } + + *pp += DSA_SIG_SIZE; + } + else { + if (DecodeECC_DSA_Sig(*pp, length, r, s) != 0) { + WOLFSSL_MSG("DecodeECC_DSA_Sig error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } +#ifndef NO_STRICT_ECDSA_LEN + *pp += length; +#else + { + /* We need to figure out how much to move by ourselves */ + word32 idx = 0; + int len = 0; + if (GetSequence(*pp, &idx, &len, (word32)length) < 0) { + WOLFSSL_MSG("GetSequence error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } + *pp += len; + } +#endif + } + + + if (sig != NULL) { + if (*sig != NULL) + wolfSSL_DSA_SIG_free(*sig); + *sig = ret; + } + + return ret; +} + /* return WOLFSSL_SUCCESS on success, < 0 otherwise */ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, WOLFSSL_DSA* dsa) @@ -31501,7 +31743,7 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, } if (rng) { - if (DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) + if (wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) WOLFSSL_MSG("DsaSign failed"); else ret = WOLFSSL_SUCCESS; @@ -31518,14 +31760,14 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, - int outLen, WOLFSSL_DSA* dsa) + int inLen, WOLFSSL_DSA* dsa) { WOLFSSL_DSA_SIG* sig = NULL; byte sigBin[DSA_SIG_SIZE]; WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex"); - if (!digest || !dsa || outLen != WC_SHA_DIGEST_SIZE) { + if (!digest || !dsa || inLen != WC_SHA_DIGEST_SIZE) { WOLFSSL_MSG("Bad function arguments"); return NULL; } @@ -37905,7 +38147,14 @@ int wolfSSL_RSA_flags(const WOLFSSL_RSA *r) void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags) { if (r && r->meth) { - r->meth->flags = flags; + r->meth->flags |= flags; + } +} + +void wolfSSL_RSA_clear_flags(WOLFSSL_RSA *r, int flags) +{ + if (r && r->meth) { + r->meth->flags &= ~flags; } } @@ -43620,8 +43869,34 @@ int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1, return WOLFSSL_FAILURE; } -void wolfSSL_CRYPTO_cleanup_all_ex_data(void) +int wolfSSL_CRYPTO_set_mem_functions( + wolfSSL_Malloc_cb m, + wolfSSL_Realloc_cb r, + wolfSSL_Free_cb f) { + if (wolfSSL_SetAllocators(m, f, r) == 0) + return WOLFSSL_SUCCESS; + else + return WOLFSSL_FAILURE; +} + +#ifndef NO_WOLFSSL_STUB +int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, + int), void (*f) (void *)) +{ + (void) m; + (void) r; + (void) f; + WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions"); + WOLFSSL_STUB("CRYPTO_set_mem_ex_functions"); + + return WOLFSSL_FAILURE; +} +#endif + + +void wolfSSL_CRYPTO_cleanup_all_ex_data(void){ WOLFSSL_ENTER("CRYPTO_cleanup_all_ex_data"); } @@ -50399,11 +50674,8 @@ int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi) static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn) { - if (bn) { + if (bn) XMEMSET(bn, 0, sizeof(WOLFSSL_BIGNUM)); - bn->neg = 0; - bn->internal = NULL; - } } diff --git a/tests/api.c b/tests/api.c index c0f46ab35..0a895fc54 100644 --- a/tests/api.c +++ b/tests/api.c @@ -35954,7 +35954,10 @@ static void test_wolfSSL_RSA_meth(void) AssertIntEQ(RSA_flags(rsa), RSA_METHOD_FLAG_NO_CHECK); RSA_set_flags(rsa, RSA_FLAG_CACHE_PUBLIC); AssertIntNE(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0); - AssertIntEQ(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC); + AssertIntEQ(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC | RSA_METHOD_FLAG_NO_CHECK); + RSA_clear_flags(rsa, RSA_FLAG_CACHE_PUBLIC); + AssertIntEQ(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0); + AssertIntNE(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC); /* rsa_meth is freed here */ RSA_free(rsa); @@ -38200,6 +38203,50 @@ static void test_wolfSSL_EVP_PKEY_set1_get1_DSA(void) #endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */ } /* END test_EVP_PKEY_set1_get1_DSA */ +static void test_wolfSSL_DSA_SIG(void) +{ +#if !defined (NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN) + DSA *dsa = NULL; + DSA *dsa2 = NULL; + DSA_SIG *sig = NULL; + const BIGNUM *p = NULL; + const BIGNUM *q = NULL; + const BIGNUM *g = NULL; + const BIGNUM *pub = NULL; + const BIGNUM *priv = NULL; + const byte digest[WC_SHA_DIGEST_SIZE] = {0}; + + printf(testingFmt, "wolfSSL_DSA_SIG"); + + AssertNotNull(dsa = DSA_generate_parameters(2048, + NULL, 0, NULL, NULL, NULL, NULL)); + DSA_free(dsa); + AssertNotNull(dsa = DSA_new()); + AssertIntEQ(DSA_generate_parameters_ex(dsa, 2048, + NULL, 0, NULL, NULL, NULL), 1); + AssertIntEQ(DSA_generate_key(dsa), 1); + DSA_get0_pqg(dsa, &p, &q, &g); + DSA_get0_key(dsa, &pub, &priv); + AssertNotNull(p = BN_dup(p)); + AssertNotNull(q = BN_dup(q)); + AssertNotNull(g = BN_dup(g)); + AssertNotNull(pub = BN_dup(pub)); + AssertNotNull(priv = BN_dup(priv)); + + AssertNotNull(sig = DSA_do_sign(digest, sizeof(digest), dsa)); + AssertNotNull(dsa2 = DSA_new()); + AssertIntEQ(DSA_set0_pqg(dsa2, (BIGNUM*)p, (BIGNUM*)q, (BIGNUM*)g), 1); + AssertIntEQ(DSA_set0_key(dsa2, (BIGNUM*)pub, (BIGNUM*)priv), 1); + AssertIntEQ(DSA_do_verify(digest, sizeof(digest), sig, dsa2), 1); + + printf(resultFmt, passed); + + DSA_free(dsa); + DSA_free(dsa2); + DSA_SIG_free(sig); +#endif +} + static void test_wolfSSL_EVP_PKEY_set1_get1_EC_KEY (void) { #ifdef HAVE_ECC @@ -46325,6 +46372,7 @@ void ApiTest(void) test_wolfSSL_ASN1_UNIVERSALSTRING_to_string(); test_wolfSSL_EC_KEY_dup(); test_wolfSSL_EVP_PKEY_set1_get1_DSA(); + test_wolfSSL_DSA_SIG(); test_wolfSSL_EVP_PKEY_set1_get1_EC_KEY(); test_wolfSSL_EVP_PKEY_set1_get1_DH(); test_wolfSSL_CTX_ctrl(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 7644b7d94..330c85e61 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -16128,7 +16128,7 @@ int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g) } #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */ -#ifdef HAVE_ECC +#if defined(HAVE_ECC) || !defined(NO_DSA) /* Der Encode r & s ints into out, outLen is (in/out) size */ int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s) @@ -16293,9 +16293,7 @@ int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen, return ret; } -#endif -#if defined(HAVE_ECC) || !defined(NO_DSA) int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s) { word32 idx = 0; diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 74254c518..3ea7e67aa 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -104,6 +104,9 @@ static int CheckDsaLN(int modLen, int divLen) int ret = -1; switch (modLen) { +#ifdef WOLFSSL_DSA_768_MODULUS + case 768: +#endif case 1024: if (divLen == 160) ret = 0; @@ -237,6 +240,9 @@ int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa) * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256) */ switch (modulus_size) { +#ifdef WOLFSSL_DSA_768_MODULUS + case 768: +#endif case 1024: qsize = 20; break; diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 55c3cd2fe..ec2bdc362 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1938,6 +1938,11 @@ int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey) return (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(pkey->rsa)); #endif /* !NO_RSA */ +#ifndef NO_DSA + case EVP_PKEY_DSA: + return DSA_SIG_SIZE; +#endif + #ifdef HAVE_ECC case EVP_PKEY_EC: if (pkey->ecc == NULL || pkey->ecc->internal == NULL) { @@ -2381,29 +2386,44 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int mdsize; unsigned char md[WC_MAX_DIGEST_SIZE]; int ret; - if (ctx == NULL) return WOLFSSL_FAILURE; - WOLFSSL_ENTER("EVP_SignFinal"); - - ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize); - if (ret <= 0) return ret; - (void)sigret; (void)siglen; + WOLFSSL_ENTER("EVP_SignFinal"); + if (ctx == NULL) + return WOLFSSL_FAILURE; + + ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize); + if (ret <= 0) + return ret; + switch (pkey->type) { #if !defined(NO_RSA) && !defined(HAVE_USER_RSA) case EVP_PKEY_RSA: { int nid; - const WOLFSSL_EVP_MD *ctxmd = wolfSSL_EVP_MD_CTX_md(ctx); - if (ctxmd == NULL) break; + const WOLFSSL_EVP_MD *ctxmd; + + ctxmd = wolfSSL_EVP_MD_CTX_md(ctx); + if (ctxmd == NULL) + return WOLFSSL_FAILURE; + nid = wolfSSL_EVP_MD_type(ctxmd); - if (nid < 0) break; + if (nid < 0) + return WOLFSSL_FAILURE; return wolfSSL_RSA_sign(nid, md, mdsize, sigret, siglen, pkey->rsa); } #endif /* NO_RSA */ - +#ifndef NO_DSA case EVP_PKEY_DSA: + if (wolfSSL_DSA_do_sign(md, sigret, pkey->dsa) == WOLFSSL_SUCCESS) { + *siglen = DSA_SIG_SIZE; + return WOLFSSL_SUCCESS; + } + else { + return WOLFSSL_FAILURE; + } +#endif case EVP_PKEY_EC: WOLFSSL_MSG("not implemented"); FALL_THROUGH; diff --git a/wolfssl/openssl/dsa.h b/wolfssl/openssl/dsa.h index 6d6f5075b..12b947572 100644 --- a/wolfssl/openssl/dsa.h +++ b/wolfssl/openssl/dsa.h @@ -68,6 +68,17 @@ WOLFSSL_API int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA*, int bits, unsigned char* seed, int seedLen, int* counterRet, unsigned long* hRet, void* cb); +WOLFSSL_API void wolfSSL_DSA_get0_pqg(const WOLFSSL_DSA *d, const WOLFSSL_BIGNUM **p, + const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g); +WOLFSSL_API int wolfSSL_DSA_set0_pqg(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *p, + WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g); + +WOLFSSL_API void wolfSSL_DSA_get0_key(const WOLFSSL_DSA *d, + const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key); +WOLFSSL_API int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key, + WOLFSSL_BIGNUM *priv_key); + + WOLFSSL_API int wolfSSL_DSA_LoadDer(WOLFSSL_DSA*, const unsigned char*, int sz); WOLFSSL_API int wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA*, const unsigned char*, @@ -84,8 +95,17 @@ WOLFSSL_API int wolfSSL_DSA_bits(const WOLFSSL_DSA *d); WOLFSSL_API WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void); WOLFSSL_API void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig); + +WOLFSSL_API void wolfSSL_DSA_SIG_get0(const WOLFSSL_DSA_SIG *sig, + const WOLFSSL_BIGNUM **r, const WOLFSSL_BIGNUM **s); +WOLFSSL_API int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r, + WOLFSSL_BIGNUM *s); + +WOLFSSL_API int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out); +WOLFSSL_API WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig, + const unsigned char **pp, long length); WOLFSSL_API WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, - int outLen, WOLFSSL_DSA* dsa); + int inLen, WOLFSSL_DSA* dsa); WOLFSSL_API int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa); @@ -99,9 +119,17 @@ WOLFSSL_API int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest #define DSA_generate_key wolfSSL_DSA_generate_key #define DSA_generate_parameters wolfSSL_DSA_generate_parameters #define DSA_generate_parameters_ex wolfSSL_DSA_generate_parameters_ex +#define DSA_get0_pqg wolfSSL_DSA_get0_pqg +#define DSA_set0_pqg wolfSSL_DSA_set0_pqg +#define DSA_get0_key wolfSSL_DSA_get0_key +#define DSA_set0_key wolfSSL_DSA_set0_key #define DSA_SIG_new wolfSSL_DSA_SIG_new #define DSA_SIG_free wolfSSL_DSA_SIG_free +#define DSA_SIG_get0 wolfSSL_DSA_SIG_get0 +#define DSA_SIG_set0 wolfSSL_DSA_SIG_set0 +#define i2d_DSA_SIG wolfSSL_i2d_DSA_SIG +#define d2i_DSA_SIG wolfSSL_d2i_DSA_SIG #define DSA_do_sign wolfSSL_DSA_do_sign_ex #define DSA_do_verify wolfSSL_DSA_do_verify_ex diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index 25594f167..86c4dae9d 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -159,6 +159,7 @@ WOLFSSL_API int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_ WOLFSSL_BIGNUM *d); WOLFSSL_API int wolfSSL_RSA_flags(const WOLFSSL_RSA *r); WOLFSSL_API void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags); +WOLFSSL_API void wolfSSL_RSA_clear_flags(WOLFSSL_RSA *r, int flags); WOLFSSL_API int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *r, int flags); WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa); @@ -212,6 +213,7 @@ WOLFSSL_API int wolfSSL_RSA_set_ex_data_with_cleanup( #define RSA_set0_key wolfSSL_RSA_set0_key #define RSA_flags wolfSSL_RSA_flags #define RSA_set_flags wolfSSL_RSA_set_flags +#define RSA_clear_flags wolfSSL_RSA_clear_flags #define RSA_test_flags wolfSSL_RSA_test_flags #define RSAPublicKey_dup wolfSSL_RSAPublicKey_dup diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index b82c5a534..2f1cbb4b9 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -148,6 +148,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define CRYPTO_EX_free WOLFSSL_CRYPTO_EX_free #define CRYPTO_EX_DATA WOLFSSL_CRYPTO_EX_DATA +#define CRYPTO_set_mem_functions wolfSSL_CRYPTO_set_mem_functions + /* depreciated */ #define CRYPTO_thread_id wolfSSL_thread_id #define CRYPTO_set_id_callback wolfSSL_set_id_callback @@ -305,6 +307,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_pending wolfSSL_pending #define SSL_load_error_strings wolfSSL_load_error_strings #define SSL_library_init wolfSSL_library_init +#define OPENSSL_cleanup (void)wolfSSL_Cleanup #define OPENSSL_init_ssl wolfSSL_OPENSSL_init_ssl #define OpenSSL_add_ssl_algorithms wolfSSL_library_init #define SSL_CTX_set_session_cache_mode wolfSSL_CTX_set_session_cache_mode diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 77a73fb06..4c2cc555a 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3976,6 +3976,10 @@ WOLFSSL_API WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, #include +WOLFSSL_API int wolfSSL_CRYPTO_set_mem_functions( + wolfSSL_Malloc_cb m, + wolfSSL_Realloc_cb r, + wolfSSL_Free_cb f); WOLFSSL_API int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), void *(*r) (void *, size_t, const char *, int), void (*f) (void *)); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 0b3b1bd11..3d8967897 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1262,7 +1262,7 @@ WOLFSSL_LOCAL int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, WOLFSSL_LOCAL int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g); WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*); -#ifdef HAVE_ECC +#if defined(HAVE_ECC) || !defined(NO_DSA) /* ASN sig helpers */ WOLFSSL_LOCAL int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s); @@ -1270,8 +1270,6 @@ WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*); const byte* r, word32 rLen, const byte* s, word32 sLen); WOLFSSL_LOCAL int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen, byte* s, word32* sLen); -#endif -#if defined(HAVE_ECC) || !defined(NO_DSA) WOLFSSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s); #endif From c7d6e26437e596090e7c3dbc9340d633e64a428a Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 21 Jun 2021 19:57:25 +0200 Subject: [PATCH 07/11] Fix DSA signature length The length of the DSA signature is 40 bytes for N=160 but 64 bytes for N=256. New enum values are added for better clarity. --- src/ssl.c | 127 ++++++++++++++++++++++------------------ wolfcrypt/src/asn.c | 30 +++++----- wolfcrypt/src/dsa.c | 36 +++++++----- wolfcrypt/src/evp.c | 8 ++- wolfssl/wolfcrypt/dsa.h | 16 ++++- 5 files changed, 128 insertions(+), 89 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index ad0dc49d1..fd4f376d6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -31579,7 +31579,7 @@ int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r, int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out) { /* Space for sequence + two asn ints */ - byte buf[MAX_SEQ_SZ + 2*(ASN_TAG_SZ + MAX_LENGTH_SZ + DSA_HALF_SIZE)]; + byte buf[MAX_SEQ_SZ + 2*(ASN_TAG_SZ + MAX_LENGTH_SZ + DSA_MAX_HALF_SIZE)]; word32 bufLen = sizeof(buf); WOLFSSL_ENTER("wolfSSL_i2d_DSA_SIG"); @@ -31615,8 +31615,8 @@ int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out) * ASN1_SEQUENCE * ASN1_INTEGER (DSA r) * ASN1_INTEGER (DSA s) - * Alternatively, if the input is DSA_SIG_SIZE in length then this - * API interprets this as two unsigned binary numbers. + * Alternatively, if the input is DSA_160_SIG_SIZE or DSA_256_SIG_SIZE in + * length then this API interprets this as two unsigned binary numbers. * @param sig If non-null then free'd first and then newly created * WOLFSSL_DSA_SIG is assigned * @param pp Input buffer that is moved forward on success @@ -31645,28 +31645,31 @@ WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig, r = (mp_int*)ret->r->internal; s = (mp_int*)ret->s->internal; - if (length == DSA_SIG_SIZE) { - /* Two raw numbers of DSA_HALF_SIZE size each */ - if (mp_read_unsigned_bin(r, *pp, DSA_HALF_SIZE) != 0) { - WOLFSSL_MSG("r mp_read_unsigned_bin error"); - wolfSSL_DSA_SIG_free(ret); - return NULL; - } + if (DecodeECC_DSA_Sig(*pp, length, r, s) != 0) { + if (length == DSA_160_SIG_SIZE || length == DSA_256_SIG_SIZE) { + /* Two raw numbers of length/2 size each */ + if (mp_read_unsigned_bin(r, *pp, length/2) != 0) { + WOLFSSL_MSG("r mp_read_unsigned_bin error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } - if (mp_read_unsigned_bin(s, *pp + DSA_HALF_SIZE, DSA_HALF_SIZE) != 0) { - WOLFSSL_MSG("s mp_read_unsigned_bin error"); - wolfSSL_DSA_SIG_free(ret); - return NULL; - } + if (mp_read_unsigned_bin(s, *pp + (length/2), length/2) != 0) { + WOLFSSL_MSG("s mp_read_unsigned_bin error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } - *pp += DSA_SIG_SIZE; - } - else { - if (DecodeECC_DSA_Sig(*pp, length, r, s) != 0) { + *pp += length; + } + else { WOLFSSL_MSG("DecodeECC_DSA_Sig error"); wolfSSL_DSA_SIG_free(ret); return NULL; } + } + else { + /* DecodeECC_DSA_Sig success move pointer forward */ #ifndef NO_STRICT_ECDSA_LEN *pp += length; #else @@ -31684,7 +31687,6 @@ WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig, #endif } - if (sig != NULL) { if (*sig != NULL) wolfSSL_DSA_SIG_free(*sig); @@ -31714,10 +31716,8 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, return ret; } - if (dsa->inSet == 0) - { + if (dsa->inSet == 0) { WOLFSSL_MSG("No DSA internal set, do it"); - if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("SetDsaInternal failed"); return ret; @@ -31762,8 +31762,9 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, int inLen, WOLFSSL_DSA* dsa) { - WOLFSSL_DSA_SIG* sig = NULL; - byte sigBin[DSA_SIG_SIZE]; + byte sigBin[DSA_MAX_SIG_SIZE]; + const byte *tmp = sigBin; + int sigLen; WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex"); @@ -31773,27 +31774,23 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, } if (wolfSSL_DSA_do_sign(digest, sigBin, dsa) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_DSA_do_sign error"); return NULL; } - if (!(sig = wolfSSL_DSA_SIG_new())) { - goto error; + if (dsa->internal == NULL) { + WOLFSSL_MSG("dsa->internal is null"); + return NULL; } - if (!(sig->r = wolfSSL_BN_bin2bn(sigBin, DSA_HALF_SIZE, NULL))) { - goto error; + sigLen = mp_unsigned_bin_size(&((DsaKey*)dsa->internal)->q); + if (sigLen <= 0) { + WOLFSSL_MSG("mp_unsigned_bin_size error"); + return NULL; } - if (!(sig->s = wolfSSL_BN_bin2bn(sigBin + DSA_HALF_SIZE, DSA_HALF_SIZE, NULL))) { - goto error; - } - - return sig; -error: - if (sig) { - wolfSSL_DSA_SIG_free(sig); - } - return NULL; + /* 2 * sigLen for the two points r and s */ + return wolfSSL_d2i_DSA_SIG(NULL, &tmp, 2 * sigLen); } #endif /* !HAVE_SELFTEST && !HAVE_FIPS */ @@ -31842,8 +31839,10 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa) { int dsacheck, sz; - byte sigBin[DSA_SIG_SIZE]; + byte sigBin[DSA_MAX_SIG_SIZE]; byte* sigBinPtr = sigBin; + DsaKey* key; + int qSz; WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex"); @@ -31857,37 +31856,51 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, return WOLFSSL_FAILURE; } - /* front pad with zeros */ - if (!(sz = wolfSSL_BN_num_bytes(sig->r))) { - return WOLFSSL_FAILURE; - } - while (sz++ < DSA_HALF_SIZE) { - *sigBinPtr++ = 0; + if (dsa->inSet == 0) { + WOLFSSL_MSG("No DSA internal set, do it"); + if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetDsaInternal failed"); + return WOLFSSL_FAILURE; + } } - if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == WOLFSSL_FATAL_ERROR) { + key = dsa->internal; + + if (key == NULL) { + WOLFSSL_MSG("dsa->internal is null"); return WOLFSSL_FAILURE; } + qSz = mp_unsigned_bin_size(&key->q); + if (qSz < 0 || qSz > DSA_MAX_HALF_SIZE) { + WOLFSSL_MSG("mp_unsigned_bin_size error"); + return WOLFSSL_FAILURE; + } + + /* read r */ + /* front pad with zeros */ + if ((sz = wolfSSL_BN_num_bytes(sig->r)) < 0 || sz > DSA_MAX_HALF_SIZE) + return WOLFSSL_FAILURE; + while (sz++ < qSz) + *sigBinPtr++ = 0; + if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == WOLFSSL_FATAL_ERROR) + return WOLFSSL_FAILURE; + /* Move to s */ - sigBinPtr = sigBin + DSA_HALF_SIZE; + sigBinPtr = sigBin + qSz; + /* read s */ /* front pad with zeros */ - if (!(sz = wolfSSL_BN_num_bytes(sig->s))) { + if ((sz = wolfSSL_BN_num_bytes(sig->s)) < 0 || sz > DSA_MAX_HALF_SIZE) return WOLFSSL_FAILURE; - } - while (sz++ < DSA_HALF_SIZE) { + while (sz++ < qSz) *sigBinPtr++ = 0; - } - - if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == WOLFSSL_FATAL_ERROR) { + if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == WOLFSSL_FATAL_ERROR) return WOLFSSL_FAILURE; - } if (wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck) != WOLFSSL_SUCCESS || - dsacheck != 1) { + dsacheck != 1) return WOLFSSL_FAILURE; - } return WOLFSSL_SUCCESS; } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 330c85e61..70d8509a0 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -7709,7 +7709,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, { word32 idx = 0; - if (sigSz < DSA_SIG_SIZE) { + if (sigSz < DSA_MIN_SIG_SIZE) { WOLFSSL_MSG("Verify Signature is too small"); ERROR_OUT(BUFFER_E, exit_cs); } @@ -7729,10 +7729,12 @@ static int ConfirmSignature(SignatureCtx* sigCtx, WOLFSSL_MSG("ASN Key decode error DSA"); goto exit_cs; } - if (sigSz != DSA_SIG_SIZE) { - #ifdef HAVE_ECC + if (sigSz != DSA_160_SIG_SIZE && + sigSz != DSA_256_SIG_SIZE) { /* Try to parse it as the contents of a bitstring */ mp_int r, s; + int rSz; + int sSz; idx = 0; if (DecodeECC_DSA_Sig(sig + idx, sigSz - idx, &r, &s) != 0) { @@ -7740,25 +7742,25 @@ static int ConfirmSignature(SignatureCtx* sigCtx, "incorrect format"); ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs); } - if (mp_to_unsigned_bin_len(&r, sigCtx->sigCpy, - DSA_HALF_SIZE) != MP_OKAY || - mp_to_unsigned_bin_len(&s, - sigCtx->sigCpy + DSA_HALF_SIZE, - DSA_HALF_SIZE) != MP_OKAY) { + rSz = mp_unsigned_bin_size(&r); + sSz = mp_unsigned_bin_size(&s); + if (rSz + sSz > (int)sigSz) { + WOLFSSL_MSG("DSA Sig is in unrecognized or " + "incorrect format"); + ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs); + } + if (mp_to_unsigned_bin(&r, sigCtx->sigCpy) != MP_OKAY || + mp_to_unsigned_bin(&s, + sigCtx->sigCpy + rSz) != MP_OKAY) { WOLFSSL_MSG("DSA Sig is in unrecognized or " "incorrect format"); ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs); } mp_free(&r); mp_free(&s); - #else - WOLFSSL_MSG("DSA Sig is in unrecognized or " - "incorrect format"); - ERROR_OUT(ASN_SIG_CONFIRM_E, exit_cs); - #endif } else { - XMEMCPY(sigCtx->sigCpy, sig, DSA_SIG_SIZE); + XMEMCPY(sigCtx->sigCpy, sig, sigSz); } break; } diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 3ea7e67aa..c6d1a3519 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -241,6 +241,7 @@ int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa) */ switch (modulus_size) { #ifdef WOLFSSL_DSA_768_MODULUS + /* This key length is unsecure and only included for bind 9 testing */ case 768: #endif case 1024: @@ -685,10 +686,10 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) #ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME mp_int b[1]; #endif - byte buffer[DSA_HALF_SIZE]; + byte buffer[DSA_MAX_HALF_SIZE]; #endif mp_int* qMinus1; - int ret = 0, sz = 0; + int ret = 0, halfSz = 0; byte* tmp; /* initial output pointer */ do { @@ -707,7 +708,7 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) #ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME b = (mp_int *)XMALLOC(sizeof *b, key->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif - buffer = (byte *)XMALLOC(DSA_HALF_SIZE, key->heap, + buffer = (byte *)XMALLOC(DSA_MAX_HALF_SIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER); if ((k == NULL) || @@ -734,7 +735,7 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) break; } - sz = min(DSA_HALF_SIZE, mp_unsigned_bin_size(&key->q)); + halfSz = min(DSA_MAX_HALF_SIZE, mp_unsigned_bin_size(&key->q)); tmp = out; qMinus1 = kInv; @@ -751,12 +752,12 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) do { /* Step 4: generate k */ - if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) { + if ((ret = wc_RNG_GenerateBlock(rng, buffer, halfSz))) { break; } /* Step 5 */ - if (mp_read_unsigned_bin(k, buffer, sz) != MP_OKAY) { + if (mp_read_unsigned_bin(k, buffer, halfSz) != MP_OKAY) { ret = MP_READ_E; break; } @@ -820,10 +821,10 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) * Generate b in range [1, q-1]. */ do { - if ((ret = wc_RNG_GenerateBlock(rng, buffer, sz))) { + if ((ret = wc_RNG_GenerateBlock(rng, buffer, halfSz))) { break; } - if (mp_read_unsigned_bin(b, buffer, sz) != MP_OKAY) { + if (mp_read_unsigned_bin(b, buffer, halfSz) != MP_OKAY) { ret = MP_READ_E; break; } @@ -916,15 +917,15 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) int rSz = mp_unsigned_bin_size(r); int sSz = mp_unsigned_bin_size(s); - while (rSz++ < DSA_HALF_SIZE) { + while (rSz++ < halfSz) { *out++ = 0x00; /* pad front with zeros */ } if (mp_to_unsigned_bin(r, out) != MP_OKAY) ret = MP_TO_E; else { - out = tmp + DSA_HALF_SIZE; /* advance to s in output */ - while (sSz++ < DSA_HALF_SIZE) { + out = tmp + halfSz; /* advance to s in output */ + while (sSz++ < halfSz) { *out++ = 0x00; /* pad front with zeros */ } ret = mp_to_unsigned_bin(s, out); @@ -971,7 +972,7 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) } #else /* !WOLFSSL_SMALL_STACK */ if (ret != MP_INIT_E) { - ForceZero(buffer, sz); + ForceZero(buffer, halfSz); mp_forcezero(kInv); mp_forcezero(k); #ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME @@ -1000,6 +1001,7 @@ int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) mp_int w[1], u1[1], u2[1], v[1], r[1], s[1]; #endif int ret = 0; + int qSz; do { if (digest == NULL || sig == NULL || key == NULL || answer == NULL) { @@ -1031,9 +1033,15 @@ int wc_DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) break; } + qSz = mp_unsigned_bin_size(&key->q); + if (qSz <= 0) { + ret = BAD_FUNC_ARG; + break; + } + /* set r and s from signature */ - if (mp_read_unsigned_bin(r, sig, DSA_HALF_SIZE) != MP_OKAY || - mp_read_unsigned_bin(s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) { + if (mp_read_unsigned_bin(r, sig, qSz) != MP_OKAY || + mp_read_unsigned_bin(s, sig + qSz, qSz) != MP_OKAY) { ret = MP_READ_E; break; } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index ec2bdc362..f723b5467 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1940,7 +1940,11 @@ int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey) #ifndef NO_DSA case EVP_PKEY_DSA: - return DSA_SIG_SIZE; + if (pkey->dsa == NULL || + (!pkey->dsa->exSet && + SetDsaExternal(pkey->dsa) != WOLFSSL_SUCCESS)) + return WOLFSSL_FAILURE; + return wolfSSL_BN_num_bytes(pkey->dsa->p); #endif #ifdef HAVE_ECC @@ -2417,7 +2421,7 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, #ifndef NO_DSA case EVP_PKEY_DSA: if (wolfSSL_DSA_do_sign(md, sigret, pkey->dsa) == WOLFSSL_SUCCESS) { - *siglen = DSA_SIG_SIZE; + *siglen = wolfSSL_BN_num_bytes(pkey->dsa->q); return WOLFSSL_SUCCESS; } else { diff --git a/wolfssl/wolfcrypt/dsa.h b/wolfssl/wolfcrypt/dsa.h index 0bb00fbfe..523e08ad0 100644 --- a/wolfssl/wolfcrypt/dsa.h +++ b/wolfssl/wolfcrypt/dsa.h @@ -53,8 +53,20 @@ enum { }; enum { - DSA_HALF_SIZE = 20, /* r and s size */ - DSA_SIG_SIZE = 40 /* signature size */ + /* 160 bit q length */ + DSA_160_HALF_SIZE = 20, /* r and s size */ + DSA_160_SIG_SIZE = 40, /* signature size */ + DSA_HALF_SIZE = DSA_160_HALF_SIZE, /* kept for compatiblity */ + DSA_SIG_SIZE = DSA_160_SIG_SIZE, /* kept for compatiblity */ + /* 256 bit q length */ + DSA_256_HALF_SIZE = 32, /* r and s size */ + DSA_256_SIG_SIZE = 64, /* signature size */ + + DSA_MIN_HALF_SIZE = DSA_160_HALF_SIZE, + DSA_MIN_SIG_SIZE = DSA_160_SIG_SIZE, + + DSA_MAX_HALF_SIZE = DSA_256_HALF_SIZE, + DSA_MAX_SIG_SIZE = DSA_256_SIG_SIZE, }; /* DSA */ From 10168e093aee33e9acf631b545eed2b88b96668a Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 29 Jun 2021 13:02:04 +0200 Subject: [PATCH 08/11] Rebase fixes --- src/ssl.c | 128 ++++++++++++++++++++++++++------------------ tests/api.c | 7 ++- wolfcrypt/src/dsa.c | 2 +- wolfcrypt/src/evp.c | 13 +++-- wolfssl/ssl.h | 1 + 5 files changed, 89 insertions(+), 62 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index fd4f376d6..aef32c855 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -30927,6 +30927,42 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p, #endif /* v1.1.0 or later */ #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, + const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key) +{ + WOLFSSL_ENTER("wolfSSL_DH_get0_key"); + + if (dh != NULL) { + if (pub_key != NULL && dh->pub_key != NULL && + wolfSSL_BN_is_zero(dh->pub_key) != WOLFSSL_SUCCESS) + *pub_key = dh->pub_key; + if (priv_key != NULL && dh->priv_key != NULL && + wolfSSL_BN_is_zero(dh->priv_key) != WOLFSSL_SUCCESS) + *priv_key = dh->priv_key; + } +} + +int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key, + WOLFSSL_BIGNUM *priv_key) +{ + WOLFSSL_ENTER("wolfSSL_DH_set0_key"); + + if (dh == NULL) + return WOLFSSL_FAILURE; + + if (pub_key != NULL) { + wolfSSL_BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + + if (priv_key != NULL) { + wolfSSL_BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return SetDhInternal(dh); +} + #endif /* NO_DH */ #endif /* OPENSSL_EXTRA */ @@ -31500,34 +31536,6 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void) return sig; } -/** - * Same as wolfSSL_DSA_SIG_new but also initializes the internal bignums as well. - * @return New WOLFSSL_DSA_SIG with r and s created as well - */ -static WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new_bn(void) -{ - WOLFSSL_DSA_SIG* ret; - - if ((ret = wolfSSL_DSA_SIG_new()) == NULL) { - WOLFSSL_MSG("wolfSSL_DSA_SIG_new error"); - return NULL; - } - - if ((ret->r = wolfSSL_BN_new()) == NULL) { - WOLFSSL_MSG("wolfSSL_BN_new error"); - wolfSSL_DSA_SIG_free(ret); - return NULL; - } - - if ((ret->s = wolfSSL_BN_new()) == NULL) { - WOLFSSL_MSG("wolfSSL_BN_new error"); - wolfSSL_DSA_SIG_free(ret); - return NULL; - } - - return ret; -} - void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig) { WOLFSSL_ENTER("wolfSSL_DSA_SIG_free"); @@ -31569,6 +31577,7 @@ int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r, return WOLFSSL_SUCCESS; } +#ifndef HAVE_SELFTEST /** * * @param sig The input signature to encode @@ -31610,6 +31619,34 @@ int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out) return (int)bufLen; } +/** + * Same as wolfSSL_DSA_SIG_new but also initializes the internal bignums as well. + * @return New WOLFSSL_DSA_SIG with r and s created as well + */ +static WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new_bn(void) +{ + WOLFSSL_DSA_SIG* ret; + + if ((ret = wolfSSL_DSA_SIG_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_DSA_SIG_new error"); + return NULL; + } + + if ((ret->r = wolfSSL_BN_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_BN_new error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } + + if ((ret->s = wolfSSL_BN_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_BN_new error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } + + return ret; +} + /** * This parses a DER encoded ASN.1 structure. The ASN.1 encoding is: * ASN1_SEQUENCE @@ -31645,16 +31682,16 @@ WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig, r = (mp_int*)ret->r->internal; s = (mp_int*)ret->s->internal; - if (DecodeECC_DSA_Sig(*pp, length, r, s) != 0) { + if (DecodeECC_DSA_Sig(*pp, (word32)length, r, s) != 0) { if (length == DSA_160_SIG_SIZE || length == DSA_256_SIG_SIZE) { /* Two raw numbers of length/2 size each */ - if (mp_read_unsigned_bin(r, *pp, length/2) != 0) { + if (mp_read_unsigned_bin(r, *pp, (int)length/2) != 0) { WOLFSSL_MSG("r mp_read_unsigned_bin error"); wolfSSL_DSA_SIG_free(ret); return NULL; } - if (mp_read_unsigned_bin(s, *pp + (length/2), length/2) != 0) { + if (mp_read_unsigned_bin(s, *pp + (length/2), (int)length/2) != 0) { WOLFSSL_MSG("s mp_read_unsigned_bin error"); wolfSSL_DSA_SIG_free(ret); return NULL; @@ -31695,6 +31732,7 @@ WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig, return ret; } +#endif /* return WOLFSSL_SUCCESS on success, < 0 otherwise */ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, @@ -32974,7 +33012,7 @@ const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx) return NULL; } - return wolfSSL_macType2EVP_md(ctx->type); + return wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type); } #ifndef NO_DES3 @@ -42427,7 +42465,7 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) } switch (pkey->type) { -#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && !defined(NO_RSA) case EVP_PKEY_RSA: WOLFSSL_MSG("populating RSA key"); if (PopulateRSAEvpPkeyDer(pkey) != WOLFSSL_SUCCESS) @@ -43893,26 +43931,7 @@ int wolfSSL_CRYPTO_set_mem_functions( return WOLFSSL_FAILURE; } -#ifndef NO_WOLFSSL_STUB -int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), - void *(*r) (void *, size_t, const char *, - int), void (*f) (void *)) -{ - (void) m; - (void) r; - (void) f; - WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions"); - WOLFSSL_STUB("CRYPTO_set_mem_ex_functions"); - - return WOLFSSL_FAILURE; -} -#endif - - -void wolfSSL_CRYPTO_cleanup_all_ex_data(void){ - WOLFSSL_ENTER("CRYPTO_cleanup_all_ex_data"); -} - +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST) WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator, void (*callback) (int, int, void *), void *cb_arg) { @@ -43979,6 +43998,7 @@ int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, int generat return WOLFSSL_SUCCESS; } +#endif /* WOLFSSL_KEY_GEN && !HAVE_SELFTEST */ void wolfSSL_ERR_load_crypto_strings(void) { @@ -52810,6 +52830,8 @@ WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx, return (WOLFSSL_STRING*) wolfSSL_lh_retrieve(db->data, value); } +#endif /* OPENSSL_ALL */ + /******************************************************************************* * END OF TXT_DB API ******************************************************************************/ diff --git a/tests/api.c b/tests/api.c index 0a895fc54..206b8b7b9 100644 --- a/tests/api.c +++ b/tests/api.c @@ -20025,7 +20025,6 @@ static int test_wc_curve25519_shared_secret_ex(void) word32 outLen = sizeof(out); int endian = EC25519_BIG_ENDIAN; - printf(testingFmt, "wc_curve25519_shared_secret_ex()"); ret = wc_curve25519_init(&private_key); @@ -20040,7 +20039,6 @@ static int test_wc_curve25519_shared_secret_ex(void) } if (ret == 0) { ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &public_key); - } if (ret == 0) { ret = wc_curve25519_shared_secret_ex(&private_key, &public_key, out, @@ -28470,7 +28468,8 @@ static void test_wolfSSL_PEM_PrivateKey(void) /* key is DES encrypted */ #if !defined(NO_DES3) && defined(WOLFSSL_ENCRYPTED_KEYS) && \ - !defined(NO_RSA) && !defined(NO_FILESYSTEM) && !defined(NO_MD5) + !defined(NO_RSA) && !defined(NO_FILESYSTEM) && !defined(NO_MD5) && \ + defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && !defined(NO_RSA) { XFILE f; pem_password_cb* passwd_cb; @@ -45931,7 +45930,7 @@ static void test_wolfSSL_DH(void) (void)pub; (void)priv; -#if defined(OPENSSL_ALL) +#if defined(OPENSSL_ALL) && defined(WOLFSSL_KEY_GEN) #if !defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)) FILE* f = NULL; diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index c6d1a3519..04d369ade 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -967,7 +967,7 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) } #endif if (buffer) { - ForceZero(buffer, sz); + ForceZero(buffer, halfSz); XFREE(buffer, key->heap, DYNAMIC_TYPE_TMP_BUFFER); } #else /* !WOLFSSL_SMALL_STACK */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index f723b5467..503cd253f 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -6619,8 +6619,10 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) if (ecc->type == ECC_PRIVATEKEY || ecc->type == ECC_PRIVATEKEY_ONLY) { #ifdef HAVE_PKCS8 if (wc_EccKeyToPKCS8(ecc, NULL, &derSz) == LENGTH_ONLY_E) { - derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); + derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, NULL, + DYNAMIC_TYPE_OPENSSL); if (derBuf != NULL) { + pkey->pkey.ptr = (char*)derBuf; if (wc_EccKeyToPKCS8(ecc, derBuf, &derSz) < 0) { XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); >>>>>>> WIP @@ -6631,8 +6633,10 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) #else derSz = (word32)wc_EccKeyDerSize(ecc, 1); if (derSz > 0) { - derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); + derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, NULL, + DYNAMIC_TYPE_OPENSSL); if (derBuf != NULL) { + pkey->pkey.ptr = (char*)derBuf; if (wc_EccKeyToDer(ecc, derBuf, derSz) < 0) { XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); derBuf = NULL; @@ -6661,8 +6665,10 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) ======= else if (ecc->type == ECC_PUBLICKEY) { if ((derSz = (word32)wc_EccPublicKeyDerSize(ecc, 1)) > 0) { - derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); + derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, NULL, + DYNAMIC_TYPE_OPENSSL); if (derBuf != NULL) { + pkey->pkey.ptr = (char*)derBuf; if (wc_EccPublicKeyToDer(ecc, derBuf, derSz, 1) < 0) { XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); >>>>>>> WIP @@ -6673,7 +6679,6 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) } if (derBuf != NULL) { pkey->pkey_sz = (int)derSz; - pkey->pkey.ptr = (char*)derBuf; return WOLFSSL_SUCCESS; } else { diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 4c2cc555a..b4f5daea8 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef HAVE_WOLF_EVENT #include From 9f7aa3266281eebece7fb6181403a42c6cb9c6bd Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 22 Jul 2021 19:33:12 +0200 Subject: [PATCH 09/11] Fix merge conflict resolution in ECC_populate_EVP_PKEY --- src/ssl.c | 2 +- wolfcrypt/src/evp.c | 109 +++++++++++++++++--------------------------- 2 files changed, 44 insertions(+), 67 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index aef32c855..6e237524b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -42480,7 +42480,7 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) #ifdef HAVE_ECC case EVP_PKEY_EC: WOLFSSL_MSG("populating ECC key"); - if (ECC_populate_EVP_PKEY(pkey, (ecc_key*)pkey->ecc->internal) + if (ECC_populate_EVP_PKEY(pkey, pkey->ecc) != WOLFSSL_SUCCESS) return WOLFSSL_FAILURE; break; diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 503cd253f..2312312ba 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -6587,82 +6587,60 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key) /* try and populate public pkey_sz and pkey.ptr */ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) { -<<<<<<< master int derSz = 0; + byte* derBuf = NULL; ecc_key* ecc; if (pkey == NULL || key == NULL || key->internal == NULL) return WOLFSSL_FAILURE; ecc = (ecc_key*)key->internal; - if (key->pkcs8HeaderSz) { - /* when key has pkcs8 header the pkey should too */ - if (wc_EccKeyToPKCS8(ecc, NULL, (word32*)&derSz) == LENGTH_ONLY_E) { - byte* derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_OPENSSL); - if (derBuf) { - if (wc_EccKeyToPKCS8(ecc, derBuf, (word32*)&derSz) >= 0) { - if (pkey->pkey.ptr) { - XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL); - } - pkey->pkey_sz = (int)derSz; - pkey->pkey.ptr = (char*)derBuf; - pkey->pkcs8HeaderSz = key->pkcs8HeaderSz; - return WOLFSSL_SUCCESS; - } - else { - XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL); -======= - word32 derSz = 0; - byte* derBuf = NULL; - if (!pkey || !ecc) - return WOLFSSL_FAILURE; if (ecc->type == ECC_PRIVATEKEY || ecc->type == ECC_PRIVATEKEY_ONLY) { #ifdef HAVE_PKCS8 - if (wc_EccKeyToPKCS8(ecc, NULL, &derSz) == LENGTH_ONLY_E) { - derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, NULL, - DYNAMIC_TYPE_OPENSSL); - if (derBuf != NULL) { - pkey->pkey.ptr = (char*)derBuf; - if (wc_EccKeyToPKCS8(ecc, derBuf, &derSz) < 0) { - XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); ->>>>>>> WIP - derBuf = NULL; - } - } - } -#else - derSz = (word32)wc_EccKeyDerSize(ecc, 1); - if (derSz > 0) { - derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, NULL, - DYNAMIC_TYPE_OPENSSL); - if (derBuf != NULL) { - pkey->pkey.ptr = (char*)derBuf; - if (wc_EccKeyToDer(ecc, derBuf, derSz) < 0) { - XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); - derBuf = NULL; - } - } - } - -#endif /* HAVE_PKCS8 */ - } -<<<<<<< master - else { - /* if not, the pkey will be traditional ecc key */ - if ((derSz = wc_EccKeyDerSize(ecc, 1)) > 0) { - byte* derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_OPENSSL); - if (derBuf) { - if (wc_EccKeyToDer(ecc, derBuf, derSz) >= 0) { - if (pkey->pkey.ptr) { - XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL); + if (key->pkcs8HeaderSz) { + /* when key has pkcs8 header the pkey should too */ + if (wc_EccKeyToPKCS8(ecc, NULL, (word32*)&derSz) == LENGTH_ONLY_E) { + derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_OPENSSL); + if (derBuf) { + if (wc_EccKeyToPKCS8(ecc, derBuf, (word32*)&derSz) >= 0) { + if (pkey->pkey.ptr) { + XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL); + } + pkey->pkey_sz = (int)derSz; + pkey->pkey.ptr = (char*)derBuf; + pkey->pkcs8HeaderSz = key->pkcs8HeaderSz; + return WOLFSSL_SUCCESS; + } + else { + XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL); + derBuf = NULL; } - pkey->pkey_sz = (int)derSz; - pkey->pkey.ptr = (char*)derBuf; - return WOLFSSL_SUCCESS; } - else { - XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL); -======= + } + } + else +#endif /* HAVE_PKCS8 */ + { + /* if not, the pkey will be traditional ecc key */ + if ((derSz = wc_EccKeyDerSize(ecc, 1)) > 0) { + derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_OPENSSL); + if (derBuf) { + if (wc_EccKeyToDer(ecc, derBuf, derSz) >= 0) { + if (pkey->pkey.ptr) { + XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL); + } + pkey->pkey_sz = (int)derSz; + pkey->pkey.ptr = (char*)derBuf; + return WOLFSSL_SUCCESS; + } + else { + XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL); + derBuf = NULL; + } + } + } + } + } else if (ecc->type == ECC_PUBLICKEY) { if ((derSz = (word32)wc_EccPublicKeyDerSize(ecc, 1)) > 0) { derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, NULL, @@ -6671,7 +6649,6 @@ static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) pkey->pkey.ptr = (char*)derBuf; if (wc_EccPublicKeyToDer(ecc, derBuf, derSz, 1) < 0) { XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL); ->>>>>>> WIP derBuf = NULL; } } From 23cff71bbfa0ceac41f8bb90db5f9c0a9f02b660 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 22 Jul 2021 20:47:36 +0200 Subject: [PATCH 10/11] Second `wc_EccPrivateKeyDecode` not needed now that it supports PKCS8 --- src/ssl.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 6e237524b..f6079e70f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -38445,15 +38445,6 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal, derSz); } - if (ret < 0 && opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) { - /* Might be in PKCS8 format so let's try */ - idx = 0; - ret = ToTraditionalInline(derBuf, &idx, (word32)derSz); - if (ret > 0) { - ret = wc_EccPrivateKeyDecode(derBuf, &idx, - (ecc_key*)key->internal, derSz); - } - } if (ret < 0) { if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) { WOLFSSL_MSG("wc_EccPrivateKeyDecode failed"); From 8ee9024da9a349e1f8372e8a79297dc843c63a86 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 23 Jul 2021 18:15:43 +0200 Subject: [PATCH 11/11] More rebase fixes --- src/ssl.c | 83 ------------------------------------------------------- 1 file changed, 83 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index f6079e70f..9cf5b47d0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -33015,52 +33015,6 @@ const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx) return wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type); } -#ifndef NO_DES3 - -void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, - unsigned char* iv, int len) -{ - (void)len; - - WOLFSSL_MSG("wolfSSL_3des_iv"); - - if (ctx == NULL || iv == NULL) { - WOLFSSL_MSG("Bad function argument"); - return; - } - - if (doset) - wc_Des3_SetIV(&ctx->cipher.des3, iv); /* OpenSSL compat, no ret */ - else - XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE); -} - -#endif /* NO_DES3 */ - - -#ifndef NO_AES - -void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, - unsigned char* iv, int len) -{ - (void)len; - - WOLFSSL_MSG("wolfSSL_aes_ctr_iv"); - - if (ctx == NULL || iv == NULL) { - WOLFSSL_MSG("Bad function argument"); - return; - } - - if (doset) - (void)wc_AesSetIV(&ctx->cipher.aes, iv); /* OpenSSL compat, no ret */ - else - XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE); -} - -#endif /* NO_AES */ - - /* Free the dynamically allocated data. * * p Pointer to dynamically allocated memory. @@ -52827,43 +52781,6 @@ WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx, * END OF TXT_DB API ******************************************************************************/ -void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, - const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key) -{ - WOLFSSL_ENTER("wolfSSL_DH_get0_key"); - - if (dh != NULL) { - if (pub_key != NULL && dh->pub_key != NULL && - wolfSSL_BN_is_zero(dh->pub_key) != WOLFSSL_SUCCESS) - *pub_key = dh->pub_key; - if (priv_key != NULL && dh->priv_key != NULL && - wolfSSL_BN_is_zero(dh->priv_key) != WOLFSSL_SUCCESS) - *priv_key = dh->priv_key; - } -} - -int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key, - WOLFSSL_BIGNUM *priv_key) -{ - WOLFSSL_ENTER("wolfSSL_DH_set0_key"); - - if (dh == NULL) - return WOLFSSL_FAILURE; - - if (pub_key != NULL) { - wolfSSL_BN_free(dh->pub_key); - dh->pub_key = pub_key; - } - - if (priv_key != NULL) { - wolfSSL_BN_free(dh->priv_key); - dh->priv_key = priv_key; - } - - return SetDhInternal(dh); -} -#endif - /******************************************************************************* * START OF CONF API ******************************************************************************/