Latest update.
This commit is contained in:
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
#define xxxHASH EVP_sha1()
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#if OPENSSL_API_0_9_8
|
||||
#ifdef OPENSSL_NO_DEPRECATED_0_9_8
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
|
||||
+189
-197
@@ -15,155 +15,9 @@
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/dh.h>
|
||||
#include "crypto/dsa.h"
|
||||
|
||||
DSA *DSA_new(void)
|
||||
{
|
||||
return DSA_new_method(NULL);
|
||||
}
|
||||
|
||||
int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
|
||||
{
|
||||
/*
|
||||
* NB: The caller is specifically setting a method, so it's not up to us
|
||||
* to deal with which ENGINE it comes from.
|
||||
*/
|
||||
const DSA_METHOD *mtmp;
|
||||
mtmp = dsa->meth;
|
||||
if (mtmp->finish)
|
||||
mtmp->finish(dsa);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(dsa->engine);
|
||||
dsa->engine = NULL;
|
||||
#endif
|
||||
dsa->meth = meth;
|
||||
if (meth->init)
|
||||
meth->init(dsa);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const DSA_METHOD *DSA_get_method(DSA *d)
|
||||
{
|
||||
return d->meth;
|
||||
}
|
||||
|
||||
DSA *DSA_new_method(ENGINE *engine)
|
||||
{
|
||||
DSA *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->references = 1;
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->meth = DSA_get_default_method();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */
|
||||
if (engine) {
|
||||
if (!ENGINE_init(engine)) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
|
||||
goto err;
|
||||
}
|
||||
ret->engine = engine;
|
||||
} else
|
||||
ret->engine = ENGINE_get_default_DSA();
|
||||
if (ret->engine) {
|
||||
ret->meth = ENGINE_get_DSA(ret->engine);
|
||||
if (ret->meth == NULL) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
|
||||
|
||||
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
|
||||
goto err;
|
||||
|
||||
if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
DSA_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DSA_free(DSA *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (r == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&r->references, &i, r->lock);
|
||||
REF_PRINT_COUNT("DSA", r);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
if (r->meth != NULL && r->meth->finish != NULL)
|
||||
r->meth->finish(r);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(r->engine);
|
||||
#endif
|
||||
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
|
||||
|
||||
CRYPTO_THREAD_lock_free(r->lock);
|
||||
|
||||
BN_clear_free(r->p);
|
||||
BN_clear_free(r->q);
|
||||
BN_clear_free(r->g);
|
||||
BN_clear_free(r->pub_key);
|
||||
BN_clear_free(r->priv_key);
|
||||
OPENSSL_free(r);
|
||||
}
|
||||
|
||||
int DSA_up_ref(DSA *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
|
||||
return 0;
|
||||
|
||||
REF_PRINT_COUNT("DSA", r);
|
||||
REF_ASSERT_ISNT(i < 2);
|
||||
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;
|
||||
}
|
||||
#ifndef FIPS_MODE
|
||||
|
||||
int DSA_set_ex_data(DSA *d, int idx, void *arg)
|
||||
{
|
||||
@@ -175,13 +29,6 @@ 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)
|
||||
{
|
||||
@@ -240,6 +87,189 @@ DH *DSA_dup_DH(const DSA *r)
|
||||
}
|
||||
#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_set_method(DSA *dsa, const DSA_METHOD *meth)
|
||||
{
|
||||
/*
|
||||
* NB: The caller is specifically setting a method, so it's not up to us
|
||||
* to deal with which ENGINE it comes from.
|
||||
*/
|
||||
const DSA_METHOD *mtmp;
|
||||
mtmp = dsa->meth;
|
||||
if (mtmp->finish)
|
||||
mtmp->finish(dsa);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(dsa->engine);
|
||||
dsa->engine = NULL;
|
||||
#endif
|
||||
dsa->meth = meth;
|
||||
if (meth->init)
|
||||
meth->init(dsa);
|
||||
return 1;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
|
||||
const DSA_METHOD *DSA_get_method(DSA *d)
|
||||
{
|
||||
return d->meth;
|
||||
}
|
||||
|
||||
static DSA *dsa_new_method(OPENSSL_CTX *libctx, ENGINE *engine)
|
||||
{
|
||||
DSA *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->references = 1;
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->meth = DSA_get_default_method();
|
||||
#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)) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
|
||||
goto err;
|
||||
}
|
||||
ret->engine = engine;
|
||||
} else
|
||||
ret->engine = ENGINE_get_default_DSA();
|
||||
if (ret->engine) {
|
||||
ret->meth = ENGINE_get_DSA(ret->engine);
|
||||
if (ret->meth == NULL) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (!crypto_new_ex_data_ex(libctx, CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
|
||||
goto err;
|
||||
#endif
|
||||
|
||||
if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
|
||||
DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
DSA_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DSA *DSA_new_method(ENGINE *engine)
|
||||
{
|
||||
return dsa_new_method(NULL, engine);
|
||||
}
|
||||
|
||||
DSA *DSA_new(void)
|
||||
{
|
||||
return DSA_new_method(NULL);
|
||||
}
|
||||
|
||||
void DSA_free(DSA *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (r == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&r->references, &i, r->lock);
|
||||
REF_PRINT_COUNT("DSA", r);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
if (r->meth != NULL && r->meth->finish != NULL)
|
||||
r->meth->finish(r);
|
||||
#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
|
||||
ENGINE_finish(r->engine);
|
||||
#endif
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
|
||||
#endif
|
||||
|
||||
CRYPTO_THREAD_lock_free(r->lock);
|
||||
|
||||
BN_clear_free(r->p);
|
||||
BN_clear_free(r->q);
|
||||
BN_clear_free(r->g);
|
||||
BN_clear_free(r->pub_key);
|
||||
BN_clear_free(r->priv_key);
|
||||
OPENSSL_free(r);
|
||||
}
|
||||
|
||||
int DSA_up_ref(DSA *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
|
||||
return 0;
|
||||
|
||||
REF_PRINT_COUNT("DSA", r);
|
||||
REF_ASSERT_ISNT(i < 2);
|
||||
return ((i > 1) ? 1 : 0);
|
||||
}
|
||||
|
||||
void DSA_get0_pqg(const DSA *d,
|
||||
const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
|
||||
{
|
||||
@@ -309,49 +339,11 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_p(const DSA *d)
|
||||
int DSA_security_bits(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;
|
||||
if (d->p && d->q)
|
||||
return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DSA_bits(const DSA *dsa)
|
||||
|
||||
@@ -26,7 +26,9 @@ struct dsa_st {
|
||||
/* Normally used to cache montgomery values */
|
||||
BN_MONT_CTX *method_mont_p;
|
||||
CRYPTO_REF_COUNT references;
|
||||
#ifndef FIPS_MODE
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
#endif
|
||||
const DSA_METHOD *meth;
|
||||
/* functional reference if 'meth' is ENGINE-provided */
|
||||
ENGINE *engine;
|
||||
@@ -78,3 +80,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);
|
||||
+17
-8
@@ -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;
|
||||
|
||||
|
||||
+179
-2
@@ -7,18 +7,195 @@
|
||||
* 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)
|
||||
{
|
||||
return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
|
||||
}
|
||||
|
||||
#if !OPENSSL_API_3
|
||||
#ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user