summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/fipsinstall.c2
-rw-r--r--crypto/dsa/build.info10
-rw-r--r--crypto/dsa/dsa_asn1.c151
-rw-r--r--crypto/dsa/dsa_lib.c294
-rw-r--r--crypto/dsa/dsa_local.h3
-rw-r--r--crypto/dsa/dsa_ossl.c25
-rw-r--r--crypto/dsa/dsa_sign.c179
-rw-r--r--crypto/evp/build.info11
-rw-r--r--crypto/evp/p_lib.c226
-rw-r--r--crypto/evp/pmeth_fn.c563
-rw-r--r--crypto/evp/pmeth_gn.c174
-rw-r--r--crypto/evp/pmeth_lib.c236
-rw-r--r--crypto/evp/signature.c580
-rw-r--r--doc/man3/EVP_PKEY_CTX_new.pod28
-rw-r--r--include/crypto/dsa.h14
-rw-r--r--include/crypto/evp.h1
-rw-r--r--include/openssl/evp.h8
-rw-r--r--providers/fips/fipsprov.c178
-rw-r--r--providers/implementations/keymgmt/dsa_kmgmt.c9
-rw-r--r--providers/implementations/signature/dsa.c5
-rw-r--r--test/evp_pkey_provided_test.c4
-rw-r--r--util/libcrypto.num3
22 files changed, 1499 insertions, 1205 deletions
diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c
index 3b19ef15a8..739df23d44 100644
--- a/apps/fipsinstall.c
+++ b/apps/fipsinstall.c
@@ -170,7 +170,7 @@ static CONF *generate_config_and_load(const char *prov_name,
if (conf == NULL)
goto end;
- if (!CONF_modules_load(conf, NULL, 0))
+ if (CONF_modules_load(conf, NULL, 0) <= 0)
goto end;
BIO_free(mem_bio);
return conf;
diff --git a/crypto/dsa/build.info b/crypto/dsa/build.info
index 2e759853a2..309fda323e 100644
--- a/crypto/dsa/build.info
+++ b/crypto/dsa/build.info
@@ -1,5 +1,9 @@
LIBS=../../libcrypto
-SOURCE[../../libcrypto]=\
- dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \
- dsa_err.c dsa_ossl.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \
+
+$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c
+
+SOURCE[../../libcrypto]=$COMMON\
+ dsa_gen.c dsa_key.c dsa_asn1.c \
+ dsa_err.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \
dsa_meth.c
+SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index bf16e282d5..20bf2518c8 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -15,110 +15,6 @@
#include <openssl/rand.h>
#include "crypto/asn1_dsa.h"
-DSA_SIG *DSA_SIG_new(void)
-{
- DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
- if (sig == NULL)
- DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
- return sig;
-}
-
-void DSA_SIG_free(DSA_SIG *sig)
-{
- if (sig == NULL)
- return;
- BN_clear_free(sig->r);
- BN_clear_free(sig->s);
- OPENSSL_free(sig);
-}
-
-DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len)
-{
- DSA_SIG *sig;
-
- if (len < 0)
- return NULL;
- if (psig != NULL && *psig != NULL) {
- sig = *psig;
- } else {
- sig = DSA_SIG_new();
- if (sig == NULL)
- return NULL;
- }
- if (sig->r == NULL)
- sig->r = BN_new();
- if (sig->s == NULL)
- sig->s = BN_new();
- if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
- if (psig == NULL || *psig == NULL)
- DSA_SIG_free(sig);
- return NULL;
- }
- if (psig != NULL && *psig == NULL)
- *psig = sig;
- return sig;
-}
-
-int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout)
-{
- BUF_MEM *buf = NULL;
- size_t encoded_len;
- WPACKET pkt;
-
- if (ppout == NULL) {
- if (!WPACKET_init_null(&pkt, 0))
- return -1;
- } else if (*ppout == NULL) {
- if ((buf = BUF_MEM_new()) == NULL
- || !WPACKET_init_len(&pkt, buf, 0)) {
- BUF_MEM_free(buf);
- return -1;
- }
- } else {
- if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
- return -1;
- }
-
- if (!encode_der_dsa_sig(&pkt, sig->r, sig->s)
- || !WPACKET_get_total_written(&pkt, &encoded_len)
- || !WPACKET_finish(&pkt)) {
- BUF_MEM_free(buf);
- WPACKET_cleanup(&pkt);
- return -1;
- }
-
- if (ppout != NULL) {
- if (*ppout == NULL) {
- *ppout = (unsigned char *)buf->data;
- buf->data = NULL;
- BUF_MEM_free(buf);
- } else {
- *ppout += encoded_len;
- }
- }
-
- return (int)encoded_len;
-}
-
-void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
-{
- if (pr != NULL)
- *pr = sig->r;
- if (ps != NULL)
- *ps = sig->s;
-}
-
-int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
-{
- if (r == NULL || s == NULL)
- return 0;
- BN_clear_free(sig->r);
- BN_clear_free(sig->s);
- sig->r = r;
- sig->s = s;
- return 1;
-}
-
/* Override the default free and new methods */
static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
@@ -168,50 +64,3 @@ DSA *DSAparams_dup(const DSA *dsa)
{
return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
}
-
-int DSA_sign(int type, const unsigned char *dgst, int dlen,
- unsigned char *sig, unsigned int *siglen, DSA *dsa)
-{
- DSA_SIG *s;
-
- s = DSA_do_sign(dgst, dlen, dsa);
- if (s == NULL) {
- *siglen = 0;
- return 0;
- }
- *siglen = i2d_DSA_SIG(s, &sig);
- DSA_SIG_free(s);
- return 1;
-}
-
-/* data has already been hashed (probably with SHA or SHA-1). */
-/*-
- * returns
- * 1: correct signature
- * 0: incorrect signature
- * -1: error
- */
-int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
- const unsigned char *sigbuf, int siglen, DSA *dsa)
-{
- DSA_SIG *s;
- const unsigned char *p = sigbuf;
- unsigned char *der = NULL;
- int derlen = -1;
- int ret = -1;
-
- s = DSA_SIG_new();
- if (s == NULL)
- return ret;
- if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
- goto err;
- /* Ensure signature uses DER and doesn't have trailing garbage */
- derlen = i2d_DSA_SIG(s, &der);
- if (derlen != siglen || memcmp(sigbuf, der, derlen))
- goto err;
- ret = DSA_do_verify(dgst, dgst_len, s, dsa);
- err:
- OPENSSL_clear_free(der, derlen);
- DSA_SIG_free(s);
- return ret;
-}
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index 4670c433c5..2a97c0852c 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -15,12 +15,140 @@
#include <openssl/asn1.h>
#include <openssl/engine.h>
#include <openssl/dh.h>
+#include "crypto/dsa.h"
+
+#ifndef FIPS_MODE
DSA *DSA_new(void)
{
return DSA_new_method(NULL);
}
+int DSA_set_ex_data(DSA *d, int idx, void *arg)
+{
+ return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
+}
+
+void *DSA_get_ex_data(DSA *d, int idx)
+{
+ return CRYPTO_get_ex_data(&d->ex_data, idx);
+}
+
+int DSA_security_bits(const DSA *d)
+{
+ if (d->p && d->q)
+ return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
+ return -1;
+}
+
+#ifndef OPENSSL_NO_DH
+DH *DSA_dup_DH(const DSA *r)
+{
+ /*
+ * DSA has p, q, g, optional pub_key, optional priv_key. DH has p,
+ * optional length, g, optional pub_key, optional priv_key, optional q.
+ */
+
+ DH *ret = NULL;
+ BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
+
+ if (r == NULL)
+ goto err;
+ ret = DH_new();
+ if (ret == NULL)
+ goto err;
+ if (r->p != NULL || r->g != NULL || r->q != NULL) {
+ if (r->p == NULL || r->g == NULL || r->q == NULL) {
+ /* Shouldn't happen */
+ goto err;
+ }
+ p = BN_dup(r->p);
+ g = BN_dup(r->g);
+ q = BN_dup(r->q);
+ if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g))
+ goto err;
+ p = g = q = NULL;
+ }
+
+ if (r->pub_key != NULL) {
+ pub_key = BN_dup(r->pub_key);
+ if (pub_key == NULL)
+ goto err;
+ if (r->priv_key != NULL) {
+ priv_key = BN_dup(r->priv_key);
+ if (priv_key == NULL)
+ goto err;
+ }
+ if (!DH_set0_key(ret, pub_key, priv_key))
+ goto err;
+ } else if (r->priv_key != NULL) {
+ /* Shouldn't happen */
+ goto err;
+ }
+
+ return ret;
+
+ err:
+ BN_free(p);
+ BN_free(g);
+ BN_free(q);
+ BN_free(pub_key);
+ BN_free(priv_key);
+ DH_free(ret);
+ return NULL;
+}
+#endif
+
+const BIGNUM *DSA_get0_p(const DSA *d)
+{
+ return d->p;
+}
+
+const BIGNUM *DSA_get0_q(const DSA *d)
+{
+ return d->q;
+}
+
+const BIGNUM *DSA_get0_g(const DSA *d)
+{
+ return d->g;
+}
+
+const BIGNUM *DSA_get0_pub_key(const DSA *d)
+{
+ return d->pub_key;
+}
+
+const BIGNUM *DSA_get0_priv_key(const DSA *d)
+{
+ return d->priv_key;
+}
+
+void DSA_clear_flags(DSA *d, int flags)
+{
+ d->flags &= ~flags;
+}
+
+int DSA_test_flags(const DSA *d, int flags)
+{
+ return d->flags & flags;
+}
+
+void DSA_set_flags(DSA *d, int flags)
+{
+ d->flags |= flags;
+}
+
+ENGINE *DSA_get0_engine(DSA *d)
+{
+ return d->engine;
+}
+
+int DSA_bits(const DSA *dsa)
+{
+ return BN_num_bits(dsa->p);
+}
+
int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
{
/*
@@ -40,13 +168,15 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
meth->init(dsa);
return 1;
}
+#endif /* FIPS_MODE */
+
const DSA_METHOD *DSA_get_method(DSA *d)
{
return d->meth;
}
-DSA *DSA_new_method(ENGINE *engine)
+static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine)
{
DSA *ret = OPENSSL_zalloc(sizeof(*ret));
@@ -64,7 +194,7 @@ DSA *DSA_new_method(ENGINE *engine)
}
ret->meth = DSA_get_default_method();
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */
if (engine) {
if (!ENGINE_init(engine)) {
@@ -85,7 +215,7 @@ DSA *DSA_new_method(ENGINE *engine)
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
- if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
+ if (!crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
goto err;
if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
@@ -100,6 +230,16 @@ DSA *DSA_new_method(ENGINE *engine)
return NULL;
}
+DSA *DSA_new_method(ENGINE *engine)
+{
+ return dsa_new_method(NULL, engine);
+}
+
+DSA *dsa_new(OPENSSL_CTX *libctx)
+{
+ return dsa_new_method(libctx, NULL);
+}
+
void DSA_free(DSA *r)
{
int i;
@@ -115,7 +255,7 @@ void DSA_free(DSA *r)
if (r->meth != NULL && r->meth->finish != NULL)
r->meth->finish(r);
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
ENGINE_finish(r->engine);
#endif
@@ -143,103 +283,6 @@ int DSA_up_ref(DSA *r)
return ((i > 1) ? 1 : 0);
}
-int DSA_size(const DSA *r)
-{
- int ret, i;
- ASN1_INTEGER bs;
- unsigned char buf[4]; /* 4 bytes looks really small. However,
- * i2d_ASN1_INTEGER() will not look beyond
- * the first byte, as long as the second
- * parameter is NULL. */
-
- i = BN_num_bits(r->q);
- bs.length = (i + 7) / 8;
- bs.data = buf;
- bs.type = V_ASN1_INTEGER;
- /* If the top bit is set the asn1 encoding is 1 larger. */
- buf[0] = 0xff;
-
- i = i2d_ASN1_INTEGER(&bs, NULL);
- i += i; /* r and s */
- ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
- return ret;
-}
-
-int DSA_set_ex_data(DSA *d, int idx, void *arg)
-{
- return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
-}
-
-void *DSA_get_ex_data(DSA *d, int idx)
-{
- return CRYPTO_get_ex_data(&d->ex_data, idx);
-}
-
-int DSA_security_bits(const DSA *d)
-{
- if (d->p && d->q)
- return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
- return -1;
-}
-
-#ifndef OPENSSL_NO_DH
-DH *DSA_dup_DH(const DSA *r)
-{
- /*
- * DSA has p, q, g, optional pub_key, optional priv_key. DH has p,
- * optional length, g, optional pub_key, optional priv_key, optional q.
- */
-
- DH *ret = NULL;
- BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
-
- if (r == NULL)
- goto err;
- ret = DH_new();
- if (ret == NULL)
- goto err;
- if (r->p != NULL || r->g != NULL || r->q != NULL) {
- if (r->p == NULL || r->g == NULL || r->q == NULL) {
- /* Shouldn't happen */
- goto err;
- }
- p = BN_dup(r->p);
- g = BN_dup(r->g);
- q = BN_dup(r->q);
- if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g))
- goto err;
- p = g = q = NULL;
- }
-
- if (r->pub_key != NULL) {
- pub_key = BN_dup(r->pub_key);
- if (pub_key == NULL)
- goto err;
- if (r->priv_key != NULL) {
- priv_key = BN_dup(r->priv_key);
- if (priv_key == NULL)
- goto err;
- }
- if (!DH_set0_key(ret, pub_key, priv_key))
- goto err;
- } else if (r->priv_key != NULL) {
- /* Shouldn't happen */
- goto err;
- }
-
- return ret;
-
- err:
- BN_free(p);
- BN_free(g);
- BN_free(q);
- BN_free(pub_key);
- BN_free(priv_key);
- DH_free(ret);
- return NULL;
-}
-#endif
-
void DSA_get0_pqg(const DSA *d,
const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
{
@@ -309,52 +352,3 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
return 1;
}
-const BIGNUM *DSA_get0_p(const DSA *d)
-{
- return d->p;
-}
-
-const BIGNUM *DSA_get0_q(const DSA *d)
-{
- return d->q;
-}
-
-const BIGNUM *DSA_get0_g(const DSA *d)
-{
- return d->g;
-}
-
-const BIGNUM *DSA_get0_pub_key(const DSA *d)
-{
- return d->pub_key;
-}
-
-const BIGNUM *DSA_get0_priv_key(const DSA *d)
-{
- return d->priv_key;
-}
-
-void DSA_clear_flags(DSA *d, int flags)
-{
- d->flags &= ~flags;
-}
-
-int DSA_test_flags(const DSA *d, int flags)
-{
- return d->flags & flags;
-}
-
-void DSA_set_flags(DSA *d, int flags)
-{
- d->flags |= flags;
-}
-
-ENGINE *DSA_get0_engine(DSA *d)
-{
- return d->engine;
-}
-
-int DSA_bits(const DSA *dsa)
-{
- return BN_num_bits(dsa->p);
-}
diff --git a/crypto/dsa/dsa_local.h b/crypto/dsa/dsa_local.h
index e56ff06977..13a3007ff0 100644
--- a/crypto/dsa/dsa_local.h
+++ b/crypto/dsa/dsa_local.h
@@ -78,3 +78,6 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
size_t seed_len, int idx, unsigned char *seed_out,
int *counter_ret, unsigned long *h_ret,
BN_GENCB *cb);
+
+DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
+ int dlen, DSA *dsa);
diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c
index 5e34fc5586..af0fa6b566 100644
--- a/crypto/dsa/dsa_ossl.c
+++ b/crypto/dsa/dsa_ossl.c
@@ -44,10 +44,12 @@ static DSA_METHOD openssl_dsa_meth = {
static const DSA_METHOD *default_DSA_method = &openssl_dsa_meth;
+#ifndef FIPS_MODE
void DSA_set_default_method(const DSA_METHOD *meth)
{
default_DSA_method = meth;
}
+#endif /* FIPS_MODE */
const DSA_METHOD *DSA_get_default_method(void)
{
@@ -59,7 +61,8 @@ const DSA_METHOD *DSA_OpenSSL(void)
return &openssl_dsa_meth;
}
-static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
+ int dlen, DSA *dsa)
{
BIGNUM *kinv = NULL;
BIGNUM *m, *blind, *blindm, *tmp;
@@ -85,7 +88,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
if (ret->r == NULL || ret->s == NULL)
goto err;
- ctx = BN_CTX_new();
+ ctx = BN_CTX_new_ex(libctx);
if (ctx == NULL)
goto err;
m = BN_CTX_get(ctx);
@@ -121,8 +124,8 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
/* Generate a blinding value */
do {
- if (!BN_priv_rand(blind, BN_num_bits(dsa->q) - 1,
- BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
+ if (!BN_priv_rand_ex(blind, BN_num_bits(dsa->q) - 1,
+ BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx))
goto err;
} while (BN_is_zero(blind));
BN_set_flags(blind, BN_FLG_CONSTTIME);
@@ -164,7 +167,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
err:
if (rv == 0) {
- DSAerr(DSA_F_DSA_DO_SIGN, reason);
+ DSAerr(0, reason);
DSA_SIG_free(ret);
ret = NULL;
}
@@ -173,6 +176,11 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
return ret;
}
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+{
+ return dsa_do_sign_int(NULL, dgst, dlen, dsa);
+}
+
static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in,
BIGNUM **kinvp, BIGNUM **rp)
{
@@ -210,7 +218,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
goto err;
if (ctx_in == NULL) {
- if ((ctx = BN_CTX_new()) == NULL)
+ /* if you don't pass in ctx_in you get a default libctx */
+ if ((ctx = BN_CTX_new_ex(NULL)) == NULL)
goto err;
} else
ctx = ctx_in;
@@ -232,7 +241,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst,
dlen, ctx))
goto err;
- } else if (!BN_priv_rand_range(k, dsa->q))
+ } else if (!BN_priv_rand_range_ex(k, dsa->q, ctx))
goto err;
} while (BN_is_zero(k));
@@ -323,7 +332,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
u1 = BN_new();
u2 = BN_new();
t1 = BN_new();
- ctx = BN_CTX_new();
+ ctx = BN_CTX_new_ex(NULL); /* verify does not need a libctx */
if (u1 == NULL || u2 == NULL || t1 == NULL || ctx == NULL)
goto err;
diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c
index 99ef0043eb..d09aaea6db 100644
--- a/crypto/dsa/dsa_sign.c
+++ b/crypto/dsa/dsa_sign.c
@@ -7,9 +7,11 @@
* https://www.openssl.org/source/license.html
*/
+#include <openssl/bn.h>
#include "internal/cryptlib.h"
#include "dsa_local.h"
-#include <openssl/bn.h>
+#include "crypto/asn1_dsa.h"
+#include "crypto/dsa.h"
DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
@@ -22,3 +24,178 @@ int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
}
#endif
+
+DSA_SIG *DSA_SIG_new(void)
+{
+ DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
+ if (sig == NULL)
+ DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
+ return sig;
+}
+
+void DSA_SIG_free(DSA_SIG *sig)
+{
+ if (sig == NULL)
+ return;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ OPENSSL_free(sig);
+}
+
+DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len)
+{
+ DSA_SIG *sig;
+
+ if (len < 0)
+ return NULL;
+ if (psig != NULL && *psig != NULL) {
+ sig = *psig;
+ } else {
+ sig = DSA_SIG_new();
+ if (sig == NULL)
+ return NULL;
+ }
+ if (sig->r == NULL)
+ sig->r = BN_new();
+ if (sig->s == NULL)
+ sig->s = BN_new();
+ if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) {
+ if (psig == NULL || *psig == NULL)
+ DSA_SIG_free(sig);
+ return NULL;
+ }
+ if (psig != NULL && *psig == NULL)
+ *psig = sig;
+ return sig;
+}
+
+int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout)
+{
+ BUF_MEM *buf = NULL;
+ size_t encoded_len;
+ WPACKET pkt;
+
+ if (ppout == NULL) {
+ if (!WPACKET_init_null(&pkt, 0))
+ return -1;
+ } else if (*ppout == NULL) {
+ if ((buf = BUF_MEM_new()) == NULL
+ || !WPACKET_init_len(&pkt, buf, 0)) {
+ BUF_MEM_free(buf);
+ return -1;
+ }
+ } else {
+ if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0))
+ return -1;
+ }
+
+ if (!encode_der_dsa_sig(&pkt, sig->r, sig->s)
+ || !WPACKET_get_total_written(&pkt, &encoded_len)
+ || !WPACKET_finish(&pkt)) {
+ BUF_MEM_free(buf);
+ WPACKET_cleanup(&pkt);
+ return -1;
+ }
+
+ if (ppout != NULL) {
+ if (*ppout == NULL) {
+ *ppout = (unsigned char *)buf->data;
+ buf->data = NULL;
+ BUF_MEM_free(buf);
+ } else {
+ *ppout += encoded_len;
+ }
+ }
+
+ return (int)encoded_len;
+}
+
+int DSA_size(const DSA *dsa)
+{
+ int ret;
+ DSA_SIG sig;
+
+ sig.r = sig.s = dsa->q;
+ ret = i2d_DSA_SIG(&sig, NULL);
+
+ if (ret < 0)
+ ret = 0;
+ return ret;
+}
+
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+ return 1;
+}
+
+int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst,
+ int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa)
+{
+ DSA_SIG *s;
+
+ /* legacy case uses the method table */
+ if (libctx == NULL || dsa->meth != DSA_get_default_method())
+ s = DSA_do_sign(dgst, dlen, dsa);
+ else
+ s = dsa_do_sign_int(libctx, dgst, dlen, dsa);
+ if (s == NULL) {
+ *siglen = 0;
+ return 0;
+ }
+ *siglen = i2d_DSA_SIG(s, &sig);
+ DSA_SIG_free(s);
+ return 1;
+}
+
+int DSA_sign(int type, const unsigned char *dgst, int dlen,
+ unsigned char *sig, unsigned int *siglen, DSA *dsa)
+{
+ return dsa_sign_int(NULL, type, dgst, dlen, sig, siglen, dsa);
+}
+
+/* data has already been hashed (probably with SHA or SHA-1). */
+/*-
+ * returns
+ * 1: correct signature
+ * 0: incorrect signature
+ * -1: error
+ */
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+ const unsigned char *sigbuf, int siglen, DSA *dsa)
+{
+ DSA_SIG *s;
+ const unsigned char *p = sigbuf;
+ unsigned char *der = NULL;
+ int derlen = -1;
+ int ret = -1;
+
+ s = DSA_SIG_new();
+ if (s == NULL)
+ return ret;
+ if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
+ goto err;
+ /* Ensure signature uses DER and doesn't have trailing garbage */
+ derlen = i2d_DSA_SIG(s, &der);
+ if (derlen != siglen || memcmp(sigbuf, der, derlen))
+ goto err;
+ ret = DSA_do_verify(dgst, dgst_len, s, dsa);
+ err:
+ OPENSSL_clear_free(der, derlen);
+ DSA_SIG_free(s);
+ return ret;
+}
+
diff --git a/crypto/evp/build.info b/crypto/evp/build.info
index 156b26050b..71e0ebaf44 100644
--- a/crypto/evp/build.info
+++ b/crypto/evp/build.info
@@ -1,19 +1,18 @@
LIBS=../../libcrypto
$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \
mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \
- m_sigver.c
+ m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c
+
SOURCE[../../libcrypto]=$COMMON\
encode.c evp_key.c evp_cnf.c \
e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c \
- e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
- m_null.c \
- p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
+ e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c m_null.c \
+ p_open.c p_seal.c p_sign.c p_verify.c p_enc.c p_dec.c \
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
c_allc.c c_alld.c bio_ok.c \
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
- pkey_kdf.c \
- e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c \
+ pkey_kdf.c e_old.c pmeth_fn.c\
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
e_chacha20_poly1305.c \
pkey_mac.c exchange.c \
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 59cadb4aad..5c11ce1b6a 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -28,7 +28,9 @@
#include "crypto/evp.h"
#include "internal/provider.h"
-static void EVP_PKEY_free_it(EVP_PKEY *x);
+static void evp_pkey_free_it(EVP_PKEY *key);
+
+#ifndef FIPS_MODE
int EVP_PKEY_bits(const EVP_PKEY *pkey)
{
@@ -46,16 +48,9 @@ int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
return pkey->ameth->pkey_security_bits(pkey);
}
-int EVP_PKEY_size(const EVP_PKEY *pkey)
-{
- if (pkey && pkey->ameth && pkey->ameth->pkey_size)
- return pkey->ameth->pkey_size(pkey);
- return 0;
-}
-
int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
{
-#ifndef OPENSSL_NO_DSA
+# ifndef OPENSSL_NO_DSA
if (pkey->type == EVP_PKEY_DSA) {
int ret = pkey->save_parameters;
@@ -63,8 +58,8 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
pkey->save_parameters = mode;
return ret;
}
-#endif
-#ifndef OPENSSL_NO_EC
+# endif
+# ifndef OPENSSL_NO_EC
if (pkey->type == EVP_PKEY_EC) {
int ret = pkey->save_parameters;
@@ -72,7 +67,7 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
pkey->save_parameters = mode;
return ret;
}
-#endif
+# endif
return 0;
}
@@ -141,38 +136,6 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
return -2;
}
-EVP_PKEY *EVP_PKEY_new(void)
-{
- EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
-
- if (ret == NULL) {
- EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
- ret->type = EVP_PKEY_NONE;
- ret->save_type = EVP_PKEY_NONE;
- ret->references = 1;
- ret->save_parameters = 1;
- ret->lock = CRYPTO_THREAD_lock_new();
- if (ret->lock == NULL) {
- EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(ret);
- return NULL;
- }
- return ret;
-}
-
-int EVP_PKEY_up_ref(EVP_PKEY *pkey)
-{
- int i;
-
- if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
- return 0;
-
- REF_PRINT_COUNT("EVP_PKEY", pkey);
- REF_ASSERT_ISNT(i < 2);
- return ((i > 1) ? 1 : 0);
-}
/*
* Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
@@ -187,29 +150,29 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
if (pkey) {
if (pkey->pkey.ptr)
- EVP_PKEY_free_it(pkey);
+ evp_pkey_free_it(pkey);
/*
* If key type matches and a method exists then this lookup has
* succeeded once so just indicate success.
*/
if ((type == pkey->save_type) && pkey->ameth)
return 1;
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
/* If we have ENGINEs release them */
ENGINE_finish(pkey->engine);
pkey->engine = NULL;
ENGINE_finish(pkey->pmeth_engine);
pkey->pmeth_engine = NULL;
-#endif
+# endif
}
if (str)
ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
else
ameth = EVP_PKEY_asn1_find(eptr, type);
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
if (pkey == NULL && eptr != NULL)
ENGINE_finish(e);
-#endif
+# endif
if (ameth == NULL) {
EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
return 0;
@@ -321,10 +284,10 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
size_t len, const EVP_CIPHER *cipher)
{
-#ifndef OPENSSL_NO_CMAC
-# ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_CMAC
+# ifndef OPENSSL_NO_ENGINE
const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
-# endif
+# endif
const char *cipher_name = EVP_CIPHER_name(cipher);
const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher);
OPENSSL_CTX *libctx =
@@ -342,11 +305,11 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
goto err;
}
-# ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
if (engine_id != NULL)
params[paramsn++] =
OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0);
-# endif
+# endif
params[paramsn++] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
@@ -369,11 +332,11 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
EVP_MAC_CTX_free(cmctx);
EVP_MAC_free(cmac);
return NULL;
-#else
+# else
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return NULL;
-#endif
+# endif
}
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
@@ -405,7 +368,7 @@ int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
return 1;
}
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
{
if (e != NULL) {
@@ -428,7 +391,7 @@ ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
{
return pkey->engine;
}
-#endif
+# endif
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
{
if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
@@ -454,7 +417,7 @@ const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
return os->data;
}
-#ifndef OPENSSL_NO_POLY1305
+# ifndef OPENSSL_NO_POLY1305
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
{
ASN1_OCTET_STRING *os = NULL;
@@ -466,9 +429,9 @@ const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
*len = os->length;
return os->data;
}
-#endif
+# endif
-#ifndef OPENSSL_NO_SIPHASH
+# ifndef OPENSSL_NO_SIPHASH
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
{
ASN1_OCTET_STRING *os = NULL;
@@ -481,9 +444,9 @@ const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
*len = os->length;
return os->data;
}
-#endif
+# endif
-#ifndef OPENSSL_NO_RSA
+# ifndef OPENSSL_NO_RSA
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
{
int ret = EVP_PKEY_assign_RSA(pkey, key);
@@ -508,9 +471,9 @@ RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
RSA_up_ref(ret);
return ret;
}
-#endif
+# endif
-#ifndef OPENSSL_NO_DSA
+# ifndef OPENSSL_NO_DSA
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
{
int ret = EVP_PKEY_assign_DSA(pkey, key);
@@ -535,9 +498,9 @@ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
DSA_up_ref(ret);
return ret;
}
-#endif
+# endif
-#ifndef OPENSSL_NO_EC
+# ifndef OPENSSL_NO_EC
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
{
@@ -563,9 +526,9 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
EC_KEY_up_ref(ret);
return ret;
}
-#endif
+# endif
-#ifndef OPENSSL_NO_DH
+# ifndef OPENSSL_NO_DH
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
{
@@ -593,7 +556,7 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
DH_up_ref(ret);
return ret;
}
-#endif
+# endif
int EVP_PKEY_type(int type)
{
@@ -605,9 +568,9 @@ int EVP_PKEY_type(int type)
ret = ameth->pkey_id;
else
ret = NID_undef;
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
ENGINE_finish(e);
-#endif
+# endif
return ret;
}
@@ -621,41 +584,6 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey)
return EVP_PKEY_type(pkey->type);
}
-void EVP_PKEY_free(EVP_PKEY *x)
-{
- int i;
-
- if (x == NULL)
- return;
-
- CRYPTO_DOWN_REF(&x->references, &i, x->lock);
- REF_PRINT_COUNT("EVP_PKEY", x);
- if (i > 0)
- return;
- REF_ASSERT_ISNT(i < 0);
- EVP_PKEY_free_it(x);
- CRYPTO_THREAD_lock_free(x->lock);
- sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
- OPENSSL_free(x);
-}
-
-static void EVP_PKEY_free_it(EVP_PKEY *x)
-{
- /* internal function; x is never NULL */
-
- evp_keymgmt_clear_pkey_cache(x);
-
- if (x->ameth && x->ameth->pkey_free) {
- x->ameth->pkey_free(x);
- x->pkey.ptr = NULL;
- }
-#ifndef OPENSSL_NO_ENGINE
- ENGINE_finish(x->engine);
- x->engine = NULL;
- ENGINE_finish(x->pmeth_engine);
- x->pmeth_engine = NULL;
-#endif
-}
static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent)
{
@@ -807,3 +735,87 @@ size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
return 0;
return rv;
}
+
+#endif /* FIPS_MODE */
+
+/*- All methods below can also be used in FIPS_MODE */
+
+EVP_PKEY *EVP_PKEY_new(void)
+{
+ EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ret->type = EVP_PKEY_NONE;
+ ret->save_type = EVP_PKEY_NONE;
+ ret->references = 1;
+ ret->save_parameters = 1;
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int EVP_PKEY_up_ref(EVP_PKEY *pkey)
+{
+ int i;
+
+ if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("EVP_PKEY", pkey);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
+static void evp_pkey_free_it(EVP_PKEY *x)
+{
+ /* internal function; x is never NULL */
+
+ evp_keymgmt_clear_pkey_cache(x);
+
+ if (x->ameth && x->ameth->pkey_free) {
+ x->ameth->pkey_free(x);
+ x->pkey.ptr = NULL;
+ }
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
+ ENGINE_finish(x->engine);
+ x->engine = NULL;
+ ENGINE_finish(x->pmeth_engine);
+ x->pmeth_engine = NULL;
+#endif
+}
+
+void EVP_PKEY_free(EVP_PKEY *x)
+{
+ int i;
+
+ if (x == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&x->references, &i, x->lock);
+ REF_PRINT_COUNT("EVP_PKEY", x);
+ if (i > 0)
+ return;
+ REF_ASSERT_ISNT(i < 0);
+ evp_pkey_free_it(x);
+ CRYPTO_THREAD_lock_free(x->lock);
+#ifndef FIPS_MODE
+ sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
+#endif
+ OPENSSL_free(x);
+}
+
+/* TODO (3.0) : Needs to call getparams fo non legacy case */
+int EVP_PKEY_size(const EVP_PKEY *pkey)
+{
+ if (pkey && pkey->ameth && pkey->ameth->pkey_size)
+ return pkey->ameth->pkey_size(pkey);
+ return 0;
+}
+
diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c
index 3d0ee2e646..31422baa4c 100644
--- a/crypto/evp/pmeth_fn.c
+++ b/crypto/evp/pmeth_fn.c
@@ -16,569 +16,6 @@
#include "internal/provider.h"
#include "evp_local.h"
-static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov)
-{
- EVP_SIGNATURE *signature = OPENSSL_zalloc(sizeof(EVP_SIGNATURE));
-
- if (signature == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- signature->lock = CRYPTO_THREAD_lock_new();
- if (signature->lock == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(signature);
- return NULL;
- }
- signature->prov = prov;
- ossl_provider_up_ref(prov);
- signature->refcnt = 1;
-
- return signature;
-}
-
-static void *evp_signature_from_dispatch(int name_id,
- const OSSL_DISPATCH *fns,
- OSSL_PROVIDER *prov)
-{
- EVP_SIGNATURE *signature = NULL;
- int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0;
- int digsignfncnt = 0, digverifyfncnt = 0;
- int gparamfncnt = 0, sparamfncnt = 0, gmdparamfncnt = 0, smdparamfncnt = 0;
-
- if ((signature = evp_signature_new(prov)) == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- signature->name_id = name_id;
-
- for (; fns->function_id != 0; fns++) {
- switch (fns->function_id) {
- case OSSL_FUNC_SIGNATURE_NEWCTX:
- if (signature->newctx != NULL)
- break;
- signature->newctx = OSSL_get_OP_signature_newctx(fns);
- ctxfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_SIGN_INIT:
- if (signature->sign_init != NULL)
- break;
- signature->sign_init = OSSL_get_OP_signature_sign_init(fns);
- signfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_SIGN:
- if (signature->sign != NULL)
- break;
- signature->sign = OSSL_get_OP_signature_sign(fns);
- signfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_VERIFY_INIT:
- if (signature->verify_init != NULL)
- break;
- signature->verify_init = OSSL_get_OP_signature_verify_init(fns);
- verifyfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_VERIFY:
- if (signature->verify != NULL)
- break;
- signature->verify = OSSL_get_OP_signature_verify(fns);
- verifyfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT:
- if (signature->verify_recover_init != NULL)
- break;
- signature->verify_recover_init
- = OSSL_get_OP_signature_verify_recover_init(fns);
- verifyrecfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER:
- if (signature->verify_recover != NULL)
- break;
- signature->verify_recover
- = OSSL_get_OP_signature_verify_recover(fns);
- verifyrecfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT:
- if (signature->digest_sign_init != NULL)
- break;
- signature->digest_sign_init
- = OSSL_get_OP_signature_digest_sign_init(fns);
- digsignfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE:
- if (signature->digest_sign_update != NULL)
- break;
- signature->digest_sign_update
- = OSSL_get_OP_signature_digest_sign_update(fns);
- digsignfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL:
- if (signature->digest_sign_final != NULL)
- break;
- signature->digest_sign_final
- = OSSL_get_OP_signature_digest_sign_final(fns);
- digsignfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT:
- if (signature->digest_verify_init != NULL)
- break;
- signature->digest_verify_init
- = OSSL_get_OP_signature_digest_verify_init(fns);
- digverifyfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE:
- if (signature->digest_verify_update != NULL)
- break;
- signature->digest_verify_update
- = OSSL_get_OP_signature_digest_verify_update(fns);
- digverifyfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL:
- if (signature->digest_verify_final != NULL)
- break;
- signature->digest_verify_final
- = OSSL_get_OP_signature_digest_verify_final(fns);
- digverifyfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_FREECTX:
- if (signature->freectx != NULL)
- break;
- signature->freectx = OSSL_get_OP_signature_freectx(fns);
- ctxfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_DUPCTX:
- if (signature->dupctx != NULL)
- break;
- signature->dupctx = OSSL_get_OP_signature_dupctx(fns);
- break;
- case OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS:
- if (signature->get_ctx_params != NULL)
- break;
- signature->get_ctx_params
- = OSSL_get_OP_signature_get_ctx_params(fns);
- gparamfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS:
- if (signature->gettable_ctx_params != NULL)
- break;
- signature->gettable_ctx_params
- = OSSL_get_OP_signature_gettable_ctx_params(fns);
- gparamfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS:
- if (signature->set_ctx_params != NULL)
- break;
- signature->set_ctx_params
- = OSSL_get_OP_signature_set_ctx_params(fns);
- sparamfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS:
- if (signature->settable_ctx_params != NULL)
- break;
- signature->settable_ctx_params
- = OSSL_get_OP_signature_settable_ctx_params(fns);
- sparamfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS:
- if (signature->get_ctx_md_params != NULL)
- break;
- signature->get_ctx_md_params
- = OSSL_get_OP_signature_get_ctx_md_params(fns);
- gmdparamfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS:
- if (signature->gettable_ctx_md_params != NULL)
- break;
- signature->gettable_ctx_md_params
- = OSSL_get_OP_signature_gettable_ctx_md_params(fns);
- gmdparamfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS:
- if (signature->set_ctx_md_params != NULL)
- break;
- signature->set_ctx_md_params
- = OSSL_get_OP_signature_set_ctx_md_params(fns);
- smdparamfncnt++;
- break;
- case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS:
- if (signature->settable_ctx_md_params != NULL)
- break;
- signature->settable_ctx_md_params
- = OSSL_get_OP_signature_settable_ctx_md_params(fns);
- smdparamfncnt++;
- break;
- }
- }
- if (ctxfncnt != 2
- || (signfncnt == 0
- && verifyfncnt == 0
- && verifyrecfncnt == 0
- && digsignfncnt == 0
- && digverifyfncnt == 0)
- || (signfncnt != 0 && signfncnt != 2)
- || (verifyfncnt != 0 && verifyfncnt != 2)
- || (verifyrecfncnt != 0 && verifyrecfncnt != 2)
- || (digsignfncnt != 0 && digsignfncnt != 3)
- || (digverifyfncnt != 0 && digverifyfncnt != 3)
- || (gparamfncnt != 0 && gparamfncnt != 2)
- || (sparamfncnt != 0 && sparamfncnt != 2)
- || (gmdparamfncnt != 0 && gmdparamfncnt != 2)
- || (smdparamfncnt != 0 && smdparamfncnt != 2)) {
- /*
- * In order to be a consistent set of functions we must have at least
- * a set of context functions (newctx and freectx) as well as a set of
- * "signature" functions:
- * (sign_init, sign) or
- * (verify_init verify) or
- * (verify_recover_init, verify_recover) or
- * (digest_sign_init, digest_sign_update, digest_sign_final) or
- * (digest_verify_init, digest_verify_update, digest_verify_final).
- *
- * set_ctx_params and settable_ctx_params are optional, but if one of
- * them is present then the other one must also be present. The same
- * applies to get_ctx_params and gettable_ctx_params. The same rules
- * apply to the "md_params" functions. The dupctx function is optional.
- */
- ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
- goto err;
- }
-
- return signature;
- err:
- EVP_SIGNATURE_free(signature);
- return NULL;
-}
-
-void EVP_SIGNATURE_free(EVP_SIGNATURE *signature)
-{
- if (signature != NULL) {
- int i;
-
- CRYPTO_DOWN_REF(&signature->refcnt, &i, signature->lock);
- if (i > 0)
- return;
- ossl_provider_free(signature->prov);
- CRYPTO_THREAD_lock_free(signature->lock);
- OPENSSL_free(signature);
- }
-}
-
-int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature)
-{
- int ref = 0;
-
- CRYPTO_UP_REF(&signature->refcnt, &ref, signature->lock);
- return 1;
-}
-
-OSSL_PROVIDER *EVP_SIGNATURE_provider(const EVP_SIGNATURE *signature)
-{
- return signature->prov;
-}
-
-EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm,
- const char *properties)
-{
- return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties,
- evp_signature_from_dispatch,
- (int (*)(void *))EVP_SIGNATURE_up_ref,
- (void (*)(void *))EVP_SIGNATURE_free);
-}
-
-int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name)
-{
- return evp_is_a(signature->prov, signature->name_id, name);
-}
-
-int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature)
-{
- return signature->name_id;
-}
-
-void EVP_SIGNATURE_do_all_provided(OPENSSL_CTX *libctx,
- void (*fn)(EVP_SIGNATURE *signature,
- void *arg),
- void *arg)
-{
- evp_generic_do_all(libctx, OSSL_OP_SIGNATURE,
- (void (*)(void *, void *))fn, arg,
- evp_signature_from_dispatch,
- (void (*)(void *))EVP_SIGNATURE_free);
-}
-
-
-void EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature,
- void (*fn)(const char *name, void *data),
- void *data)
-{
- if (signature->prov != NULL)
- evp_names_do_all(signature->prov, signature->name_id, fn, data);
-}
-
-static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation)
-{
- int ret = 0;
- void *provkey = NULL;
- EVP_SIGNATURE *signature = NULL;
-
- if (ctx == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- evp_pkey_ctx_free_old_ops(ctx);
- ctx->operation = operation;
-
- if (ctx->keytype == NULL)
- goto legacy;
-
- if (ctx->keymgmt == NULL)
- ctx->keymgmt =
- EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
- if (ctx->keymgmt != NULL) {
- const char *supported_sig = NULL;
-
- if (ctx->keymgmt->query_operation_name != NULL)
- supported_sig =
- ctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE);
-
- /*
- * If we didn't get a supported sig, assume there is one with the
- * same name as the key type.
- */
- if (supported_sig == NULL)
- supported_sig = ctx->keytype;
-
- /*
- * Because we cleared out old ops, we shouldn't need to worry about
- * checking if signature is already there.
- */
- signature =
- EVP_SIGNATURE_fetch(ctx->libctx, supported_sig, ctx->propquery);
- }
-
- if (ctx->keymgmt == NULL
- || signature == NULL
- || (EVP_KEYMGMT_provider(ctx->keymgmt)
- != EVP_SIGNATURE_provider(signature))) {
- /*
- * We don't have the full support we need with provided methods,
- * let's go see if legacy does. Also, we don't need to free
- * ctx->keymgmt here, as it's not necessarily tied to this
- * operation. It will be freed by EVP_PKEY_CTX_free().
- */
- EVP_SIGNATURE_free(signature);
- goto legacy;
- }
-
- ctx->op.sig.signature = signature;
-
- if (ctx->pkey != NULL) {
- provkey =
- evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0);
- /* If export failed, legacy may be able to pick it up */
- if (provkey == NULL)
- goto legacy;
- }
- ctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov));
- if (ctx->op.sig.sigprovctx == NULL) {
- /* The provider key can stay in the cache */
- EVPerr(0, EVP_R_INITIALIZATION_ERROR);
- goto err;
- }
-
- switch (operation) {
- case EVP_PKEY_OP_SIGN:
- if (signature->sign_init == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- ret = -2;
- goto err;
- }
- ret = signature->sign_init(ctx->op.sig.sigprovctx, provkey);
- break;
- case EVP_PKEY_OP_VERIFY:
- if (signature->verify_init == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- ret = -2;
- goto err;
- }
- ret = signature->verify_init(ctx->op.sig.sigprovctx, provkey);
- break;
- case EVP_PKEY_OP_VERIFYRECOVER:
- if (signature->verify_recover_init == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- ret = -2;
- goto err;
- }
- ret = signature->verify_recover_init(ctx->op.sig.sigprovctx, provkey);
- break;
- default:
- EVPerr(0, EVP_R_INITIALIZATION_ERROR);
- goto err;
- }
-
- if (ret <= 0) {
- signature->freectx(ctx->op.sig.sigprovctx);
- ctx->op.sig.sigprovctx = NULL;
- goto err;
- }
- return 1;
-
- legacy:
- if (ctx->pmeth == NULL
- || (operation == EVP_PKEY_OP_SIGN && ctx->pmeth->sign == NULL)
- || (operation == EVP_PKEY_OP_VERIFY && ctx->pmeth->verify == NULL)
- || (operation == EVP_PKEY_OP_VERIFYRECOVER
- && ctx->pmeth->verify_recover == NULL)) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- switch (operation) {
- case EVP_PKEY_OP_SIGN:
- if (ctx->pmeth->sign_init == NULL)
- return 1;
- ret = ctx->pmeth->sign_init(ctx);
- break;
- case EVP_PKEY_OP_VERIFY:
- if (ctx->pmeth->verify_init == NULL)
- return 1;
- ret = ctx->pmeth->verify_init(ctx);
- break;
- case EVP_PKEY_OP_VERIFYRECOVER:
- if (ctx->pmeth->verify_recover_init == NULL)
- return 1;
- ret = ctx->pmeth->verify_recover_init(ctx);
- break;
- default:
- EVPerr(0, EVP_R_INITIALIZATION_ERROR);
- goto err;
- }
- if (ret <= 0)
- goto err;
- return ret;
-
- err:
- ctx->operation = EVP_PKEY_OP_UNDEFINED;
- return ret;
-}
-
-int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
-{
- return evp_pkey_signature_init(ctx, EVP_PKEY_OP_SIGN);
-}
-
-int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
- unsigned char *sig, size_t *siglen,
- const unsigned char *tbs, size_t tbslen)
-{
- int ret;
-
- if (ctx == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- if (ctx->operation != EVP_PKEY_OP_SIGN) {
- EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
- return -1;
- }
-
- if (ctx->op.sig.sigprovctx == NULL)
- goto legacy;
-
- ret = ctx->op.sig.signature->sign(ctx->op.sig.sigprovctx, sig, siglen,
- SIZE_MAX, tbs, tbslen);
-
- return ret;
- legacy:
-
- if (ctx->pmeth == NULL || ctx->pmeth->sign == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
- return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
-}
-
-int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
-{
- return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFY);
-}
-
-int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
- const unsigned char *sig, size_t siglen,
- const unsigned char *tbs, size_t tbslen)
-{
- int ret;
-
- if (ctx == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- if (ctx->operation != EVP_PKEY_OP_VERIFY) {
- EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
- return -1;
- }
-
- if (ctx->op.sig.sigprovctx == NULL)
- goto legacy;
-
- ret = ctx->op.sig.signature->verify(ctx->op.sig.sigprovctx, sig, siglen,
- tbs, tbslen);
-
- return ret;
- legacy:
- if (ctx->pmeth == NULL || ctx->pmeth->verify == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
-}
-
-int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
-{
- return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFYRECOVER);
-}
-
-int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
- unsigned char *rout, size_t *routlen,
- const unsigned char *sig, size_t siglen)
-{
- int ret;
-
- if (ctx == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
- EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
- return -1;
- }
-
- if (ctx->op.sig.sigprovctx == NULL)
- goto legacy;
-
- ret = ctx->op.sig.signature->verify_recover(ctx->op.sig.sigprovctx, rout,
- routlen,
- (rout == NULL ? 0 : *routlen),
- sig, siglen);
- return ret;
- legacy:
- if (ctx->pmeth == NULL || ctx->pmeth->verify_recover == NULL) {
- EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
- M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
- return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
-}
-
static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation)
{
int ret = 0;
diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c
index 100931cda7..14c5fd4b99 100644
--- a/crypto/evp/pmeth_gn.c
+++ b/crypto/evp/pmeth_gn.c
@@ -17,89 +17,7 @@
#include "crypto/evp.h"
#include "evp_local.h"
-static int fromdata_init(EVP_PKEY_CTX *ctx, int operation)
-{
- if (ctx == NULL || ctx->keytype == NULL)
- goto not_supported;
-
- evp_pkey_ctx_free_old_ops(ctx);
- ctx->operation = operation;
- if (ctx->keymgmt == NULL)
- ctx->keymgmt = EVP_KEYMGMT_fetch(NULL, ctx->keytype, ctx->propquery);
- if (ctx->keymgmt == NULL)
- goto not_supported;
-
- return 1;
-
- not_supported:
- ctx->operation = EVP_PKEY_OP_UNDEFINED;
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
-}
-
-int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx)
-{
- return fromdata_init(ctx, EVP_PKEY_OP_PARAMFROMDATA);
-}
-
-int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx)
-{
- return fromdata_init(ctx, EVP_PKEY_OP_KEYFROMDATA);
-}
-
-int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[])
-{
- void *provdata = NULL;
-
- if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) {
- ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- if (ppkey == NULL)
- return -1;
-
- if (*ppkey == NULL)
- *ppkey = EVP_PKEY_new();
-
- if (*ppkey == NULL) {
- ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
- return -1;
- }
-
- provdata =
- evp_keymgmt_fromdata(*ppkey, ctx->keymgmt, params,
- ctx->operation == EVP_PKEY_OP_PARAMFROMDATA);
-
- if (provdata == NULL)
- return 0;
- /* provdata is cached in *ppkey, so we need not bother with it further */
- return 1;
-}
-
-/*
- * TODO(3.0) Re-evaluate the names, it's possible that we find these to be
- * better:
- *
- * EVP_PKEY_param_settable()
- * EVP_PKEY_param_gettable()
- */
-const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx)
-{
- /* We call fromdata_init to get ctx->keymgmt populated */
- if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
- return evp_keymgmt_importdomparam_types(ctx->keymgmt);
- return NULL;
-}
-
-const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx)
-{
- /* We call fromdata_init to get ctx->keymgmt populated */
- if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
- return evp_keymgmt_importdomparam_types(ctx->keymgmt);
- return NULL;
-}
-
+#ifndef FIPS_MODE
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
{
int ret;
@@ -321,3 +239,93 @@ int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
return pkey->ameth->pkey_param_check(pkey);
}
+
+#endif /* FIPS_MODE */
+
+/*- All methods below can also be used in FIPS_MODE */
+
+static int fromdata_init(EVP_PKEY_CTX *ctx, int operation)
+{
+ if (ctx == NULL || ctx->keytype == NULL)
+ goto not_supported;
+
+ evp_pkey_ctx_free_old_ops(ctx);
+ ctx->operation = operation;
+ if (ctx->keymgmt == NULL)
+ ctx->keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype,
+ ctx->propquery);
+ if (ctx->keymgmt == NULL)
+ goto not_supported;
+
+ return 1;
+
+ not_supported:
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+}
+
+int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx)
+{
+ return fromdata_init(ctx, EVP_PKEY_OP_PARAMFROMDATA);
+}
+
+int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx)
+{
+ return fromdata_init(ctx, EVP_PKEY_OP_KEYFROMDATA);
+}
+
+int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[])
+{
+ void *provdata = NULL;
+
+ if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ if (ppkey == NULL)
+ return -1;
+
+ if (*ppkey == NULL)
+ *ppkey = EVP_PKEY_new();
+
+ if (*ppkey == NULL) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ provdata =
+ evp_keymgmt_fromdata(*ppkey, ctx->keymgmt, params,
+ ctx->operation == EVP_PKEY_OP_PARAMFROMDATA);
+
+ if (provdata == NULL)
+ return 0;
+ /* provdata is cached in *ppkey, so we need not bother with it further */
+ return 1;
+}
+
+/*
+ * TODO(3.0) Re-evaluate the names, it's possible that we find these to be
+ * better:
+ *
+ * EVP_PKEY_param_settable()
+ * EVP_PKEY_param_gettable()
+ */
+const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx)
+{
+ /* We call fromdata_init to get ctx->keymgmt populated */
+ if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
+ return evp_keymgmt_importdomparam_types(ctx->keymgmt);
+ return NULL;
+}
+
+const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx)
+{
+ /* We call fromdata_init to get ctx->keymgmt populated */
+ if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
+ return evp_keymgmt_importdomparam_types(ctx->keymgmt);
+ return NULL;
+}
+
+
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 2ecc17734e..428b97b7b5 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -23,6 +23,8 @@
#include "internal/provider.h"
#include "evp_local.h"
+#ifndef FIPS_MODE
+
typedef const EVP_PKEY_METHOD *(*pmeth_fn)(void);
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
@@ -30,50 +32,50 @@ static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
/* This array needs to be in order of NIDs */
static pmeth_fn standard_methods[] = {
-#ifndef OPENSSL_NO_RSA
+# ifndef OPENSSL_NO_RSA
rsa_pkey_method,
-#endif
-#ifndef OPENSSL_NO_DH
+# endif
+# ifndef OPENSSL_NO_DH
dh_pkey_method,
-#endif
-#ifndef OPENSSL_NO_DSA
+# endif
+# ifndef OPENSSL_NO_DSA
dsa_pkey_method,
-#endif
-#ifndef OPENSSL_NO_EC
+# endif
+# ifndef OPENSSL_NO_EC
ec_pkey_method,
-#endif
+# endif
hmac_pkey_method,
-#ifndef OPENSSL_NO_CMAC
+# ifndef OPENSSL_NO_CMAC
cmac_pkey_method,
-#endif
-#ifndef OPENSSL_NO_RSA
+# endif
+# ifndef OPENSSL_NO_RSA
rsa_pss_pkey_method,
-#endif
-#ifndef OPENSSL_NO_DH
+# endif
+# ifndef OPENSSL_NO_DH
dhx_pkey_method,
-#endif
-#ifndef OPENSSL_NO_SCRYPT
+# endif
+# ifndef OPENSSL_NO_SCRYPT
scrypt_pkey_method,
-#endif
+# endif
tls1_prf_pkey_method,
-#ifndef OPENSSL_NO_EC
+# ifndef OPENSSL_NO_EC
ecx25519_pkey_method,
ecx448_pkey_method,
-#endif
+# endif
hkdf_pkey_method,
-#ifndef OPENSSL_NO_POLY1305
+# ifndef OPENSSL_NO_POLY1305
poly1305_pkey_method,
-#endif
-#ifndef OPENSSL_NO_SIPHASH
+# endif
+# ifndef OPENSSL_NO_SIPHASH
siphash_pkey_method,
-#endif
-#ifndef OPENSSL_NO_EC
+# endif
+# ifndef OPENSSL_NO_EC
ed25519_pkey_method,
ed448_pkey_method,
-#endif
-#ifndef OPENSSL_NO_SM2
+# endif
+# ifndef OPENSSL_NO_SM2
sm2_pkey_method,
-#endif
+# endif
};
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func);
@@ -112,10 +114,27 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
return (**ret)();
}
+EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
+{
+ EVP_PKEY_METHOD *pmeth;
+
+ pmeth = OPENSSL_zalloc(sizeof(*pmeth));
+ if (pmeth == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ pmeth->pkey_id = id;
+ pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
+ return pmeth;
+}
+#endif /* FIPS_MODE */
+
static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
EVP_PKEY *pkey, ENGINE *e,
const char *name, const char *propquery,
int id)
+
{
EVP_PKEY_CTX *ret;
const EVP_PKEY_METHOD *pmeth = NULL;
@@ -131,7 +150,7 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
* If the key doesn't contain anything legacy, then it must be provided,
* so we extract the necessary information and use that.
*/
- if (pkey != NULL && pkey->ameth == NULL) {
+ if (pkey != NULL && pkey->pkey.ptr == NULL) {
/* If we have an engine, something went wrong somewhere... */
if (!ossl_assert(e == NULL))
return NULL;
@@ -143,7 +162,7 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
*/
goto common;
}
-
+#ifndef FIPS_MODE
/* TODO(3.0) Legacy code should be removed when all is provider based */
/* BEGIN legacy */
if (id == -1) {
@@ -179,7 +198,7 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
*/
libctx = NULL;
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
if (e == NULL && pkey != NULL)
e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : pkey->engine;
/* Try to find an ENGINE which implements this method */
@@ -199,22 +218,22 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
if (e)
pmeth = ENGINE_get_pkey_meth(e, id);
else
-#endif
+# endif
pmeth = EVP_PKEY_meth_find(id);
if (pmeth == NULL) {
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
ENGINE_finish(e);
-#endif
+# endif
EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
return NULL;
}
/* END legacy */
-
+#endif /* FIPS_MODE */
common:
ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
ENGINE_finish(e);
#endif
EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
@@ -241,20 +260,37 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
return ret;
}
+/*- All methods below can also be used in FIPS_MODE */
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx,
+ const char *name,
+ const char *propquery)
+{
+ return int_ctx_new(libctx, NULL, NULL, name, propquery, -1);
+}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx, EVP_PKEY *pkey)
+{
+ return int_ctx_new(libctx, pkey, NULL, NULL, NULL, -1);
+}
+
void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx)
{
- if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
- if (ctx->op.kex.exchprovctx != NULL && ctx->op.kex.exchange != NULL)
- ctx->op.kex.exchange->freectx(ctx->op.kex.exchprovctx);
- EVP_KEYEXCH_free(ctx->op.kex.exchange);
- ctx->op.kex.exchprovctx = NULL;
- ctx->op.kex.exchange = NULL;
- } else if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
+ if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
if (ctx->op.sig.sigprovctx != NULL && ctx->op.sig.signature != NULL)
ctx->op.sig.signature->freectx(ctx->op.sig.sigprovctx);
EVP_SIGNATURE_free(ctx->op.sig.signature);
ctx->op.sig.sigprovctx = NULL;
ctx->op.sig.signature = NULL;
+ }
+/* TODO(3.0): add dependancies and uncomment this when available for fips mode */
+#ifndef FIPS_MODE
+ else if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
+ if (ctx->op.kex.exchprovctx != NULL && ctx->op.kex.exchange != NULL)
+ ctx->op.kex.exchange->freectx(ctx->op.kex.exchprovctx);
+ EVP_KEYEXCH_free(ctx->op.kex.exchange);
+ ctx->op.kex.exchprovctx = NULL;
+ ctx->op.kex.exchange = NULL;
} else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
if (ctx->op.ciph.ciphprovctx != NULL && ctx->op.ciph.cipher != NULL)
ctx->op.ciph.cipher->freectx(ctx->op.ciph.ciphprovctx);
@@ -262,23 +298,29 @@ void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx)
ctx->op.ciph.ciphprovctx = NULL;
ctx->op.ciph.cipher = NULL;
}
+#endif
}
-EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
{
- EVP_PKEY_METHOD *pmeth;
+ if (ctx == NULL)
+ return;
+ if (ctx->pmeth && ctx->pmeth->cleanup)
+ ctx->pmeth->cleanup(ctx);
- pmeth = OPENSSL_zalloc(sizeof(*pmeth));
- if (pmeth == NULL) {
- EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ evp_pkey_ctx_free_old_ops(ctx);
+ EVP_KEYMGMT_free(ctx->keymgmt);
- pmeth->pkey_id = id;
- pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
- return pmeth;
+ EVP_PKEY_free(ctx->pkey);
+ EVP_PKEY_free(ctx->peerkey);
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
+ ENGINE_finish(ctx->engine);
+#endif
+ OPENSSL_free(ctx);
}
+#ifndef FIPS_MODE
+
void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
const EVP_PKEY_METHOD *meth)
{
@@ -347,12 +389,6 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
return int_ctx_new(NULL, NULL, e, NULL, NULL, id);
}
-EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(OPENSSL_CTX *libctx,
- const char *name,
- const char *propquery)
-{
- return int_ctx_new(libctx, NULL, NULL, name, propquery, -1);
-}
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
{
@@ -364,13 +400,13 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)
&& pctx->op.sig.sigprovctx == NULL)))
return NULL;
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
/* Make sure it's safe to copy a pkey context using an ENGINE */
if (pctx->engine && !ENGINE_init(pctx->engine)) {
EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
return 0;
}
-#endif
+# endif
rctx = OPENSSL_zalloc(sizeof(*rctx));
if (rctx == NULL) {
EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE);
@@ -448,9 +484,9 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
}
rctx->pmeth = pctx->pmeth;
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
rctx->engine = pctx->engine;
-#endif
+# endif
if (pctx->peerkey)
EVP_PKEY_up_ref(pctx->peerkey);
@@ -517,25 +553,32 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx)
return NULL;
return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
}
+#endif
-void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
+int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
{
- if (ctx == NULL)
- return;
- if (ctx->pmeth && ctx->pmeth->cleanup)
- ctx->pmeth->cleanup(ctx);
-
- evp_pkey_ctx_free_old_ops(ctx);
- EVP_KEYMGMT_free(ctx->keymgmt);
-
- EVP_PKEY_free(ctx->pkey);
- EVP_PKEY_free(ctx->peerkey);
-#ifndef OPENSSL_NO_ENGINE
- ENGINE_finish(ctx->engine);
-#endif
- OPENSSL_free(ctx);
+ if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
+ && ctx->op.kex.exchprovctx != NULL
+ && ctx->op.kex.exchange != NULL
+ && ctx->op.kex.exchange->set_ctx_params != NULL)
+ return ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx,
+ params);
+ if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
+ && ctx->op.sig.sigprovctx != NULL
+ && ctx->op.sig.signature != NULL
+ && ctx->op.sig.signature->set_ctx_params != NULL)
+ return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx,
+ params);
+ if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
+ && ctx->op.ciph.ciphprovctx != NULL
+ && ctx->op.ciph.cipher != NULL
+ && ctx->op.ciph.cipher->set_ctx_params != NULL)
+ return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx,
+ params);
+ return 0;
}
+#ifndef FIPS_MODE
int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
{
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
@@ -568,29 +611,6 @@ const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx)
return NULL;
}
-int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
-{
- if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
- && ctx->op.kex.exchprovctx != NULL
- && ctx->op.kex.exchange != NULL
- && ctx->op.kex.exchange->set_ctx_params != NULL)
- return ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx,
- params);
- if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
- && ctx->op.sig.sigprovctx != NULL
- && ctx->op.sig.signature != NULL
- && ctx->op.sig.signature->set_ctx_params != NULL)
- return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx,
- params);
- if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
- && ctx->op.ciph.ciphprovctx != NULL
- && ctx->op.ciph.cipher != NULL
- && ctx->op.ciph.cipher->set_ctx_params != NULL)
- return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx,
- params);
- return 0;
-}
-
const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
{
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
@@ -609,7 +629,7 @@ const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
return NULL;
}
-#ifndef OPENSSL_NO_DH
+# ifndef OPENSSL_NO_DH
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
{
OSSL_PARAM dh_pad_params[2];
@@ -631,7 +651,7 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
return EVP_PKEY_CTX_set_params(ctx, dh_pad_params);
}
-#endif
+# endif
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
{
@@ -711,10 +731,10 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2)
{
switch (cmd) {
-#ifndef OPENSSL_NO_DH
+# ifndef OPENSSL_NO_DH
case EVP_PKEY_CTRL_DH_PAD:
return EVP_PKEY_CTX_set_dh_pad(ctx, p1);
-#endif
+# endif
case EVP_PKEY_CTRL_MD:
return EVP_PKEY_CTX_set_signature_md(ctx, p2);
case EVP_PKEY_CTRL_GET_MD:
@@ -737,10 +757,10 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2);
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
-#ifndef OPENSSL_NO_CMS
+# ifndef OPENSSL_NO_CMS
case EVP_PKEY_CTRL_CMS_DECRYPT:
case EVP_PKEY_CTRL_CMS_ENCRYPT:
-#endif
+# endif
if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
return 1;
ERR_raise(ERR_LIB_EVP,
@@ -806,14 +826,14 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
const char *value)
{
-#ifndef OPENSSL_NO_DH
+# ifndef OPENSSL_NO_DH
if (strcmp(name, "dh_pad") == 0) {
int pad;
pad = atoi(value);
return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
}
-#endif
+# endif
if (strcmp(name, "digest") == 0) {
int ret;
EVP_MD *md;
@@ -1380,3 +1400,5 @@ void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
if (pdigest_custom != NULL)
*pdigest_custom = pmeth->digest_custom;
}
+
+#endif /* FIPS_MODE */
diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c
new file mode 100644
index 0000000000..119cd322a3
--- /dev/null
+++ b/crypto/evp/signature.c
@@ -0,0 +1,580 @@
+/*
+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include "internal/cryptlib.h"
+#include "crypto/evp.h"
+#include "internal/provider.h"
+#include "evp_local.h"
+
+static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov)
+{
+ EVP_SIGNATURE *signature = OPENSSL_zalloc(sizeof(EVP_SIGNATURE));
+
+ if (signature == NULL) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ signature->lock = CRYPTO_THREAD_lock_new();
+ if (signature->lock == NULL) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(signature);
+ return NULL;
+ }
+ signature->prov = prov;
+ ossl_provider_up_ref(prov);
+ signature->refcnt = 1;
+
+ return signature;
+}
+
+static void *evp_signature_from_dispatch(int name_id,
+ const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov)
+{
+ EVP_SIGNATURE *signature = NULL;
+ int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0;
+ int digsignfncnt = 0, digverifyfncnt = 0;
+ int gparamfncnt = 0, sparamfncnt = 0, gmdparamfncnt = 0, smdparamfncnt = 0;
+
+ if ((signature = evp_signature_new(prov)) == NULL) {
+ ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ signature->name_id = name_id;
+
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_SIGNATURE_NEWCTX:
+ if (signature->newctx != NULL)
+ break;
+ signature->newctx = OSSL_get_OP_signature_newctx(fns);
+ ctxfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_SIGN_INIT:
+ if (signature->sign_init != NULL)
+ break;
+ signature->sign_init = OSSL_get_OP_signature_sign_init(fns);
+ signfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_SIGN:
+ if (signature->sign != NULL)
+ break;
+ signature->sign = OSSL_get_OP_signature_sign(fns);
+ signfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_VERIFY_INIT:
+ if (signature->verify_init != NULL)
+ break;
+ signature->verify_init = OSSL_get_OP_signature_verify_init(fns);
+ verifyfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_VERIFY:
+ if (signature->verify != NULL)
+ break;
+ signature->verify = OSSL_get_OP_signature_verify(fns);
+ verifyfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT:
+ if (signature->verify_recover_init != NULL)
+ break;
+ signature->verify_recover_init
+ = OSSL_get_OP_signature_verify_recover_init(fns);
+ verifyrecfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER:
+ if (signature->verify_recover != NULL)
+ break;
+ signature->verify_recover
+ = OSSL_get_OP_signature_verify_recover(fns);
+ verifyrecfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT:
+ if (signature->digest_sign_init != NULL)
+ break;
+ signature->digest_sign_init
+ = OSSL_get_OP_signature_digest_sign_init(fns);
+ digsignfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE:
+ if (signature->digest_sign_update != NULL)
+ break;
+ signature->digest_sign_update
+ = OSSL_get_OP_signature_digest_sign_update(fns);
+ digsignfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL:
+ if (signature->digest_sign_final != NULL)
+ break;
+ signature->digest_sign_final
+ = OSSL_get_OP_signature_digest_sign_final(fns);
+ digsignfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT:
+ if (signature->digest_verify_init != NULL)
+ break;
+ signature->digest_verify_init
+ = OSSL_get_OP_signature_digest_verify_init(fns);
+ digverifyfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE:
+ if (signature->digest_verify_update != NULL)
+ break;
+ signature->digest_verify_update
+ = OSSL_get_OP_signature_digest_verify_update(fns);
+ digverifyfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL:
+ if (signature->digest_verify_final != NULL)
+ break;
+ signature->digest_verify_final
+ = OSSL_get_OP_signature_digest_verify_final(fns);
+ digverifyfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_FREECTX:
+ if (signature->freectx != NULL)
+ break;
+ signature->freectx = OSSL_get_OP_signature_freectx(fns);
+ ctxfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_DUPCTX:
+ if (signature->dupctx != NULL)
+ break;
+ signature->dupctx = OSSL_get_OP_signature_dupctx(fns);
+ break;
+ case OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS:
+ if (signature->get_ctx_params != NULL)
+ break;
+ signature->get_ctx_params
+ = OSSL_get_OP_signature_get_ctx_params(fns);
+ gparamfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS:
+ if (signature->gettable_ctx_params != NULL)
+ break;
+ signature->gettable_ctx_params
+ = OSSL_get_OP_signature_gettable_ctx_params(fns);
+ gparamfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS:
+ if (signature->set_ctx_params != NULL)
+ break;
+ signature->set_ctx_params
+ = OSSL_get_OP_signature_set_ctx_params(fns);
+ sparamfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS:
+ if (signature->settable_ctx_params != NULL)
+ break;
+ signature->settable_ctx_params
+ = OSSL_get_OP_signature_settable_ctx_params(fns);
+ sparamfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS:
+ if (signature->get_ctx_md_params != NULL)
+ break;
+ signature->get_ctx_md_params
+ = OSSL_get_OP_signature_get_ctx_md_params(fns);
+ gmdparamfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS:
+ if (signature->gettable_ctx_md_params != NULL)
+ break;
+ signature->gettable_ctx_md_params
+ = OSSL_get_OP_signature_gettable_ctx_md_params(fns);
+ gmdparamfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS:
+ if (signature->set_ctx_md_params != NULL)
+ break;
+ signature->set_ctx_md_params
+ = OSSL_get_OP_signature_set_ctx_md_params(fns);
+ smdparamfncnt++;
+ break;
+ case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS:
+ if (signature->settable_ctx_md_params != NULL)
+ break;
+ signature->settable_ctx_md_params
+ = OSSL_get_OP_signature_settable_ctx_md_params(fns);
+ smdparamfncnt++;
+ break;
+ }
+ }
+ if (ctxfncnt != 2
+ || (signfncnt == 0
+ && verifyfncnt == 0
+ && verifyrecfncnt == 0
+ && digsignfncnt == 0
+ && digverifyfncnt == 0)
+ || (signfncnt != 0 && signfncnt != 2)
+ || (verifyfncnt != 0 && verifyfncnt != 2)
+ || (verifyrecfncnt != 0 && verifyrecfncnt != 2)
+ || (digsignfncnt != 0 && digsignfncnt != 3)
+ || (digverifyfncnt != 0 && digverifyfncnt != 3)
+ || (gparamfncnt != 0 && gparamfncnt != 2)
+ || (sparamfncnt != 0 && sparamfncnt != 2)
+ || (gmdparamfncnt != 0 && gmdparamfncnt != 2)
+ || (smdparamfncnt != 0 && smdparamfncnt != 2)) {
+ /*
+ * In order to be a consistent set of functions we must have at least
+ * a set of context functions (newctx and freectx) as well as a set of
+ * "signature" functions:
+ * (sign_init, sign) or
+ * (verify_init verify) or
+ * (verify_recover_init, verify_recover) or
+ * (digest_sign_init, digest_sign_update, digest_sign_final) or
+ * (digest_verify_init, digest_verify_update, digest_verify_final).
+ *
+ * set_ctx_params and settable_ctx_params are optional, but if one of
+ * them is present then the other one must also be present. The same
+ * applies to get_ctx_params and gettable_ctx_params. The same rules
+ * apply to the "md_params" functions. The dupctx function is optional.
+ */
+ ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
+ goto err;
+ }
+
+ return signature;
+ err:
+ EVP_SIGNATURE_free(signature);
+ return NULL;
+}
+
+void EVP_SIGNATURE_free(EVP_SIGNATURE *signature)
+{
+ if (signature != NULL) {
+ int i;
+
+ CRYPTO_DOWN_REF(&signature->refcnt, &i, signature->lock);
+ if (i > 0)
+ return;
+ ossl_provider_free(signature->prov);
+ CRYPTO_THREAD_lock_free(signature->lock);
+ OPENSSL_free(signature);
+ }
+}
+
+int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature)
+{
+ int ref = 0;
+
+ CRYPTO_UP_REF(&signature->refcnt, &ref, signature->lock);
+ return 1;
+}
+
+OSSL_PROVIDER *EVP_SIGNATURE_provider(const EVP_SIGNATURE *signature)
+{
+ return signature->prov;
+}
+
+EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm,
+ const char *properties)
+{
+ return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties,
+ evp_signature_from_dispatch,
+ (int (*)(void *))EVP_SIGNATURE_up_ref,
+ (void (*)(void *))EVP_SIGNATURE_free);
+}
+
+int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name)
+{
+ return evp_is_a(signature->prov, signature->name_id, name);
+}
+
+int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature)
+{
+ return signature->name_id;
+}
+
+void EVP_SIGNATURE_do_all_provided(OPENSSL_CTX *libctx,
+ void (*fn)(EVP_SIGNATURE *signature,
+ void *arg),
+ void *arg)
+{
+ evp_generic_do_all(libctx, OSSL_OP_SIGNATURE,
+ (void (*)(void *, void *))fn, arg,
+ evp_signature_from_dispatch,
+ (void (*)(void *))EVP_SIGNATURE_free);
+}
+
+
+void EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature,
+ void (*fn)(const char *name, void *data),
+ void *data)
+{
+ if (signature->prov != NULL)
+ evp_names_do_all(signature->prov, signature->name_id, fn, data);
+}
+
+static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation)
+{
+ int ret = 0;
+ void *provkey = NULL;
+ EVP_SIGNATURE *signature = NULL;
+
+ if (ctx == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ evp_pkey_ctx_free_old_ops(ctx);
+ ctx->operation = operation;
+
+ if (ctx->keytype == NULL)
+ goto legacy;
+
+ if (ctx->keymgmt == NULL)
+ ctx->keymgmt =
+ EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
+ if (ctx->keymgmt != NULL) {
+ const char *supported_sig = NULL;
+
+ if (ctx->keymgmt->query_operation_name != NULL)
+ supported_sig =
+ ctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE);
+
+ /*
+ * If we didn't get a supported sig, assume there is one with the
+ * same name as the key type.
+ */
+ if (supported_sig == NULL)
+ supported_sig = ctx->keytype;
+
+ /*
+ * Because we cleared out old ops, we shouldn't need to worry about
+ * checking if signature is already there.
+ */
+ signature =
+ EVP_SIGNATURE_fetch(ctx->libctx, supported_sig, ctx->propquery);
+ }
+
+ if (ctx->keymgmt == NULL
+ || signature == NULL
+ || (EVP_KEYMGMT_provider(ctx->keymgmt)
+ != EVP_SIGNATURE_provider(signature))) {
+ /*
+ * We don't have the full support we need with provided methods,
+ * let's go see if legacy does. Also, we don't need to free
+ * ctx->keymgmt here, as it's not necessarily tied to this
+ * operation. It will be freed by EVP_PKEY_CTX_free().
+ */
+ EVP_SIGNATURE_free(signature);
+ goto legacy;
+ }
+
+ ctx->op.sig.signature = signature;
+
+ if (ctx->pkey != NULL) {
+ provkey =
+ evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0);
+ /* If export failed, legacy may be able to pick it up */
+ if (provkey == NULL)
+ goto legacy;
+ }
+ ctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov));
+ if (ctx->op.sig.sigprovctx == NULL) {
+ /* The provider key can stay in the cache */
+ EVPerr(0, EVP_R_INITIALIZATION_ERROR);
+ goto err;
+ }
+
+ switch (operation) {
+ case EVP_PKEY_OP_SIGN:
+ if (signature->sign_init == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ret = -2;
+ goto err;
+ }
+ ret = signature->sign_init(ctx->op.sig.sigprovctx, provkey);
+ break;
+ case EVP_PKEY_OP_VERIFY:
+ if (signature->verify_init == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ret = -2;
+ goto err;
+ }
+ ret = signature->verify_init(ctx->op.sig.sigprovctx, provkey);
+ break;
+ case EVP_PKEY_OP_VERIFYRECOVER:
+ if (signature->verify_recover_init == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ ret = -2;
+ goto err;
+ }
+ ret = signature->verify_recover_init(ctx->op.sig.sigprovctx, provkey);
+ break;
+ default:
+ EVPerr(0, EVP_R_INITIALIZATION_ERROR);
+ goto err;
+ }
+
+ if (ret <= 0) {
+ signature->freectx(ctx->op.sig.sigprovctx);
+ ctx->op.sig.sigprovctx = NULL;
+ goto err;
+ }
+ return 1;
+
+ legacy:
+ if (ctx->pmeth == NULL
+ || (operation == EVP_PKEY_OP_SIGN && ctx->pmeth->sign == NULL)
+ || (operation == EVP_PKEY_OP_VERIFY && ctx->pmeth->verify == NULL)
+ || (operation == EVP_PKEY_OP_VERIFYRECOVER
+ && ctx->pmeth->verify_recover == NULL)) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ switch (operation) {
+ case EVP_PKEY_OP_SIGN:
+ if (ctx->pmeth->sign_init == NULL)
+ return 1;
+ ret = ctx->pmeth->sign_init(ctx);
+ break;
+ case EVP_PKEY_OP_VERIFY:
+ if (ctx->pmeth->verify_init == NULL)
+ return 1;
+ ret = ctx->pmeth->verify_init(ctx);
+ break;
+ case EVP_PKEY_OP_VERIFYRECOVER:
+ if (ctx->pmeth->verify_recover_init == NULL)
+ return 1;
+ ret = ctx->pmeth->verify_recover_init(ctx);
+ break;
+ default:
+ EVPerr(0, EVP_R_INITIALIZATION_ERROR);
+ goto err;
+ }
+ if (ret <= 0)
+ goto err;
+ return ret;
+
+ err:
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+}
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
+{
+ return evp_pkey_signature_init(ctx, EVP_PKEY_OP_SIGN);
+}
+
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ int ret;
+
+ if (ctx == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ if (ctx->operation != EVP_PKEY_OP_SIGN) {
+ EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+
+ if (ctx->op.sig.sigprovctx == NULL)
+ goto legacy;
+
+ ret = ctx->op.sig.signature->sign(ctx->op.sig.sigprovctx, sig, siglen,
+ SIZE_MAX, tbs, tbslen);
+
+ return ret;
+ legacy:
+
+ if (ctx->pmeth == NULL || ctx->pmeth->sign == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
+ return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
+}
+
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
+{
+ return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFY);
+}
+
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ int ret;
+
+ if (ctx == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ if (ctx->operation != EVP_PKEY_OP_VERIFY) {
+ EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+
+ if (ctx->op.sig.sigprovctx == NULL)
+ goto legacy;
+
+ ret = ctx->op.sig.signature->verify(ctx->op.sig.sigprovctx, sig, siglen,
+ tbs, tbslen);
+
+ return ret;
+ legacy:
+ if (ctx->pmeth == NULL || ctx->pmeth->verify == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
+}
+
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
+{
+ return evp_pkey_signature_init(ctx, EVP_PKEY_OP_VERIFYRECOVER);
+}
+
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+ unsigned char *rout, size_t *routlen,
+ const unsigned char *sig, size_t siglen)
+{
+ int ret;
+
+ if (ctx == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
+ EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+
+ if (ctx->op.sig.sigprovctx == NULL)
+ goto legacy;
+
+ ret = ctx->op.sig.signature->verify_recover(ctx->op.sig.sigprovctx, rout,
+ routlen,
+ (rout == NULL ? 0 : *routlen),
+ sig, siglen);
+ return ret;
+ legacy:
+ if (ctx->pmeth == NULL || ctx->pmeth->verify_recover == NULL) {
+ EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
+ return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
+}
diff --git a/doc/man3/EVP_PKEY_CTX_new.pod b/doc/man3/EVP_PKEY_CTX_new.pod
index 90486ae0dc..b08f7e4d78 100644
--- a/doc/man3/EVP_PKEY_CTX_new.pod
+++ b/doc/man3/EVP_PKEY_CTX_new.pod
@@ -2,8 +2,8 @@
=head1 NAME
-EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_new_provided,
-EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free
+EVP_PKEY_CTX_new, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_new_from_name,
+EVP_PKEY_CTX_new_from_pkey, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free
- public key algorithm context functions
=head1 SYNOPSIS
@@ -12,9 +12,11 @@ EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
- EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(OPENSSL_CTX *libctx,
- const char *name,
- const char *propquery);
+ EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx,
+ const char *name,
+ const char *propquery);
+ EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx,
+ EVP_PKEY *pkey);
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
@@ -26,13 +28,19 @@ the I<pkey> key type and ENGINE I<e>.
The EVP_PKEY_CTX_new_id() function allocates public key algorithm context
using the key type specified by I<id> and ENGINE I<e>.
-The EVP_PKEY_CTX_new_provided() function allocates a public key algorithm
+The EVP_PKEY_CTX_new_from_name() function allocates a public key algorithm
context using the library context I<libctx> (see L<OPENSSL_CTX(3)>), the
key type specified by I<name> and the property query I<propquery>. None
of the arguments are duplicated, so they must remain unchanged for the
lifetime of the returned B<EVP_PKEY_CTX> or of any of its duplicates.
-EVP_PKEY_CTX_new_id() and EVP_PKEY_CTX_new_provided() are normally
+The EVP_PKEY_CTX_new_from_pkey() function allocates a public key algorithm
+context using the library context I<libctx> (see L<OPENSSL_CTX(3)>) and the
+algorithm specified by I<pkey> . None of the arguments are duplicated, so they
+must remain unchanged for the lifetime of the returned B<EVP_PKEY_CTX> or of
+any of its duplicates.
+
+EVP_PKEY_CTX_new_id() and EVP_PKEY_CTX_new_from_name() are normally
used when no B<EVP_PKEY> structure is associated with the operations,
for example during parameter generation or key generation for some
algorithms.
@@ -76,7 +84,11 @@ L<EVP_PKEY_new(3)>
=head1 HISTORY
-These functions were added in OpenSSL 1.0.0.
+The EVP_PKEY_CTX_new(), EVP_PKEY_CTX_new_id(), EVP_PKEY_CTX_dup() and
+EVP_PKEY_CTX_free() functions were added in OpenSSL 1.0.0.
+
+The EVP_PKEY_CTX_new_from_name() and EVP_PKEY_CTX_new_from_pkey() functions were
+added in OpenSSL 3.0.
=head1 COPYRIGHT
diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h
new file mode 100644
index 0000000000..efd4acf6fc
--- /dev/null
+++ b/include/crypto/dsa.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/dsa.h>
+
+DSA *dsa_new(OPENSSL_CTX *libctx);
+int dsa_sign_int(OPENSSL_CTX *libctx, int type, const unsigned char *dgst,
+ int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa);
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 973ef203ba..91f535093d 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -638,3 +638,4 @@ void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags);
const EVP_CIPHER *evp_get_cipherbyname_ex(OPENSSL_CTX *libctx, const char *name);
const EVP_MD *evp_get_digestbyname_ex(OPENSSL_CTX *libctx, const char *name);
+
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index e661053225..57a73382e8 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1466,9 +1466,11 @@ void EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt,
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
-EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(OPENSSL_CTX *libctx,
- const char *name,
- const char *propquery);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx,
+ const char *name,
+ const char *propquery);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx,
+ EVP_PKEY *pkey);
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 7afab78063..788963911b 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -121,6 +121,49 @@ static OSSL_PARAM core_params[] =
OSSL_PARAM_END
};
+/*
+ * This routine is currently necessary as bn params are currently processed
+ * using BN_native2bn when raw data is received. This means we need to do
+ * magic to reverse the order of the bytes to match native format.
+ * The array of hexdata is to get around compilers that dont like
+ * strings longer than 509 bytes,
+ */
+static int rawnative_fromhex(const char *hex_data[],
+ unsigned char **native, size_t *nativelen)
+{
+ int ret = 0;
+ unsigned char *data = NULL;
+ BIGNUM *bn = NULL;
+ int i, slen, datalen, sz;
+ char *str = NULL;
+
+ for (slen = 0, i = 0; hex_data[i] != NULL; ++i)
+ slen += strlen(hex_data[i]);
+ str = OPENSSL_zalloc(slen + 1);
+ if (str == NULL)
+ return 0;
+ for (i = 0; hex_data[i] != NULL; ++i)
+ strcat(str, hex_data[i]);
+
+ if (BN_hex2bn(&bn, str) <= 0)
+ return 0;
+
+ datalen = slen / 2;
+ data = (unsigned char *)str; /* reuse the str buffer */
+
+ sz = BN_bn2nativepad(bn, data, datalen);
+ if (sz <= 0)
+ goto err;
+ ret = 1;
+ *native = data;
+ *nativelen = datalen;
+ data = NULL; /* so it does not get freed */
+err:
+ BN_free(bn);
+ OPENSSL_free(data);
+ return ret;
+}
+
/* TODO(3.0): To be removed */
static int dummy_evp_call(void *provctx)
{
@@ -128,6 +171,58 @@ static int dummy_evp_call(void *provctx)
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_MD *sha256 = EVP_MD_fetch(libctx, "SHA256", NULL);
EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF2, NULL);
+ EVP_PKEY_CTX *sctx = NULL, *kctx = NULL;
+ EVP_PKEY *pkey = NULL;
+ OSSL_PARAM *p;
+ OSSL_PARAM params[16];
+ unsigned char sig[64];
+ size_t siglen, sigdgstlen;
+ unsigned char *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
+ unsigned char *dsa_pub = NULL, *dsa_priv = NULL;
+ size_t dsa_p_len, dsa_q_len, dsa_g_len, dsa_pub_len, dsa_priv_len;
+
+ /* dsa 2048 */
+ static const char *dsa_p_hex[] = {
+ "a29b8872ce8b8423b7d5d21d4b02f57e03e9e6b8a258dc16611ba098ab543415"
+ "e415f156997a3ee236658fa093260de3ad422e05e046f9ec29161a375f0eb4ef"
+ "fcef58285c5d39ed425d7a62ca12896c4a92cb1946f2952a48133f07da364d1b"
+ "df6b0f7139983e693c80059b0eacd1479ba9f2857754ede75f112b07ebbf3534",
+ "8bbf3e01e02f2d473de39453f99dd2367541caca3ba01166343d7b5b58a37bd1"
+ "b7521db2f13b86707132fe09f4cd09dc1618fa3401ebf9cc7b19fa94aa472088"
+ "133d6cb2d35c1179c8c8ff368758d507d9f9a17d46c110fe3144ce9b022b42e4"
+ "19eb4f5388613bfc3e26241a432e8706bc58ef76117278deab6cf692618291b7",
+ NULL
+ };
+ static const char *dsa_q_hex[] = {
+ "a3bfd9ab7884794e383450d5891dc18b65157bdcfcdac51518902867",
+ NULL
+ };
+ static const char *dsa_g_hex[] = {
+ "6819278869c7fd3d2d7b77f77e8150d9ad433bea3ba85efc80415aa3545f78f7"
+ "2296f06cb19ceda06c94b0551cfe6e6f863e31d1de6eed7dab8b0c9df231e084"
+ "34d1184f91d033696bb382f8455e9888f5d31d4784ec40120246f4bea61794bb"
+ "a5866f09746463bdf8e9e108cd9529c3d0f6df80316e2e70aaeb1b26cdb8ad97",
+ "bc3d287e0b8d616c42e65b87db20deb7005bc416747a6470147a68a7820388eb"
+ "f44d52e0628af9cf1b7166d03465f35acc31b6110c43dabc7c5d591e671eaf7c"
+ "252c1c145336a1a4ddf13244d55e835680cab2533b82df2efe55ec18c1e6cd00"
+ "7bb089758bb17c2cbe14441bd093ae66e5976d53733f4fa3269701d31d23d467",
+ NULL
+ };
+ static const char *dsa_pub_hex[] = {
+ "a012b3b170b307227957b7ca2061a816ac7a2b3d9ae995a5119c385b603bf6f6"
+ "c5de4dc5ecb5dfa4a41c68662eb25b638b7e2620ba898d07da6c4991e76cc0ec"
+ "d1ad3421077067e47c18f58a92a72ad43199ecb7bd84e7d3afb9019f0e9dd0fb"
+ "aa487300b13081e33c902876436f7b03c345528481d362815e24fe59dac5ac34",
+ "660d4c8a76cb99a7c7de93eb956cd6bc88e58d901034944a094b01803a43c672"
+ "b9688c0e01d8f4fc91c62a3f88021f7bd6a651b1a88f43aa4ef27653d12bf8b7"
+ "099fdf6b461082f8e939107bfd2f7210087d326c375200f1f51e7e74a3413190"
+ "1bcd0863521ff8d676c48581868736c5e51b16a4e39215ea0b17c4735974c516",
+ NULL
+ };
+ static const char *dsa_priv_hex[] = {
+ "6ccaeef6d73b4e80f11c17b8e9627c036635bac39423505e407e5cb7",
+ NULL
+ };
char msg[] = "Hello World!";
const unsigned char exptd[] = {
0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
@@ -186,7 +281,54 @@ static int dummy_evp_call(void *provctx)
if (!EC_KEY_generate_key(key))
goto err;
#endif
+ if (!rawnative_fromhex(dsa_p_hex, &dsa_p, &dsa_p_len)
+ || !rawnative_fromhex(dsa_q_hex, &dsa_q, &dsa_q_len)
+ || !rawnative_fromhex(dsa_g_hex, &dsa_g, &dsa_g_len)
+ || !rawnative_fromhex(dsa_pub_hex, &dsa_pub, &dsa_pub_len)
+ || !rawnative_fromhex(dsa_priv_hex, &dsa_priv, &dsa_priv_len))
+ goto err;
+
+ p = params;
+ *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_P, dsa_p, dsa_p_len);
+ *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_Q, dsa_q, dsa_q_len);
+ *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_G, dsa_g, dsa_g_len);
+ *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_DSA_PUB_KEY,
+ dsa_pub, dsa_pub_len);
+ *p++ = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_DSA_PRIV_KEY,
+ dsa_priv, dsa_priv_len);
+ *p = OSSL_PARAM_construct_end();
+
+ kctx = EVP_PKEY_CTX_new_from_name(libctx, SN_dsa, "");
+ if (kctx == NULL)
+ goto err;
+ if (EVP_PKEY_key_fromdata_init(kctx) <= 0
+ || EVP_PKEY_fromdata(kctx, &pkey, params) <= 0)
+ goto err;
+
+ sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey);
+ if (sctx == NULL)
+ goto err;;
+ if (EVP_PKEY_sign_init(sctx) <= 0)
+ goto err;
+
+ /* set signature parameters */
+ sigdgstlen = SHA256_DIGEST_LENGTH;
+ p = params;
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
+ SN_sha256,
+ strlen(SN_sha256) + 1);
+
+ *p++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
+ &sigdgstlen);
+ *p = OSSL_PARAM_construct_end();
+ if (EVP_PKEY_CTX_set_params(sctx, params) <= 0)
+ goto err;
+
+ if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0
+ || EVP_PKEY_verify_init(sctx) <= 0
+ || EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0)
+ goto err;
ret = 1;
err:
BN_CTX_end(bnctx);
@@ -199,6 +341,14 @@ static int dummy_evp_call(void *provctx)
#ifndef OPENSSL_NO_EC
EC_KEY_free(key);
#endif
+ OPENSSL_free(dsa_p);
+ OPENSSL_free(dsa_q);
+ OPENSSL_free(dsa_g);
+ OPENSSL_free(dsa_pub);
+ OPENSSL_free(dsa_priv);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(kctx);
+ EVP_PKEY_CTX_free(sctx);
return ret;
}
@@ -435,6 +585,19 @@ static const OSSL_ALGORITHM fips_kdfs[] = {
{ NULL, NULL, NULL }
};
+static const OSSL_ALGORITHM fips_signature[] = {
+#ifndef OPENSSL_NO_DSA
+ { "DSA:dsaEncryption", "fips=yes", dsa_signature_functions },
+#endif
+ { NULL, NULL, NULL }
+};
+
+static const OSSL_ALGORITHM fips_keymgmt[] = {
+#ifndef OPENSSL_NO_DSA
+ { "DSA", "fips=yes", dsa_keymgmt_functions },
+#endif
+ { NULL, NULL, NULL }
+};
static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
int operation_id,
@@ -451,6 +614,10 @@ static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
return fips_macs;
case OSSL_OP_KDF:
return fips_kdfs;
+ case OSSL_OP_KEYMGMT:
+ return fips_keymgmt;
+ case OSSL_OP_SIGNATURE:
+ return fips_signature;
}
return NULL;
}
@@ -574,19 +741,18 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
return 0;
}
- *out = fips_dispatch_table;
- *provctx = ctx;
-
/*
* TODO(3.0): Remove me. This is just a dummy call to demonstrate making
* EVP calls from within the FIPS module.
*/
- if (!dummy_evp_call(*provctx)) {
- OPENSSL_CTX_free(*provctx);
- *provctx = NULL;
+ if (!dummy_evp_call(ctx)) {
+ OPENSSL_CTX_free(ctx);
return 0;
}
+ *out = fips_dispatch_table;
+ *provctx = ctx;
+
return 1;
}
diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c
index ca4354af59..c3ab48b4eb 100644
--- a/providers/implementations/keymgmt/dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/dsa_kmgmt.c
@@ -10,11 +10,12 @@
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
#include <openssl/bn.h>
-#include <openssl/dsa.h>
#include <openssl/params.h>
#include "internal/param_build.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
+#include "prov/provider_ctx.h"
+#include "crypto/dsa.h"
static OSSL_OP_keymgmt_importdomparams_fn dsa_importdomparams;
static OSSL_OP_keymgmt_exportdomparams_fn dsa_exportdomparams;
@@ -134,8 +135,9 @@ static int key_to_params(DSA *dsa, OSSL_PARAM_BLD *tmpl)
static void *dsa_importdomparams(void *provctx, const OSSL_PARAM params[])
{
DSA *dsa;
+ OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
- if ((dsa = DSA_new()) == NULL
+ if ((dsa = dsa_new(libctx)) == NULL
|| !params_to_domparams(dsa, params)) {
DSA_free(dsa);
dsa = NULL;
@@ -164,8 +166,9 @@ static int dsa_exportdomparams(void *domparams,
static void *dsa_importkey(void *provctx, const OSSL_PARAM params[])
{
DSA *dsa;
+ OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
- if ((dsa = DSA_new()) == NULL
+ if ((dsa = dsa_new(libctx)) == NULL
|| !params_to_key(dsa, params)) {
DSA_free(dsa);
dsa = NULL;
diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c
index 1eef3c9165..c656a45fd7 100644
--- a/providers/implementations/signature/dsa.c
+++ b/providers/implementations/signature/dsa.c
@@ -15,6 +15,7 @@
#include <openssl/evp.h>
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
+#include "crypto/dsa.h"
static OSSL_OP_signature_newctx_fn dsa_newctx;
static OSSL_OP_signature_sign_init_fn dsa_signature_init;
@@ -95,8 +96,8 @@ static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen,
if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
return 0;
- ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa);
-
+ ret = dsa_sign_int(pdsactx->libctx, 0, tbs, tbslen, sig, &sltmp,
+ pdsactx->dsa);
if (ret <= 0)
return 0;
diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c
index c38f79ce79..029a8e425a 100644
--- a/test/evp_pkey_provided_test.c
+++ b/test/evp_pkey_provided_test.c
@@ -122,7 +122,7 @@ static int test_fromdata_rsa(void)
OSSL_PARAM_END
};
- if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_provided(NULL, "RSA", NULL)))
+ if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)))
goto err;
if (!TEST_true(EVP_PKEY_key_fromdata_init(ctx))
@@ -172,7 +172,7 @@ static int test_fromdata_dh(void)
OSSL_PARAM_END
};
- if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_provided(NULL, "DH", NULL)))
+ if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)))
goto err;
if (!TEST_true(EVP_PKEY_key_fromdata_init(ctx))
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 1fbd264047..e2729895d9 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4819,7 +4819,6 @@ EVP_DigestSignUpdate ? 3_0_0 EXIST::FUNCTION:
EVP_DigestVerifyInit_ex ? 3_0_0 EXIST::FUNCTION:
EVP_DigestVerifyUpdate ? 3_0_0 EXIST::FUNCTION:
BN_check_prime ? 3_0_0 EXIST::FUNCTION:
-EVP_PKEY_CTX_new_provided ? 3_0_0 EXIST::FUNCTION:
EVP_KEYMGMT_is_a ? 3_0_0 EXIST::FUNCTION:
EVP_KEYMGMT_do_all_provided ? 3_0_0 EXIST::FUNCTION:
EVP_KEYEXCH_is_a ? 3_0_0 EXIST::FUNCTION:
@@ -4912,3 +4911,5 @@ RSA_get0_pss_params ? 3_0_0 EXIST::FUNCTION:RSA
X509_cmp_timeframe ? 3_0_0 EXIST::FUNCTION:
OSSL_CMP_MSG_get0_header ? 3_0_0 EXIST::FUNCTION:CMP
BIO_f_prefix ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_CTX_new_from_name ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_CTX_new_from_pkey ? 3_0_0 EXIST::FUNCTION: