summaryrefslogtreecommitdiff
path: root/main/openssl/crypto/dsa
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2014-04-23 09:56:37 +0200
committerArne Schwabe <arne@rfc2549.org>2014-04-23 09:56:37 +0200
commite436c963f0976b885a7db04681344779e26dd3b5 (patch)
tree240663106f32e02e1c34080656f4ef21a2e1776e /main/openssl/crypto/dsa
parent6a99715a9b072fa249e79c98cd9f03991f0f1219 (diff)
Update OpenSSL to 1.0.1g and statically link OpenVPN with it
Diffstat (limited to 'main/openssl/crypto/dsa')
-rw-r--r--main/openssl/crypto/dsa/dsa.h30
-rw-r--r--main/openssl/crypto/dsa/dsa_ameth.c47
-rw-r--r--main/openssl/crypto/dsa/dsa_asn1.c40
-rw-r--r--main/openssl/crypto/dsa/dsa_err.c8
-rw-r--r--main/openssl/crypto/dsa/dsa_gen.c35
-rw-r--r--main/openssl/crypto/dsa/dsa_key.c16
-rw-r--r--main/openssl/crypto/dsa/dsa_lib.c22
-rw-r--r--main/openssl/crypto/dsa/dsa_locl.h1
-rw-r--r--main/openssl/crypto/dsa/dsa_ossl.c44
-rw-r--r--main/openssl/crypto/dsa/dsa_pmeth.c6
-rw-r--r--main/openssl/crypto/dsa/dsa_sign.c57
-rw-r--r--main/openssl/crypto/dsa/dsa_vrf.c29
12 files changed, 283 insertions, 52 deletions
diff --git a/main/openssl/crypto/dsa/dsa.h b/main/openssl/crypto/dsa/dsa.h
index ac50a5c8..7531c653 100644
--- a/main/openssl/crypto/dsa/dsa.h
+++ b/main/openssl/crypto/dsa/dsa.h
@@ -96,6 +96,25 @@
* faster variable sliding window method to
* be used for all exponents.
*/
+#define DSA_FLAG_NONCE_FROM_HASH 0x04 /* Causes the DSA nonce to be calculated
+ from SHA512(private_key + H(message) +
+ random). This strengthens DSA against a
+ weak PRNG. */
+
+/* If this flag is set the DSA method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its reposibility
+ * to ensure the result is compliant.
+ */
+
+#define DSA_FLAG_FIPS_METHOD 0x0400
+
+/* If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+#define DSA_FLAG_NON_FIPS_ALLOW 0x0400
#ifdef __cplusplus
extern "C" {
@@ -115,8 +134,9 @@ struct dsa_method
{
const char *name;
DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa);
- int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
- BIGNUM **rp);
+ int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in,
+ BIGNUM **kinvp, BIGNUM **rp,
+ const unsigned char *dgst, int dlen);
int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
DSA_SIG *sig, DSA *dsa);
int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
@@ -272,6 +292,8 @@ void ERR_load_DSA_strings(void);
#define DSA_F_DSAPARAMS_PRINT_FP 101
#define DSA_F_DSA_DO_SIGN 112
#define DSA_F_DSA_DO_VERIFY 113
+#define DSA_F_DSA_GENERATE_KEY 124
+#define DSA_F_DSA_GENERATE_PARAMETERS_EX 123
#define DSA_F_DSA_NEW_METHOD 103
#define DSA_F_DSA_PARAM_DECODE 119
#define DSA_F_DSA_PRINT_FP 105
@@ -282,6 +304,7 @@ void ERR_load_DSA_strings(void);
#define DSA_F_DSA_SIGN 106
#define DSA_F_DSA_SIGN_SETUP 107
#define DSA_F_DSA_SIG_NEW 109
+#define DSA_F_DSA_SIG_PRINT 125
#define DSA_F_DSA_VERIFY 108
#define DSA_F_I2D_DSA_SIG 111
#define DSA_F_OLD_DSA_PRIV_DECODE 122
@@ -298,6 +321,9 @@ void ERR_load_DSA_strings(void);
#define DSA_R_INVALID_DIGEST_TYPE 106
#define DSA_R_MISSING_PARAMETERS 101
#define DSA_R_MODULUS_TOO_LARGE 103
+#define DSA_R_NEED_NEW_SETUP_VALUES 110
+#define DSA_R_NONCE_CANNOT_BE_PRECOMPUTED 112
+#define DSA_R_NON_FIPS_DSA_METHOD 111
#define DSA_R_NO_PARAMETERS_SET 107
#define DSA_R_PARAMETER_ENCODING_ERROR 105
diff --git a/main/openssl/crypto/dsa/dsa_ameth.c b/main/openssl/crypto/dsa/dsa_ameth.c
index 6413aae4..376156ec 100644
--- a/main/openssl/crypto/dsa/dsa_ameth.c
+++ b/main/openssl/crypto/dsa/dsa_ameth.c
@@ -542,6 +542,52 @@ static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
}
+static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
+ const ASN1_STRING *sig,
+ int indent, ASN1_PCTX *pctx)
+ {
+ DSA_SIG *dsa_sig;
+ const unsigned char *p;
+ if (!sig)
+ {
+ if (BIO_puts(bp, "\n") <= 0)
+ return 0;
+ else
+ return 1;
+ }
+ p = sig->data;
+ dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
+ if (dsa_sig)
+ {
+ int rv = 0;
+ size_t buf_len = 0;
+ unsigned char *m=NULL;
+ update_buflen(dsa_sig->r, &buf_len);
+ update_buflen(dsa_sig->s, &buf_len);
+ m = OPENSSL_malloc(buf_len+10);
+ if (m == NULL)
+ {
+ DSAerr(DSA_F_DSA_SIG_PRINT,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (BIO_write(bp, "\n", 1) != 1)
+ goto err;
+
+ if (!ASN1_bn_print(bp,"r: ",dsa_sig->r,m,indent))
+ goto err;
+ if (!ASN1_bn_print(bp,"s: ",dsa_sig->s,m,indent))
+ goto err;
+ rv = 1;
+ err:
+ if (m)
+ OPENSSL_free(m);
+ DSA_SIG_free(dsa_sig);
+ return rv;
+ }
+ return X509_signature_dump(bp, sig, indent);
+ }
+
static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
{
switch (op)
@@ -647,6 +693,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
dsa_copy_parameters,
dsa_cmp_parameters,
dsa_param_print,
+ dsa_sig_print,
int_dsa_free,
dsa_pkey_ctrl,
diff --git a/main/openssl/crypto/dsa/dsa_asn1.c b/main/openssl/crypto/dsa/dsa_asn1.c
index c37460b2..60585343 100644
--- a/main/openssl/crypto/dsa/dsa_asn1.c
+++ b/main/openssl/crypto/dsa/dsa_asn1.c
@@ -61,6 +61,7 @@
#include <openssl/dsa.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include <openssl/rand.h>
/* Override the default new methods */
static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
@@ -87,7 +88,7 @@ ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = {
ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG)
-IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG)
/* Override the default free and new methods */
static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
@@ -148,3 +149,40 @@ DSA *DSAparams_dup(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;
+ RAND_seed(dgst, dlen);
+ 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;
+ int ret=-1;
+
+ s = DSA_SIG_new();
+ if (s == NULL) return(ret);
+ if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+ ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+err:
+ DSA_SIG_free(s);
+ return(ret);
+ }
diff --git a/main/openssl/crypto/dsa/dsa_err.c b/main/openssl/crypto/dsa/dsa_err.c
index bba984e9..e6171cce 100644
--- a/main/openssl/crypto/dsa/dsa_err.c
+++ b/main/openssl/crypto/dsa/dsa_err.c
@@ -1,6 +1,6 @@
/* crypto/dsa/dsa_err.c */
/* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -76,6 +76,8 @@ static ERR_STRING_DATA DSA_str_functs[]=
{ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"},
{ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"},
{ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"},
+{ERR_FUNC(DSA_F_DSA_GENERATE_KEY), "DSA_generate_key"},
+{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX), "DSA_generate_parameters_ex"},
{ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"},
{ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "DSA_PARAM_DECODE"},
{ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
@@ -86,6 +88,7 @@ static ERR_STRING_DATA DSA_str_functs[]=
{ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"},
{ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
{ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"},
+{ERR_FUNC(DSA_F_DSA_SIG_PRINT), "DSA_SIG_PRINT"},
{ERR_FUNC(DSA_F_DSA_VERIFY), "DSA_verify"},
{ERR_FUNC(DSA_F_I2D_DSA_SIG), "i2d_DSA_SIG"},
{ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "OLD_DSA_PRIV_DECODE"},
@@ -105,6 +108,9 @@ static ERR_STRING_DATA DSA_str_reasons[]=
{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
{ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"},
{ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
+{ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"},
+{ERR_REASON(DSA_R_NONCE_CANNOT_BE_PRECOMPUTED),"nonce cannot be precomputed"},
+{ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD) ,"non fips dsa method"},
{ERR_REASON(DSA_R_NO_PARAMETERS_SET) ,"no parameters set"},
{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
{0,NULL}
diff --git a/main/openssl/crypto/dsa/dsa_gen.c b/main/openssl/crypto/dsa/dsa_gen.c
index cb0b4538..c398761d 100644
--- a/main/openssl/crypto/dsa/dsa_gen.c
+++ b/main/openssl/crypto/dsa/dsa_gen.c
@@ -81,13 +81,33 @@
#include <openssl/sha.h>
#include "dsa_locl.h"
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
int DSA_generate_parameters_ex(DSA *ret, int bits,
const unsigned char *seed_in, int seed_len,
int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+ DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD);
+ return 0;
+ }
+#endif
if(ret->meth->dsa_paramgen)
return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
counter_ret, h_ret, cb);
+#ifdef OPENSSL_FIPS
+ else if (FIPS_mode())
+ {
+ return FIPS_dsa_generate_parameters_ex(ret, bits,
+ seed_in, seed_len,
+ counter_ret, h_ret, cb);
+ }
+#endif
else
{
const EVP_MD *evpmd;
@@ -105,12 +125,13 @@ int DSA_generate_parameters_ex(DSA *ret, int bits,
}
return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
- seed_in, seed_len, counter_ret, h_ret, cb);
+ seed_in, seed_len, NULL, counter_ret, h_ret, cb);
}
}
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+ unsigned char *seed_out,
int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
{
int ok=0;
@@ -201,8 +222,10 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
}
/* step 2 */
- EVP_Digest(seed, qsize, md, NULL, evpmd, NULL);
- EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL);
+ if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
+ goto err;
+ if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
+ goto err;
for (i = 0; i < qsize; i++)
md[i]^=buf2[i];
@@ -251,7 +274,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
break;
}
- EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL);
+ if (!EVP_Digest(buf, qsize, md ,NULL, evpmd,
+ NULL))
+ goto err;
/* step 8 */
if (!BN_bin2bn(md, qsize, r0))
@@ -332,6 +357,8 @@ err:
}
if (counter_ret != NULL) *counter_ret=counter;
if (h_ret != NULL) *h_ret=h;
+ if (seed_out)
+ memcpy(seed_out, seed, qsize);
}
if(ctx)
{
diff --git a/main/openssl/crypto/dsa/dsa_key.c b/main/openssl/crypto/dsa/dsa_key.c
index c4aa86bc..9cf669b9 100644
--- a/main/openssl/crypto/dsa/dsa_key.c
+++ b/main/openssl/crypto/dsa/dsa_key.c
@@ -64,12 +64,28 @@
#include <openssl/dsa.h>
#include <openssl/rand.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
static int dsa_builtin_keygen(DSA *dsa);
int DSA_generate_key(DSA *dsa)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+ DSAerr(DSA_F_DSA_GENERATE_KEY, DSA_R_NON_FIPS_DSA_METHOD);
+ return 0;
+ }
+#endif
if(dsa->meth->dsa_keygen)
return dsa->meth->dsa_keygen(dsa);
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_dsa_generate_key(dsa);
+#endif
return dsa_builtin_keygen(dsa);
}
diff --git a/main/openssl/crypto/dsa/dsa_lib.c b/main/openssl/crypto/dsa/dsa_lib.c
index e9b75902..96d8d0c4 100644
--- a/main/openssl/crypto/dsa/dsa_lib.c
+++ b/main/openssl/crypto/dsa/dsa_lib.c
@@ -70,6 +70,10 @@
#include <openssl/dh.h>
#endif
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT;
static const DSA_METHOD *default_DSA_method = NULL;
@@ -82,7 +86,16 @@ void DSA_set_default_method(const DSA_METHOD *meth)
const DSA_METHOD *DSA_get_default_method(void)
{
if(!default_DSA_method)
+ {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_dsa_openssl();
+ else
+ return DSA_OpenSSL();
+#else
default_DSA_method = DSA_OpenSSL();
+#endif
+ }
return default_DSA_method;
}
@@ -163,7 +176,7 @@ DSA *DSA_new_method(ENGINE *engine)
ret->method_mont_p=NULL;
ret->references=1;
- ret->flags=ret->meth->flags;
+ ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
if ((ret->meth->init != NULL) && !ret->meth->init(ret))
{
@@ -276,7 +289,8 @@ void *DSA_get_ex_data(DSA *d, int idx)
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.
+ * DH has p, optional length, g, optional pub_key, optional priv_key,
+ * optional q.
*/
DH *ret = NULL;
@@ -290,7 +304,11 @@ DH *DSA_dup_DH(const DSA *r)
if ((ret->p = BN_dup(r->p)) == NULL)
goto err;
if (r->q != NULL)
+ {
ret->length = BN_num_bits(r->q);
+ if ((ret->q = BN_dup(r->q)) == NULL)
+ goto err;
+ }
if (r->g != NULL)
if ((ret->g = BN_dup(r->g)) == NULL)
goto err;
diff --git a/main/openssl/crypto/dsa/dsa_locl.h b/main/openssl/crypto/dsa/dsa_locl.h
index 2b8cfee3..21e2e452 100644
--- a/main/openssl/crypto/dsa/dsa_locl.h
+++ b/main/openssl/crypto/dsa/dsa_locl.h
@@ -56,4 +56,5 @@
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+ unsigned char *seed_out,
int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
diff --git a/main/openssl/crypto/dsa/dsa_ossl.c b/main/openssl/crypto/dsa/dsa_ossl.c
index a3ddd7d2..177fc545 100644
--- a/main/openssl/crypto/dsa/dsa_ossl.c
+++ b/main/openssl/crypto/dsa/dsa_ossl.c
@@ -67,7 +67,9 @@
#include <openssl/asn1.h>
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
-static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
+ BIGNUM **kinvp, BIGNUM **rp,
+ const unsigned char *dgst, int dlen);
static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
DSA *dsa);
static int dsa_init(DSA *dsa);
@@ -136,6 +138,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
BN_CTX *ctx=NULL;
int reason=ERR_R_BN_LIB;
DSA_SIG *ret=NULL;
+ int noredo = 0;
BN_init(&m);
BN_init(&xr);
@@ -150,10 +153,11 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
if (s == NULL) goto err;
ctx=BN_CTX_new();
if (ctx == NULL) goto err;
-
+redo:
if ((dsa->kinv == NULL) || (dsa->r == NULL))
{
- if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
+ if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r,dgst,dlen))
+ goto err;
}
else
{
@@ -161,6 +165,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
dsa->kinv=NULL;
r=dsa->r;
dsa->r=NULL;
+ noredo = 1;
}
@@ -181,6 +186,18 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
ret=DSA_SIG_new();
if (ret == NULL) goto err;
+ /* Redo if r or s is zero as required by FIPS 186-3: this is
+ * very unlikely.
+ */
+ if (BN_is_zero(r) || BN_is_zero(s))
+ {
+ if (noredo)
+ {
+ reason = DSA_R_NEED_NEW_SETUP_VALUES;
+ goto err;
+ }
+ goto redo;
+ }
ret->r = r;
ret->s = s;
@@ -199,7 +216,9 @@ err:
return(ret);
}
-static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
+ BIGNUM **kinvp, BIGNUM **rp,
+ const unsigned char *dgst, int dlen)
{
BN_CTX *ctx;
BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
@@ -225,8 +244,21 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
/* Get random k */
do
- if (!BN_rand_range(&k, dsa->q)) goto err;
- while (BN_is_zero(&k));
+ {
+#ifndef OPENSSL_NO_SHA512
+ if (dsa->flags & DSA_FLAG_NONCE_FROM_HASH)
+ {
+ /* If DSA_FLAG_NONCE_FROM_HASH is set then we calculate k from
+ * SHA512(private_key + H(message) + random). This protects the
+ * private key from a weak PRNG. */
+ if (!BN_generate_dsa_nonce(&k, dsa->q, dsa->priv_key, dgst,
+ dlen, ctx))
+ goto err;
+ }
+ else
+#endif
+ if (!BN_rand_range(&k, dsa->q)) goto err;
+ } while (BN_is_zero(&k));
if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
{
BN_set_flags(&k, BN_FLG_CONSTTIME);
diff --git a/main/openssl/crypto/dsa/dsa_pmeth.c b/main/openssl/crypto/dsa/dsa_pmeth.c
index e2df54fe..715d8d67 100644
--- a/main/openssl/crypto/dsa/dsa_pmeth.c
+++ b/main/openssl/crypto/dsa/dsa_pmeth.c
@@ -189,7 +189,9 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
EVP_MD_type((const EVP_MD *)p2) != NID_dsa &&
EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha256)
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
{
DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
return 0;
@@ -253,7 +255,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
if (!dsa)
return 0;
ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
- NULL, 0, NULL, NULL, pcb);
+ NULL, 0, NULL, NULL, NULL, pcb);
if (ret)
EVP_PKEY_assign_DSA(pkey, dsa);
else
diff --git a/main/openssl/crypto/dsa/dsa_sign.c b/main/openssl/crypto/dsa/dsa_sign.c
index 17555e58..8ace300a 100644
--- a/main/openssl/crypto/dsa/dsa_sign.c
+++ b/main/openssl/crypto/dsa/dsa_sign.c
@@ -61,30 +61,61 @@
#include "cryptlib.h"
#include <openssl/dsa.h>
#include <openssl/rand.h>
+#include <openssl/bn.h>
DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD);
+ return NULL;
+ }
+#endif
return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
}
-int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
- unsigned int *siglen, DSA *dsa)
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
- DSA_SIG *s;
- RAND_seed(dgst, dlen);
- s=DSA_do_sign(dgst,dlen,dsa);
- if (s == NULL)
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
{
- *siglen=0;
- return(0);
+ DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD);
+ return 0;
}
- *siglen=i2d_DSA_SIG(s,&sig);
- DSA_SIG_free(s);
- return(1);
+#endif
+ if (dsa->flags & DSA_FLAG_NONCE_FROM_HASH)
+ {
+ /* You cannot precompute the DSA nonce if it is required to
+ * depend on the message. */
+ DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NONCE_CANNOT_BE_PRECOMPUTED);
+ return 0;
+ }
+ return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0);
}
-int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+DSA_SIG *DSA_SIG_new(void)
{
- return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
+ DSA_SIG *sig;
+ sig = OPENSSL_malloc(sizeof(DSA_SIG));
+ if (!sig)
+ return NULL;
+ sig->r = NULL;
+ sig->s = NULL;
+ return sig;
+ }
+
+void DSA_SIG_free(DSA_SIG *sig)
+ {
+ if (sig)
+ {
+ if (sig->r)
+ BN_free(sig->r);
+ if (sig->s)
+ BN_free(sig->s);
+ OPENSSL_free(sig);
+ }
}
diff --git a/main/openssl/crypto/dsa/dsa_vrf.c b/main/openssl/crypto/dsa/dsa_vrf.c
index 226a75ff..674cb5fa 100644
--- a/main/openssl/crypto/dsa/dsa_vrf.c
+++ b/main/openssl/crypto/dsa/dsa_vrf.c
@@ -64,26 +64,13 @@
int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
DSA *dsa)
{
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+ && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD);
+ return -1;
+ }
+#endif
return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, 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;
- int ret=-1;
-
- s = DSA_SIG_new();
- if (s == NULL) return(ret);
- if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
- ret=DSA_do_verify(dgst,dgst_len,s,dsa);
-err:
- DSA_SIG_free(s);
- return(ret);
- }