Top level ECDSA sign/verify redirection.
authorDr. Stephen Henson <steve@openssl.org>
Wed, 28 Oct 2015 16:57:51 +0000 (16:57 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 9 Dec 2015 22:09:19 +0000 (22:09 +0000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
crypto/ec/ec_kmeth.c
crypto/ec/ec_lcl.h
crypto/ec/ecdsa_ossl.c
crypto/ec/ecdsa_sign.c
crypto/ec/ecdsa_vrf.c

index a329e7a..596d8c0 100644 (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
 };
 
index b18e882..3cd2345 100644 (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);
index 08e10f7..40742bd 100644 (file)
@@ -56,6 +56,7 @@
  *
  */
 
+#include <string.h>
 #include <openssl/err.h>
 #include <openssl/obj_mac.h>
 #include <openssl/bn.h>
 #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)
 {
index f3c6d78..aeccda7 100644 (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,
index a62b999..f545cf6 100644 (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;
 }