-/* crypto/ec/ecdsa_ossl.c */
/*
* Written by Nils Larsch for the OpenSSL project
*/
*
*/
+#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)
{
BN_CTX *ctx = NULL;
- BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
+ BIGNUM *k = NULL, *r = NULL, *X = NULL;
+ const BIGNUM *order;
EC_POINT *tmp_point = NULL;
const EC_GROUP *group;
int ret = 0;
k = BN_new(); /* this value is later returned in *kinvp */
r = BN_new(); /* this value is later returned in *rp */
- order = BN_new();
X = BN_new();
- if (k == NULL || r == NULL || order == NULL || X == NULL) {
+ if (k == NULL || r == NULL || X == NULL) {
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
goto err;
}
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
- if (!EC_GROUP_get_order(group, order, ctx)) {
+ order = EC_GROUP_get0_order(group);
+ if (order == NULL) {
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
}
if (ctx != ctx_in)
BN_CTX_free(ctx);
- BN_free(order);
EC_POINT_free(tmp_point);
BN_clear_free(X);
return (ret);
EC_KEY *eckey)
{
int ok = 0, i;
- BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
- const BIGNUM *ckinv;
+ BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL;
+ const BIGNUM *order, *ckinv;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
ECDSA_SIG *ret;
}
s = ret->s;
- if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
+ if ((ctx = BN_CTX_new()) == NULL ||
(tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!EC_GROUP_get_order(group, order, ctx)) {
+ order = EC_GROUP_get0_order(group);
+ if (order == NULL) {
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_EC_LIB);
goto err;
}
BN_CTX_free(ctx);
BN_clear_free(m);
BN_clear_free(tmp);
- BN_free(order);
BN_clear_free(kinv);
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) != 0)
+ 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)
{
int ret = -1, i;
BN_CTX *ctx;
- BIGNUM *order, *u1, *u2, *m, *X;
+ const BIGNUM *order;
+ BIGNUM *u1, *u2, *m, *X;
EC_POINT *point = NULL;
const EC_GROUP *group;
const EC_POINT *pub_key;
return -1;
}
BN_CTX_start(ctx);
- order = BN_CTX_get(ctx);
u1 = BN_CTX_get(ctx);
u2 = BN_CTX_get(ctx);
m = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
- if (!X) {
+ if (X == NULL) {
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
goto err;
}
- if (!EC_GROUP_get_order(group, order, ctx)) {
+ order = EC_GROUP_get0_order(group);
+ if (order == NULL) {
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
goto err;
}