Top level ECDSA sign/verify redirection.

Reviewed-by: Richard Levitte <levitte@openssl.org>
This commit is contained in:
Dr. Stephen Henson 2015-10-28 16:57:51 +00:00
parent 7d711cbc33
commit a200a817ad
5 changed files with 73 additions and 32 deletions

View file

@ -66,8 +66,10 @@ static const EC_KEY_METHOD openssl_ec_key_method = {
0,0,0,0,0,0,
ossl_ec_key_gen,
ossl_ecdh_compute_key,
ossl_ecdsa_sign,
ossl_ecdsa_sign_setup,
ossl_ecdsa_sign_sig,
ossl_ecdsa_verify,
ossl_ecdsa_verify_sig
};

View file

@ -572,11 +572,17 @@ struct ec_key_method_st {
void *(*KDF) (const void *in, size_t inlen,
void *out, size_t *outlen));
int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char
*sig, unsigned int *siglen, const BIGNUM *kinv,
const BIGNUM *r, EC_KEY *eckey);
int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp);
ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len,
const BIGNUM *in_kinv, const BIGNUM *in_r,
EC_KEY *eckey);
int (*verify)(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
int (*verify_sig)(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey);
} /* EC_KEY_METHOD */ ;
@ -596,8 +602,13 @@ struct ECDSA_SIG_st {
int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp);
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
unsigned char *sig, unsigned int *siglen,
const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey);
ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
const BIGNUM *in_kinv, const BIGNUM *in_r,
EC_KEY *eckey);
int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey);

View file

@ -56,6 +56,7 @@
*
*/
#include <string.h>
#include <openssl/err.h>
#include <openssl/obj_mac.h>
#include <openssl/bn.h>
@ -63,6 +64,22 @@
#include <openssl/ec.h>
#include "ec_lcl.h"
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
unsigned char *sig, unsigned int *siglen,
const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
{
ECDSA_SIG *s;
RAND_seed(dgst, dlen);
s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
if (s == NULL) {
*siglen = 0;
return 0;
}
*siglen = i2d_ECDSA_SIG(s, &sig);
ECDSA_SIG_free(s);
return 1;
}
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
BIGNUM **kinvp, BIGNUM **rp,
const unsigned char *dgst, int dlen)
@ -326,6 +343,37 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
return ret;
}
/*-
* returns
* 1: correct signature
* 0: incorrect signature
* -1: error
*/
int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
{
ECDSA_SIG *s;
const unsigned char *p = sigbuf;
unsigned char *der = NULL;
int derlen = -1;
int ret = -1;
s = ECDSA_SIG_new();
if (s == NULL)
return (ret);
if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
goto err;
/* Ensure signature uses DER and doesn't have trailing garbage */
derlen = i2d_ECDSA_SIG(s, &der);
if (derlen != sig_len || memcmp(sigbuf, der, derlen))
goto err;
ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
err:
OPENSSL_clear_free(der, derlen);
ECDSA_SIG_free(s);
return (ret);
}
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey)
{

View file

@ -82,20 +82,14 @@ int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
}
int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char
*sig, unsigned int *siglen, const BIGNUM *kinv,
int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen,
unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
const BIGNUM *r, EC_KEY *eckey)
{
ECDSA_SIG *s;
RAND_seed(dgst, dlen);
s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
if (s == NULL) {
*siglen = 0;
return 0;
}
*siglen = i2d_ECDSA_SIG(s, &sig);
ECDSA_SIG_free(s);
return 1;
if (eckey->meth->sign)
return eckey->meth->sign(type, dgst, dlen, sig, siglen, kinv, r, eckey);
ECerr(EC_F_ECDSA_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
return 0;
}
int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,

View file

@ -88,24 +88,10 @@ int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
{
ECDSA_SIG *s;
const unsigned char *p = sigbuf;
unsigned char *der = NULL;
int derlen = -1;
int ret = -1;
s = ECDSA_SIG_new();
if (s == NULL)
return (ret);
if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
goto err;
/* Ensure signature uses DER and doesn't have trailing garbage */
derlen = i2d_ECDSA_SIG(s, &der);
if (derlen != sig_len || memcmp(sigbuf, der, derlen))
goto err;
ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
err:
OPENSSL_clear_free(der, derlen);
ECDSA_SIG_free(s);
return (ret);
if (eckey->meth->verify)
return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len,
eckey);
ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
return 0;
return 0;
}