return NULL;
ossl_param_bld_init(&tmpl);
- if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_P, p)
- || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_G, g)
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
+ || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g)
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, pub_key))
return NULL;
if (q != NULL) {
- if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_Q, q))
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
return NULL;
}
*/
#include <stdio.h>
-#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/asn1.h>
-#include "dsa_locl.h"
#include <openssl/bn.h>
#include <openssl/cms.h>
+#include <openssl/core_names.h>
+#include "internal/cryptlib.h"
#include "internal/asn1_int.h"
#include "internal/evp_int.h"
+#include "internal/param_build.h"
+#include "dsa_locl.h"
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
goto err;
}
+ dsa->dirty_cnt++;
ASN1_INTEGER_free(public_key);
EVP_PKEY_assign_DSA(pkey, dsa);
return 1;
goto dsaerr;
}
+ dsa->dirty_cnt++;
EVP_PKEY_assign_DSA(pkey, dsa);
ret = 1;
return 0;
BN_free(to->pkey.dsa->g);
to->pkey.dsa->g = a;
+ to->pkey.dsa->dirty_cnt++;
return 1;
}
DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
return 0;
}
+ dsa->dirty_cnt++;
EVP_PKEY_assign_DSA(pkey, dsa);
return 1;
}
DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
return 0;
}
+ dsa->dirty_cnt++;
EVP_PKEY_assign_DSA(pkey, dsa);
return 1;
}
}
+static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
+{
+ return pkey->pkey.dsa->dirty_cnt;
+}
+
+static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
+{
+ DSA *dsa = pk->pkey.dsa;
+ OSSL_PARAM_BLD tmpl;
+ const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa);
+ const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
+ const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
+ OSSL_PARAM *params;
+ void *provkey = NULL;
+
+ if (p == NULL || q == NULL || g == NULL)
+ return NULL;
+
+ ossl_param_bld_init(&tmpl);
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
+ || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
+ || !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
+ return NULL;
+
+ /*
+ * This may be used to pass domain parameters only without any key data -
+ * so "pub_key" is optional. We can never have a "priv_key" without a
+ * corresponding "pub_key" though.
+ */
+ if (pub_key != NULL) {
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY,
+ pub_key))
+ return NULL;
+
+ if (priv_key != NULL) {
+ if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY,
+ priv_key))
+ return NULL;
+ }
+ }
+
+ params = ossl_param_bld_to_param(&tmpl);
+
+ /* We export, the provider imports */
+ provkey = evp_keymgmt_importkey(keymgmt, params);
+
+ ossl_param_bld_free(params);
+ return provkey;
+}
+
/* NB these are sorted in pkey_id order, lowest first */
const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
int_dsa_free,
dsa_pkey_ctrl,
old_dsa_priv_decode,
- old_dsa_priv_encode}
+ old_dsa_priv_encode,
+
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+
+ dsa_pkey_dirty_cnt,
+ dsa_pkey_export_to
+ }
};
ret->p = BN_dup(p);
ret->q = BN_dup(q);
ret->g = BN_dup(g);
+ ret->dirty_cnt++;
if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
ok = 0;
goto err;
ok = -1;
goto err;
}
+ ret->dirty_cnt++;
if (counter_ret != NULL)
*counter_ret = counter;
if (h_ret != NULL)
dsa->priv_key = priv_key;
dsa->pub_key = pub_key;
+ dsa->dirty_cnt++;
ok = 1;
err:
BN_free(d->g);
d->g = g;
}
+ d->dirty_cnt++;
return 1;
}
BN_free(d->priv_key);
d->priv_key = priv_key;
}
+ d->dirty_cnt++;
return 1;
}
/* functional reference if 'meth' is ENGINE-provided */
ENGINE *engine;
CRYPTO_RWLOCK *lock;
+
+ /* Provider data */
+ size_t dirty_cnt; /* If any key material changes, increment this */
};
struct DSA_SIG_st {
*/
if (ctx->pkey != NULL) {
switch (ctx->pkey->type) {
+ case NID_dsa:
+ break;
default:
goto legacy;
}
}
#endif
+int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+{
+ OSSL_PARAM sig_md_params[3];
+ size_t mdsize;
+ const char *name;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->sigprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
+ EVP_PKEY_CTRL_MD, 0, (void *)(md));
+
+ if (md == NULL)
+ return 1;
+
+ mdsize = EVP_MD_size(md);
+ name = EVP_MD_name(md);
+ sig_md_params[0] = OSSL_PARAM_construct_utf8_string(
+ OSSL_SIGNATURE_PARAM_DIGEST,
+ /*
+ * Cast away the const. This is read only so should
+ * be safe
+ */
+ (char *)name,
+ strlen(name) + 1);
+ sig_md_params[1] = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
+ &mdsize);
+ sig_md_params[2] = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, sig_md_params);
+
+}
+
static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2)
{
#define OSSL_KDF_PARAM_SIZE "size" /* size_t */
/* PKEY parameters */
-/* Diffie-Hellman Parameters */
-#define OSSL_PKEY_PARAM_DH_P "dh-p"
-#define OSSL_PKEY_PARAM_DH_G "dh-g"
-#define OSSL_PKEY_PARAM_DH_Q "dh-q"
+/* Diffie-Hellman/DSA Parameters */
+#define OSSL_PKEY_PARAM_FFC_P "ffc-p"
+#define OSSL_PKEY_PARAM_FFC_G "ffc-g"
+#define OSSL_PKEY_PARAM_FFC_Q "ffc-q"
+
/* Diffie-Hellman Keys */
#define OSSL_PKEY_PARAM_DH_PUB_KEY "dh-pub"
#define OSSL_PKEY_PARAM_DH_PRIV_KEY "dh-priv"
+/* DSA Keys */
+#define OSSL_PKEY_PARAM_DSA_PUB_KEY "dsa-pub"
+#define OSSL_PKEY_PARAM_DSA_PRIV_KEY "dsa-priv"
+
/* Key Exchange parameters */
#define OSSL_EXCHANGE_PARAM_PAD "exchange-pad" /* uint */
+/* Signature parameters */
+#define OSSL_SIGNATURE_PARAM_DIGEST "digest"
+#define OSSL_SIGNATURE_PARAM_DIGEST_SIZE "digest-size"
+
# ifdef __cplusplus
}
# endif
# define OSSL_FUNC_SIGNATURE_SIGN 3
# define OSSL_FUNC_SIGNATURE_FREECTX 4
# define OSSL_FUNC_SIGNATURE_DUPCTX 5
+# define OSSL_FUNC_SIGNATURE_SET_PARAMS 6
OSSL_CORE_MAKE_FUNC(void *, OP_signature_newctx, (void *provctx))
OSSL_CORE_MAKE_FUNC(int, OP_signature_sign_init, (void *ctx, void *provkey))
size_t tbslen))
OSSL_CORE_MAKE_FUNC(void, OP_signature_freectx, (void *ctx))
OSSL_CORE_MAKE_FUNC(void *, OP_signature_dupctx, (void *ctx))
+OSSL_CORE_MAKE_FUNC(int, OP_signature_set_params, (void *ctx,
+ const OSSL_PARAM params[]))
# ifdef __cplusplus
}
int (*pkey_security_bits) (const EVP_PKEY
*pk));
+int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
+
# define EVP_PKEY_OP_UNDEFINED 0
# define EVP_PKEY_OP_PARAMGEN (1<<1)
# define EVP_PKEY_OP_KEYGEN (1<<2)
# define EVP_PKEY_OP_TYPE_GEN \
(EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
-# define EVP_PKEY_CTX_set_signature_md(ctx, md) \
- EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \
- EVP_PKEY_CTRL_MD, 0, (void *)(md))
-
# define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \
EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \
EVP_PKEY_CTRL_GET_MD, 0, (void *)(pmd))
-SUBDIRS=digests ciphers macs kdfs exchange keymgmt
+SUBDIRS=digests ciphers macs kdfs exchange keymgmt signature
$COMMON=provider_util.c
SOURCE[../../libcrypto]=$COMMON provider_err.c provlib.c
/* Key management */
extern const OSSL_DISPATCH dh_keymgmt_functions[];
+extern const OSSL_DISPATCH dsa_keymgmt_functions[];
/* Key Exchange */
extern const OSSL_DISPATCH dh_keyexch_functions[];
+
+/* Signature */
+extern const OSSL_DISPATCH dsa_signature_functions[];
LIBS=../../../libcrypto
IF[{- !$disabled{dh} -}]
SOURCE[../../../libcrypto]=\
- dh_kmgmt.c
+ dh_kmgmt.c dsa_kmgmt.c
ENDIF
if (dh == NULL)
return 0;
- param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_P);
- param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_G);
+ param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
+ param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
param_priv_key =
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_KEY);
param_pub_key =
--- /dev/null
+/*
+ * 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/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/params.h>
+#include "internal/provider_algs.h"
+
+static OSSL_OP_keymgmt_importkey_fn dsa_importkey;
+
+static int params_to_key(DSA *dsa, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *param_p, *param_q, *param_g, *param_priv_key;
+ const OSSL_PARAM *param_pub_key;
+ BIGNUM *p = NULL, *q = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL;
+
+ if (dsa == NULL)
+ return 0;
+
+ param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
+ param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q);
+ param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
+ param_priv_key =
+ OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PRIV_KEY);
+ param_pub_key =
+ OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DSA_PUB_KEY);
+
+ /*
+ * DSA documentation says that a public key must be present if a private key
+ * is.
+ */
+ if (param_priv_key != NULL && param_pub_key == NULL)
+ return 0;
+
+ if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
+ || (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q))
+ || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))
+ || (param_priv_key != NULL
+ && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
+ || (param_pub_key != NULL
+ && !OSSL_PARAM_get_BN(param_pub_key, &pub_key)))
+ goto err;
+
+ if (!DSA_set0_pqg(dsa, p, q, g))
+ goto err;
+ p = q = g = NULL;
+
+ if (pub_key != NULL && !DSA_set0_key(dsa, pub_key, priv_key))
+ goto err;
+ priv_key = pub_key = NULL;
+
+ return 1;
+
+ err:
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ BN_free(priv_key);
+ BN_free(pub_key);
+ return 0;
+}
+
+static void *dsa_importkey(void *provctx, const OSSL_PARAM params[])
+{
+ DSA *dsa;
+
+ if ((dsa = DSA_new()) == NULL
+ || !params_to_key(dsa, params)) {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+ return dsa;
+}
+
+const OSSL_DISPATCH dsa_keymgmt_functions[] = {
+ /*
+ * TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also
+ * implement OSSL_FUNC_KEYMGMT_EXPORTKEY.
+ */
+ { OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dsa_importkey },
+ { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DSA_free },
+ { 0, NULL }
+};
--- /dev/null
+LIBS=../../../libcrypto
+IF[{- !$disabled{dsa} -}]
+ SOURCE[../../../libcrypto]=\
+ dsa.c
+ENDIF
+
+
--- /dev/null
+/*
+ * 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/crypto.h>
+#include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
+#include <openssl/dsa.h>
+#include <openssl/params.h>
+#include "internal/provider_algs.h"
+
+static OSSL_OP_signature_newctx_fn dsa_newctx;
+static OSSL_OP_signature_sign_init_fn dsa_sign_init;
+static OSSL_OP_signature_sign_fn dsa_sign;
+static OSSL_OP_signature_freectx_fn dsa_freectx;
+static OSSL_OP_signature_dupctx_fn dsa_dupctx;
+static OSSL_OP_signature_set_params_fn dsa_set_params;
+
+/*
+ * What's passed as an actual key is defined by the KEYMGMT interface.
+ * We happen to know that our KEYMGMT simply passes DSA structures, so
+ * we use that here too.
+ */
+
+typedef struct {
+ DSA *dsa;
+ size_t mdsize;
+} PROV_DSA_CTX;
+
+static void *dsa_newctx(void *provctx)
+{
+ return OPENSSL_zalloc(sizeof(PROV_DSA_CTX));
+}
+
+static int dsa_sign_init(void *vpdsactx, void *vdsa)
+{
+ PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+ if (pdsactx == NULL || vdsa == NULL || !DSA_up_ref(vdsa))
+ return 0;
+ DSA_free(pdsactx->dsa);
+ pdsactx->dsa = vdsa;
+ return 1;
+}
+
+static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen,
+ size_t sigsize, const unsigned char *tbs, size_t tbslen)
+{
+ PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+ int ret;
+ unsigned int sltmp;
+ size_t dsasize = DSA_size(pdsactx->dsa);
+
+ if (sig == NULL) {
+ *siglen = dsasize;
+ return 1;
+ }
+
+ if (sigsize < (size_t)dsasize)
+ return 0;
+
+ if (pdsactx->mdsize != 0 && tbslen != pdsactx->mdsize)
+ return 0;
+
+ ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, pdsactx-> dsa);
+
+ if (ret <= 0)
+ return 0;
+
+ *siglen = sltmp;
+ return 1;
+}
+
+static void dsa_freectx(void *vpdsactx)
+{
+ PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+
+ DSA_free(pdsactx->dsa);
+
+ OPENSSL_free(pdsactx);
+}
+
+static void *dsa_dupctx(void *vpdsactx)
+{
+ PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx;
+ PROV_DSA_CTX *dstctx;
+
+ dstctx = OPENSSL_zalloc(sizeof(*srcctx));
+ if (dstctx == NULL)
+ return NULL;
+
+ *dstctx = *srcctx;
+ if (dstctx->dsa != NULL && !DSA_up_ref(dstctx->dsa)) {
+ OPENSSL_free(dstctx);
+ return NULL;
+ }
+
+ return dstctx;
+}
+
+static int dsa_set_params(void *vpdsactx, const OSSL_PARAM params[])
+{
+ PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
+ const OSSL_PARAM *p;
+ size_t mdsize;
+
+ if (pdsactx == NULL || params == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
+ if (p == NULL || !OSSL_PARAM_get_size_t(p, &mdsize))
+ return 0;
+
+ pdsactx->mdsize = mdsize;
+
+ return 1;
+}
+
+const OSSL_DISPATCH dsa_signature_functions[] = {
+ { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx },
+ { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_sign_init },
+ { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign },
+ { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))dsa_freectx },
+ { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))dsa_dupctx },
+ { OSSL_FUNC_SIGNATURE_SET_PARAMS, (void (*)(void))dsa_set_params },
+ { 0, NULL }
+};
{ NULL, NULL, NULL }
};
+static const OSSL_ALGORITHM deflt_signature[] = {
+#ifndef OPENSSL_NO_DSA
+ { "DSA", "default=yes", dsa_signature_functions },
+#endif
+ { NULL, NULL, NULL }
+};
+
+
static const OSSL_ALGORITHM deflt_keymgmt[] = {
#ifndef OPENSSL_NO_DH
{ "dhKeyAgreement", "default=yes", dh_keymgmt_functions },
+#endif
+#ifndef OPENSSL_NO_DSA
+ { "DSA", "default=yes", dsa_keymgmt_functions },
#endif
{ NULL, NULL, NULL }
};
return deflt_keymgmt;
case OSSL_OP_KEYEXCH:
return deflt_keyexch;
+ case OSSL_OP_SIGNATURE:
+ return deflt_signature;
}
return NULL;
}
EVP_SIGNATURE_provider 4862 3_0_0 EXIST::FUNCTION:
EVP_SIGNATURE_fetch 4863 3_0_0 EXIST::FUNCTION:
EVP_PKEY_sign_init_ex 4864 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_CTX_set_signature_md 4865 3_0_0 EXIST::FUNCTION: