X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fecdsa%2Fecs_ossl.c;h=215da3892af8e9485c78b670f96d211d279fef76;hp=915ece7bf448db950a7a1521e899d0d23bfd2f64;hb=b53e44e57259b2b015c54de8ecbcf4e06be23298;hpb=0bee0e6294882b18ffa0053597532058a19d6f89 diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c index 915ece7bf4..215da3892a 100644 --- a/crypto/ecdsa/ecs_ossl.c +++ b/crypto/ecdsa/ecs_ossl.c @@ -55,22 +55,26 @@ #include "ecdsa.h" #include +#include -/* TODO : general case */ -#define EC_POINT_get_affine_coordinates EC_POINT_get_affine_coordinates_GFp - -static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, ECDSA *ecdsa); -static int ecdsa_sign_setup(ECDSA *ecdsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); -static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, ECDSA_SIG *sig, - ECDSA *ecdsa); +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, + EC_KEY *eckey); +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, + ECDSA_SIG *sig, EC_KEY *eckey); static ECDSA_METHOD openssl_ecdsa_meth = { -"OpenSSL ECDSA method", -ecdsa_do_sign, -ecdsa_sign_setup, -ecdsa_do_verify, -0, -NULL + "OpenSSL ECDSA method", + ecdsa_do_sign, + ecdsa_sign_setup, + ecdsa_do_verify, +#if 0 + NULL, /* init */ + NULL, /* finish */ +#endif + 0, /* flags */ + NULL /* app_data */ }; const ECDSA_METHOD *ECDSA_OpenSSL(void) @@ -78,35 +82,52 @@ const ECDSA_METHOD *ECDSA_OpenSSL(void) return &openssl_ecdsa_meth; } -static int ecdsa_sign_setup(ECDSA *ecdsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) { BN_CTX *ctx = NULL; BIGNUM k,*kinv=NULL,*r=NULL,*order=NULL,*X=NULL; EC_POINT *tmp_point=NULL; - int ret = 0,reason = ERR_R_BN_LIB; - if (!ecdsa || !ecdsa->group || !ecdsa->pub_key || !ecdsa->priv_key) + int ret = 0; + if (!eckey || !eckey->group || !eckey->pub_key || !eckey->priv_key) { - reason = ECDSA_R_MISSING_PARAMETERS; + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (ctx_in == NULL) { - if ((ctx=BN_CTX_new()) == NULL) goto err; + if ((ctx=BN_CTX_new()) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); + goto err; + } } else ctx=ctx_in; - if ((r = BN_new()) == NULL) goto err; - if ((order = BN_new()) == NULL) goto err; - if ((X = BN_new()) == NULL) goto err; - if ((tmp_point = EC_POINT_new(ecdsa->group)) == NULL) + if ((r = BN_new()) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + if ((order = BN_new()) == NULL) { - reason = ERR_R_EC_LIB; + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + if ((X = BN_new()) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + if ((tmp_point = EC_POINT_new(eckey->group)) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } - if (!EC_GROUP_get_order(ecdsa->group,order,ctx)) + if (!EC_GROUP_get_order(eckey->group,order,ctx)) { - reason = ERR_R_EC_LIB; + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); goto err; } @@ -117,24 +138,53 @@ static int ecdsa_sign_setup(ECDSA *ecdsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM do if (!BN_rand_range(&k,order)) { - reason = ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED; + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, + ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); goto err; } while (BN_is_zero(&k)); /* compute r the x-coordinate of generator * k */ - if (!EC_POINT_mul(ecdsa->group,tmp_point,&k,NULL,NULL,ctx) - || !EC_POINT_get_affine_coordinates(ecdsa->group,tmp_point,X,NULL,ctx)) + if (!EC_POINT_mul(eckey->group, tmp_point, &k, NULL, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + if (EC_METHOD_get_field_type(EC_GROUP_method_of(eckey->group)) + == NID_X9_62_prime_field) + { + if (!EC_POINT_get_affine_coordinates_GFp(eckey->group, + tmp_point, X, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, + ERR_R_EC_LIB); + goto err; + } + } + else /* NID_X9_62_characteristic_two_field */ + { + if (!EC_POINT_get_affine_coordinates_GF2m(eckey->group, + tmp_point, X, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, + ERR_R_EC_LIB); + goto err; + } + } + if (!BN_nnmod(r,X,order,ctx)) { - reason = ERR_R_EC_LIB; + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); goto err; } - if (!BN_nnmod(r,X,order,ctx)) goto err; } while (BN_is_zero(r)); /* compute the inverse of k */ - if ((kinv = BN_mod_inverse(NULL,&k,order,ctx)) == NULL) goto err; + if ((kinv = BN_mod_inverse(NULL,&k,order,ctx)) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } if (*rp == NULL) BN_clear_free(*rp); @@ -147,7 +197,6 @@ static int ecdsa_sign_setup(ECDSA *ecdsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM err: if (!ret) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,reason); if (kinv != NULL) BN_clear_free(kinv); if (r != NULL) BN_clear_free(r); } @@ -165,44 +214,60 @@ err: } -static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, ECDSA *ecdsa) +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey) { BIGNUM *kinv=NULL,*r=NULL,*s=NULL,*m=NULL,*tmp=NULL,*order=NULL; BIGNUM xr; BN_CTX *ctx=NULL; - int reason=ERR_R_BN_LIB; ECDSA_SIG *ret=NULL; + ECDSA_DATA *ecdsa; + + ecdsa = ecdsa_check(eckey); - if (!ecdsa || !ecdsa->group || !ecdsa->pub_key || !ecdsa->priv_key) + if (!eckey || !eckey->group || !eckey->pub_key || !eckey->priv_key + || !ecdsa) { - reason = ECDSA_R_MISSING_PARAMETERS; + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); goto err; } BN_init(&xr); - if ((ctx = BN_CTX_new()) == NULL) goto err; - if ((order = BN_new()) == NULL) goto err; - if ((tmp = BN_new()) == NULL) goto err; - if ((m = BN_new()) == NULL) goto err; - if ((s = BN_new()) == NULL) goto err; + if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || + (tmp = BN_new()) == NULL || (m = BN_new()) == NULL || + (s = BN_new()) == NULL ) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } - if (!EC_GROUP_get_order(ecdsa->group,order,ctx)) + if (!EC_GROUP_get_order(eckey->group,order,ctx)) { - reason = ECDSA_R_ERR_EC_LIB; + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); goto err; } if (dgst_len > BN_num_bytes(order)) { - reason = ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, + ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } - if (BN_bin2bn(dgst,dgst_len,m) == NULL) goto err; + if (BN_bin2bn(dgst,dgst_len,m) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } do { - if ((ecdsa->kinv == NULL) || (ecdsa->r == NULL)) + if (ecdsa->kinv == NULL || ecdsa->r == NULL) { - if (!ECDSA_sign_setup(ecdsa,ctx,&kinv,&r)) goto err; + if (!ECDSA_sign_setup(eckey,ctx,&kinv,&r)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, + ERR_R_ECDSA_LIB); + goto err; + } } else { @@ -212,109 +277,176 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, ECDSA * ecdsa->r = NULL; } - if (!BN_mod_mul(tmp,ecdsa->priv_key,r,order,ctx)) goto err; - if (!BN_add(s,tmp,m)) goto err; + if (!BN_mod_mul(tmp,eckey->priv_key,r,order,ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (!BN_add(s,tmp,m)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } if (BN_cmp(s,order) > 0) BN_sub(s,s,order); - if (!BN_mod_mul(s,s,kinv,order,ctx)) goto err; + if (!BN_mod_mul(s,s,kinv,order,ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } } while (BN_is_zero(s)); if ((ret = ECDSA_SIG_new()) == NULL) { - reason = ECDSA_R_SIGNATURE_MALLOC_FAILED; + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); goto err; } if (BN_copy(ret->r, r) == NULL || BN_copy(ret->s, s) == NULL) { ECDSA_SIG_free(ret); ret = NULL; - reason = ERR_R_BN_LIB; + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); } err: - if (!ret) - { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,reason); - } - if (r != NULL) BN_clear_free(r); - if (s != NULL) BN_clear_free(s); - if (ctx != NULL) BN_CTX_free(ctx); - if (m != NULL) BN_clear_free(m); - if (tmp != NULL) BN_clear_free(tmp); - if (order != NULL) BN_clear_free(order); - if (kinv != NULL) BN_clear_free(kinv); + if (r) + BN_clear_free(r); + if (s) + BN_clear_free(s); + if (ctx) + BN_CTX_free(ctx); + if (m) + BN_clear_free(m); + if (tmp) + BN_clear_free(tmp); + if (order) + BN_clear_free(order); + if (kinv) + BN_clear_free(kinv); return(ret); } -static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, ECDSA_SIG *sig, - ECDSA *ecdsa) +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, + ECDSA_SIG *sig, EC_KEY *eckey) { BN_CTX *ctx; BIGNUM *order=NULL,*u1=NULL,*u2=NULL,*m=NULL,*X=NULL; EC_POINT *point=NULL; - int ret = -1,reason = ERR_R_BN_LIB; - if (!ecdsa || !ecdsa->group || !ecdsa->pub_key || !sig) + int ret = -1; + if (!eckey || !eckey->group || !eckey->pub_key || !sig) { - reason = ECDSA_R_MISSING_PARAMETERS; + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); return -1; } - if ((ctx = BN_CTX_new()) == NULL) goto err; - if ((order = BN_new()) == NULL) goto err; - if ((u1 = BN_new()) == NULL) goto err; - if ((u2 = BN_new()) == NULL) goto err; - if ((m = BN_new()) == NULL) goto err; - if ((X = BN_new()) == NULL) goto err; - if (!EC_GROUP_get_order(ecdsa->group,order,ctx)) goto err; + if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || + (u1 = BN_new()) == NULL || (u2 = BN_new()) == NULL || + (m = BN_new()) == NULL || (X = BN_new()) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_GROUP_get_order(eckey->group, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } - if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, order) >= 0) + if (BN_is_zero(sig->r) || BN_get_sign(sig->r) || + BN_ucmp(sig->r, order) >= 0) { - reason = ECDSA_R_BAD_SIGNATURE; + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); ret = 0; goto err; } - if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, order) >= 0) + if (BN_is_zero(sig->s) || BN_get_sign(sig->s) || + BN_ucmp(sig->s, order) >= 0) { - reason = ECDSA_R_BAD_SIGNATURE; + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); ret = 0; goto err; } /* calculate tmp1 = inv(S) mod order */ - if ((BN_mod_inverse(u2,sig->s,order,ctx)) == NULL) goto err; + if ((BN_mod_inverse(u2,sig->s,order,ctx)) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } /* digest -> m */ - if (BN_bin2bn(dgst,dgst_len,m) == NULL) goto err; + if (BN_bin2bn(dgst,dgst_len,m) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } /* u1 = m * tmp mod order */ - if (!BN_mod_mul(u1,m,u2,order,ctx)) goto err; + if (!BN_mod_mul(u1,m,u2,order,ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } /* u2 = r * w mod q */ - if (!BN_mod_mul(u2,sig->r,u2,order,ctx)) goto err; + if (!BN_mod_mul(u2,sig->r,u2,order,ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } - if ((point = EC_POINT_new(ecdsa->group)) == NULL) + if ((point = EC_POINT_new(eckey->group)) == NULL) { - reason = ERR_R_EC_LIB; + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } - if (!EC_POINT_mul(ecdsa->group,point,u1,ecdsa->pub_key,u2,ctx) - || !EC_POINT_get_affine_coordinates(ecdsa->group,point,X,NULL,ctx)) + if (!EC_POINT_mul(eckey->group, point, u1, eckey->pub_key, u2, ctx)) { - reason = ERR_R_EC_LIB; + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + if (EC_METHOD_get_field_type(EC_GROUP_method_of(eckey->group)) + == NID_X9_62_prime_field) + { + if (!EC_POINT_get_affine_coordinates_GFp(eckey->group, + point, X, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + } + else /* NID_X9_62_characteristic_two_field */ + { + if (!EC_POINT_get_affine_coordinates_GF2m(eckey->group, + point, X, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + } + + if (!BN_nnmod(u1,X,order,ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } - if (!BN_nnmod(u1,X,order,ctx)) goto err; /* is now in u1. If the signature is correct, it will be * equal to R. */ ret = (BN_ucmp(u1,sig->r) == 0); err: - if (ret != 1) ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY,reason); - if (ctx != NULL) BN_CTX_free(ctx); - if (u1 != NULL) BN_clear_free(u1); - if (u2 != NULL) BN_clear_free(u2); - if (m != NULL) BN_clear_free(m); - if (X != NULL) BN_clear_free(X); - if (order != NULL) BN_clear_free(order); - if (point != NULL) EC_POINT_free(point); + if (ctx) + BN_CTX_free(ctx); + if (u1) + BN_clear_free(u1); + if (u2) + BN_clear_free(u2); + if (m) + BN_clear_free(m); + if (X) + BN_clear_free(X); + if (order) + BN_clear_free(order); + if (point) + EC_POINT_free(point); return(ret); }