diff --git a/configure.ac b/configure.ac index 1fa58e4f6..684232f3a 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 @@ -1993,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 @@ -4361,6 +4373,16 @@ then fi fi +if test "$ENABLED_BIND" = "yes" +then + 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" + ENABLED_SHA384="yes" + ENABLED_SHA512="yes" +fi + if test "$ENABLED_OPENVPN" = "yes" then ENABLED_SUPPORTED_CURVES="yes" diff --git a/src/ssl.c b/src/ssl.c index 8559c6f8f..9cf5b47d0 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); @@ -30810,7 +30813,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; @@ -30924,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 */ @@ -31425,6 +31464,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; @@ -31449,6 +31550,190 @@ 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; +} + +#ifndef HAVE_SELFTEST +/** + * + * @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_MAX_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; +} + +/** + * 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 + * ASN1_INTEGER (DSA r) + * ASN1_INTEGER (DSA s) + * 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 + * @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 (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, (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), (int)length/2) != 0) { + WOLFSSL_MSG("s mp_read_unsigned_bin error"); + wolfSSL_DSA_SIG_free(ret); + return NULL; + } + + *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 + { + /* 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; +} +#endif + /* return WOLFSSL_SUCCESS on success, < 0 otherwise */ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, WOLFSSL_DSA* dsa) @@ -31469,10 +31754,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; @@ -31498,7 +31781,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; @@ -31515,40 +31798,37 @@ 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]; + byte sigBin[DSA_MAX_SIG_SIZE]; + const byte *tmp = sigBin; + int sigLen; 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; } 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 */ @@ -31597,8 +31877,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"); @@ -31612,37 +31894,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; } @@ -32004,6 +32300,103 @@ 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 SetRsaInternal(r) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} + +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 SetRsaInternal(r) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} + void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n, const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d) { @@ -32613,6 +33006,15 @@ 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((enum wc_HashType)ctx->type); +} + /* Free the dynamically allocated data. * * p Pointer to dynamically allocated memory. @@ -33689,7 +34091,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; @@ -34171,6 +34574,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 +35239,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; @@ -37704,10 +38152,22 @@ 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; + } +} + +int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *r, int flags) +{ + return r && r->meth ? 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) { @@ -37811,7 +38271,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 */ @@ -41948,6 +42409,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(HAVE_USER_RSA) && !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, pkey->ecc) + != 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, @@ -43379,35 +43865,85 @@ int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1, return WOLFSSL_FAILURE; } -#ifndef NO_WOLFSSL_STUB +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; +} + +#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) { - (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; + (void)generator; + + 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; + } + + /* Don't need SetDhInternal call since we are generating + * parameters ourselves */ + + key = (DhKey*)dh->internal; + + /* 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"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; } -#endif +#endif /* WOLFSSL_KEY_GEN && !HAVE_SELFTEST */ void wolfSSL_ERR_load_crypto_strings(void) { @@ -47889,14 +48425,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 */ @@ -50112,11 +50652,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; - } } @@ -52237,7 +52774,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 + +#endif /* OPENSSL_ALL */ /******************************************************************************* * END OF TXT_DB API 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/tests/api.c b/tests/api.c index 9f1555b71..4421e6f25 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2570,8 +2570,15 @@ 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); + 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); #endif /* HAVE_ECC */ @@ -20018,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); @@ -20033,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, @@ -28463,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; @@ -29123,6 +29129,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 +29140,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 +29152,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 +29164,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 +29176,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 +29188,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 +29197,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 +29209,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 +34100,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 +35698,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 +35712,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 +35726,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,7 +35952,11 @@ 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); - AssertIntEQ(RSA_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_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); @@ -37990,7 +38045,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; @@ -38147,6 +38202,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 @@ -39218,7 +39317,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,19 +45914,23 @@ 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(OPENSSL_ALL) && defined(WOLFSSL_KEY_GEN) #if !defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)) FILE* f = NULL; @@ -45845,21 +45948,32 @@ static void test_wolfSSL_DH_get0_pqg(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); 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); + + AssertNotNull(dh = DH_generate_parameters(2048, 2, NULL, NULL)); 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 +46096,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(); @@ -46258,6 +46371,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(); @@ -46417,7 +46531,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/asn.c b/wolfcrypt/src/asn.c index f751f0034..d3d096d98 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; } @@ -16138,7 +16140,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) @@ -16303,9 +16305,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..04d369ade 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,10 @@ 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 + /* This key length is unsecure and only included for bind 9 testing */ + case 768: +#endif case 1024: qsize = 20; break; @@ -679,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 { @@ -701,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) || @@ -728,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; @@ -745,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; } @@ -814,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; } @@ -910,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); @@ -960,12 +967,12 @@ 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 */ if (ret != MP_INIT_E) { - ForceZero(buffer, sz); + ForceZero(buffer, halfSz); mp_forcezero(kInv); mp_forcezero(k); #ifndef WOLFSSL_MP_INVMOD_CONSTANT_TIME @@ -994,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) { @@ -1025,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/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 db7c286a2..2312312ba 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1938,6 +1938,15 @@ 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: + 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 case EVP_PKEY_EC: if (pkey->ecc == NULL || pkey->ecc->internal == NULL) { @@ -2345,8 +2354,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; } } @@ -2354,6 +2363,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 @@ -2369,29 +2390,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 = wolfSSL_BN_num_bytes(pkey->dsa->q); + return WOLFSSL_SUCCESS; + } + else { + return WOLFSSL_FAILURE; + } +#endif case EVP_PKEY_EC: WOLFSSL_MSG("not implemented"); FALL_THROUGH; @@ -4212,6 +4248,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: @@ -6045,48 +6084,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 @@ -6095,13 +6209,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; @@ -6125,82 +6232,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) { @@ -6551,54 +6588,79 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key) static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key) { 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); + if (ecc->type == ECC_PRIVATEKEY || ecc->type == ECC_PRIVATEKEY_ONLY) { +#ifdef HAVE_PKCS8 + 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; - pkey->pkcs8HeaderSz = key->pkcs8HeaderSz; - 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, + 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); derBuf = NULL; } } } } + if (derBuf != NULL) { + pkey->pkey_sz = (int)derSz; + return WOLFSSL_SUCCESS; + } 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); - } - pkey->pkey_sz = (int)derSz; - pkey->pkey.ptr = (char*)derBuf; - return WOLFSSL_SUCCESS; - } - else { - XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL); - derBuf = NULL; - } - } - } + return WOLFSSL_FAILURE; } - return WOLFSSL_FAILURE; } int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) 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) && \ diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 06128fe7f..b9ee29fe7 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/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/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..86c4dae9d 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -144,12 +144,23 @@ 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 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); @@ -194,10 +205,16 @@ 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_clear_flags wolfSSL_RSA_clear_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/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 87e1a623d..b4f5daea8 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef HAVE_WOLF_EVENT #include @@ -3976,6 +3977,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 *)); @@ -4234,7 +4239,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) 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 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 */