summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2015-10-28 16:57:51 +0000
committerDr. Stephen Henson <steve@openssl.org>2015-12-09 22:09:19 +0000
commita200a817add039d0515e6ecf94237b634819687d (patch)
tree8a968313e9398c4dfd7d462293888e586ce2325e
parent7d711cbc335206327d1dbb0389d9ab83b461d4de (diff)
Top level ECDSA sign/verify redirection.
Reviewed-by: Richard Levitte <levitte@openssl.org>
-rw-r--r--crypto/ec/ec_kmeth.c2
-rw-r--r--crypto/ec/ec_lcl.h11
-rw-r--r--crypto/ec/ecdsa_ossl.c48
-rw-r--r--crypto/ec/ecdsa_sign.c18
-rw-r--r--crypto/ec/ecdsa_vrf.c26
5 files changed, 73 insertions, 32 deletions
diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c
index a329e7adcb..596d8c02fd 100644
--- a/crypto/ec/ec_kmeth.c
+++ b/crypto/ec/ec_kmeth.c
@@ -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
};
diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h
index b18e8821df..3cd2345695 100644
--- a/crypto/ec/ec_lcl.h
+++ b/crypto/ec/ec_lcl.h
@@ -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);
diff --git a/crypto/ec/ecdsa_ossl.c b/crypto/ec/ecdsa_ossl.c
index 08e10f773f..40742bdf06 100644
--- a/crypto/ec/ecdsa_ossl.c
+++ b/crypto/ec/ecdsa_ossl.c
@@ -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)
{
diff --git a/crypto/ec/ecdsa_sign.c b/crypto/ec/ecdsa_sign.c
index f3c6d7871c..aeccda74a2 100644
--- a/crypto/ec/ecdsa_sign.c
+++ b/crypto/ec/ecdsa_sign.c
@@ -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,
diff --git a/crypto/ec/ecdsa_vrf.c b/crypto/ec/ecdsa_vrf.c
index a62b999bb9..f545cf6871 100644
--- a/crypto/ec/ecdsa_vrf.c
+++ b/crypto/ec/ecdsa_vrf.c
@@ -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;
}