ecs_ossl.c 13.4 KB
Newer Older
B
Bodo Möller 已提交
1
/* crypto/ecdsa/ecs_ossl.c */
2 3 4
/*
 * Written by Nils Larsch for the OpenSSL project
 */
B
Bodo Möller 已提交
5
/* ====================================================================
6
 * Copyright (c) 1998-2004 The OpenSSL Project.  All rights reserved.
B
Bodo Möller 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
58

D
Dr. Stephen Henson 已提交
59

60

61
#include "ecs_locl.h"
62
#include <openssl/err.h>
63
#include <openssl/obj_mac.h>
64
#include <openssl/bn.h>
A
Adam Langley 已提交
65
#include <openssl/rand.h>
B
Bodo Möller 已提交
66

67
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, 
N
Nils Larsch 已提交
68
		const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
69 70 71
static int ecdsa_sign_setup_no_digest(EC_KEY *eckey,
		BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
72 73
					BIGNUM **kinvp, BIGNUM **rp,
					const unsigned char *dgst, int dlen);
74
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 
N
Nils Larsch 已提交
75
		const ECDSA_SIG *sig, EC_KEY *eckey);
B
Bodo Möller 已提交
76 77

static ECDSA_METHOD openssl_ecdsa_meth = {
78 79
	"OpenSSL ECDSA method",
	ecdsa_do_sign,
80
	ecdsa_sign_setup_no_digest,
81 82 83 84 85
	ecdsa_do_verify,
#if 0
	NULL, /* init     */
	NULL, /* finish   */
#endif
86
	ECDSA_FLAG_FIPS_METHOD,    /* flags    */
87
	NULL  /* app_data */
B
Bodo Möller 已提交
88 89 90 91 92 93 94
};

const ECDSA_METHOD *ECDSA_OpenSSL(void)
{
	return &openssl_ecdsa_meth;
}

95 96 97
static int ecdsa_sign_setup_no_digest(EC_KEY *eckey,
		BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) {
	return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
98 99
}

100
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
101 102
					BIGNUM **kinvp, BIGNUM **rp,
					const unsigned char *dgst, int dlen)
B
Bodo Möller 已提交
103 104
{
	BN_CTX   *ctx = NULL;
105
	BIGNUM	 *k = NULL, *r = NULL, *order = NULL, *X = NULL;
B
Bodo Möller 已提交
106
	EC_POINT *tmp_point=NULL;
N
Nils Larsch 已提交
107
	const EC_GROUP *group;
108
	int 	 ret = 0;
N
Nils Larsch 已提交
109 110

	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
B
Bodo Möller 已提交
111
	{
112
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
B
Bodo Möller 已提交
113 114
		return 0;
	}
115

B
Bodo Möller 已提交
116 117
	if (ctx_in == NULL) 
	{
118
		if ((ctx = BN_CTX_new()) == NULL)
119
		{
120 121
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
			return 0;
122
		}
B
Bodo Möller 已提交
123 124
	}
	else
125
		ctx = ctx_in;
B
Bodo Möller 已提交
126

127 128 129 130 131
	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 || !r || !order || !X)
B
Bodo Möller 已提交
132
	{
133 134
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
		goto err;
135
	}
136
	if ((tmp_point = EC_POINT_new(group)) == NULL)
137 138
	{
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
B
Bodo Möller 已提交
139 140
		goto err;
	}
141
	if (!EC_GROUP_get_order(group, order, ctx))
B
Bodo Möller 已提交
142
	{
143
		ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
B
Bodo Möller 已提交
144 145
		goto err;
	}
146

B
Bodo Möller 已提交
147 148 149 150
	do
	{
		/* get random k */	
		do
A
Adam Langley 已提交
151
#ifndef OPENSSL_NO_SHA512
152
			if (dgst != NULL)
B
Bodo Möller 已提交
153
			{
A
Adam Langley 已提交
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
				if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
							   dgst, dlen, ctx))
					{
					ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
						 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
					goto err;
					}
			}
			else
#endif
			{
				if (!BN_rand_range(k, order))
				{
					ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
						 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
					goto err;
				}
B
Bodo Möller 已提交
171
			}
172
		while (BN_is_zero(k));
B
Bodo Möller 已提交
173

174 175 176 177 178 179 180 181
		/* We do not want timing information to leak the length of k,
		 * so we compute G*k using an equivalent scalar of fixed
		 * bit-length. */

		if (!BN_add(k, k, order)) goto err;
		if (BN_num_bits(k) <= BN_num_bits(order))
			if (!BN_add(k, k, order)) goto err;

B
Bodo Möller 已提交
182
		/* compute r the x-coordinate of generator * k */
183
		if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
184 185 186 187
		{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
			goto err;
		}
188
		if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
189
		{
190
			if (!EC_POINT_get_affine_coordinates_GFp(group,
191 192
				tmp_point, X, NULL, ctx))
			{
193
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
194 195 196
				goto err;
			}
		}
197
#ifndef OPENSSL_NO_EC2M
198 199
		else /* NID_X9_62_characteristic_two_field */
		{
200
			if (!EC_POINT_get_affine_coordinates_GF2m(group,
201 202
				tmp_point, X, NULL, ctx))
			{
203
				ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
204 205 206
				goto err;
			}
		}
207
#endif
208
		if (!BN_nnmod(r, X, order, ctx))
B
Bodo Möller 已提交
209
		{
210
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
B
Bodo Möller 已提交
211 212 213 214 215 216
			goto err;
		}
	}
	while (BN_is_zero(r));

	/* compute the inverse of k */
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
	if (EC_GROUP_get_mont_data(group) != NULL)
		{
		/* We want inverse in constant time, therefore we utilize the
		 * fact order must be prime and use Fermats Little Theorem
		 * instead. */
		if (!BN_set_word(X, 2) )
			{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
			goto err;
			}
		if (!BN_mod_sub(X, order, X, order, ctx))
			{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
			goto err;
			}
		BN_set_flags(X, BN_FLG_CONSTTIME);
		if (!BN_mod_exp_mont_consttime(k, k, X, order, ctx, EC_GROUP_get_mont_data(group)))
			{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
			goto err;
			}
		}
	else
		{
		if (!BN_mod_inverse(k, k, order, ctx))
			{
			ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
			goto err;	
			}
		}

248 249
	/* clear old values if necessary */
	if (*rp != NULL)
B
Bodo Möller 已提交
250
		BN_clear_free(*rp);
251
	if (*kinvp != NULL) 
B
Bodo Möller 已提交
252
		BN_clear_free(*kinvp);
253 254 255
	/* save the pre-computed values  */
	*rp    = r;
	*kinvp = k;
B
Bodo Möller 已提交
256 257 258 259
	ret = 1;
err:
	if (!ret)
	{
260
		if (k != NULL) BN_clear_free(k);
B
Bodo Möller 已提交
261 262 263 264 265
		if (r != NULL) BN_clear_free(r);
	}
	if (ctx_in == NULL) 
		BN_CTX_free(ctx);
	if (order != NULL)
266
		BN_free(order);
B
Bodo Möller 已提交
267 268
	if (tmp_point != NULL) 
		EC_POINT_free(tmp_point);
269 270
	if (X)
		BN_clear_free(X);
B
Bodo Möller 已提交
271 272 273 274
	return(ret);
}


275
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 
N
Nils Larsch 已提交
276
		const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
B
Bodo Möller 已提交
277
{
D
Dr. Stephen Henson 已提交
278
	int     ok = 0, i;
N
Nils Larsch 已提交
279 280
	BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
	const BIGNUM *ckinv;
281
	BN_CTX     *ctx = NULL;
N
Nils Larsch 已提交
282
	const EC_GROUP   *group;
283
	ECDSA_SIG  *ret;
284
	ECDSA_DATA *ecdsa;
N
Nils Larsch 已提交
285
	const BIGNUM *priv_key;
286

N
Nils Larsch 已提交
287 288 289 290 291
	ecdsa    = ecdsa_check(eckey);
	group    = EC_KEY_get0_group(eckey);
	priv_key = EC_KEY_get0_private_key(eckey);
	
	if (group == NULL || priv_key == NULL || ecdsa == NULL)
B
Bodo Möller 已提交
292
	{
293
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
294
		return NULL;
B
Bodo Möller 已提交
295 296
	}

297 298 299 300 301 302 303 304
	ret = ECDSA_SIG_new();
	if (!ret)
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	s = ret->s;

305
	if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
306
		(tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
307 308 309 310
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
		goto err;
	}
B
Bodo Möller 已提交
311

312
	if (!EC_GROUP_get_order(group, order, ctx))
B
Bodo Möller 已提交
313
	{
314
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
B
Bodo Möller 已提交
315 316
		goto err;
	}
D
Dr. Stephen Henson 已提交
317 318 319 320 321 322 323
	i = BN_num_bits(order);
	/* Need to truncate digest if it is too long: first truncate whole
	 * bytes.
	 */
	if (8 * dgst_len > i)
		dgst_len = (i + 7)/8;
	if (!BN_bin2bn(dgst, dgst_len, m))
B
Bodo Möller 已提交
324
	{
D
Dr. Stephen Henson 已提交
325
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
B
Bodo Möller 已提交
326 327
		goto err;
	}
D
Dr. Stephen Henson 已提交
328 329
	/* If still too long truncate remaining bits with a shift */
	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
330 331 332 333
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
		goto err;
	}
B
Bodo Möller 已提交
334 335
	do
	{
N
Nils Larsch 已提交
336
		if (in_kinv == NULL || in_r == NULL)
B
Bodo Möller 已提交
337
		{
338
			if (!ecdsa_sign_setup(
339
				eckey, ctx, &kinv, &ret->r, dgst, dgst_len))
340
			{
341
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
342 343
				goto err;
			}
N
Nils Larsch 已提交
344
			ckinv = kinv;
B
Bodo Möller 已提交
345 346 347
		}
		else
		{
N
Nils Larsch 已提交
348 349 350 351 352 353
			ckinv  = in_kinv;
			if (BN_copy(ret->r, in_r) == NULL)
			{
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
				goto err;
			}
B
Bodo Möller 已提交
354 355
		}

N
Nils Larsch 已提交
356
		if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
357 358 359 360
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
361
		if (!BN_mod_add_quick(s, tmp, m, order))
362 363 364 365
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
N
Nils Larsch 已提交
366
		if (!BN_mod_mul(s, s, ckinv, order, ctx))
367 368 369 370
		{
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
371 372 373 374 375 376 377 378 379 380 381 382 383
		if (BN_is_zero(s))
		{
			/* if kinv and r have been supplied by the caller
			 * don't to generate new kinv and r values */
			if (in_kinv != NULL && in_r != NULL)
			{
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
				goto err;
			}
		}
		else
			/* s != 0 => we have a valid signature */
			break;
B
Bodo Möller 已提交
384
	}
385
	while (1);
B
Bodo Möller 已提交
386

387 388 389
	ok = 1;
err:
	if (!ok)
B
Bodo Möller 已提交
390 391 392 393
	{
		ECDSA_SIG_free(ret);
		ret = NULL;
	}
394 395 396 397 398 399 400
	if (ctx)
		BN_CTX_free(ctx);
	if (m)
		BN_clear_free(m);
	if (tmp)
		BN_clear_free(tmp);
	if (order)
401
		BN_free(order);
402 403
	if (kinv)
		BN_clear_free(kinv);
404
	return ret;
B
Bodo Möller 已提交
405 406
}

407
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
N
Nils Larsch 已提交
408
		const ECDSA_SIG *sig, EC_KEY *eckey)
B
Bodo Möller 已提交
409
{
D
Dr. Stephen Henson 已提交
410
	int ret = -1, i;
411 412 413
	BN_CTX   *ctx;
	BIGNUM   *order, *u1, *u2, *m, *X;
	EC_POINT *point = NULL;
N
Nils Larsch 已提交
414 415 416
	const EC_GROUP *group;
	const EC_POINT *pub_key;

417
	/* check input values */
N
Nils Larsch 已提交
418 419
	if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
	    (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
B
Bodo Möller 已提交
420
	{
421
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
B
Bodo Möller 已提交
422 423 424
		return -1;
	}

425 426
	ctx = BN_CTX_new();
	if (!ctx)
427 428
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
429
		return -1;
430
	}
431 432 433 434 435 436 437
	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)
438 439 440 441
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
442 443
	
	if (!EC_GROUP_get_order(group, order, ctx))
B
Bodo Möller 已提交
444
	{
445
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
B
Bodo Möller 已提交
446 447
		goto err;
	}
448

449
	if (BN_is_zero(sig->r)          || BN_is_negative(sig->r) || 
450
	    BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s)  ||
451
	    BN_is_negative(sig->s)      || BN_ucmp(sig->s, order) >= 0)
B
Bodo Möller 已提交
452
	{
453
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
454
		ret = 0;	/* signature is invalid */
B
Bodo Möller 已提交
455 456 457
		goto err;
	}
	/* calculate tmp1 = inv(S) mod order */
458
	if (!BN_mod_inverse(u2, sig->s, order, ctx))
459 460 461 462
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
B
Bodo Möller 已提交
463
	/* digest -> m */
D
Dr. Stephen Henson 已提交
464 465 466 467 468 469
	i = BN_num_bits(order);
	/* Need to truncate digest if it is too long: first truncate whole
	 * bytes.
	 */
	if (8 * dgst_len > i)
		dgst_len = (i + 7)/8;
470
	if (!BN_bin2bn(dgst, dgst_len, m))
471 472 473 474
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
D
Dr. Stephen Henson 已提交
475 476 477 478 479 480
	/* If still too long truncate remaining bits with a shift */
	if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
B
Bodo Möller 已提交
481
	/* u1 = m * tmp mod order */
482
	if (!BN_mod_mul(u1, m, u2, order, ctx))
483 484 485 486
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
B
Bodo Möller 已提交
487
	/* u2 = r * w mod q */
488
	if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
489 490 491 492
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
B
Bodo Möller 已提交
493

494
	if ((point = EC_POINT_new(group)) == NULL)
B
Bodo Möller 已提交
495
	{
496
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
B
Bodo Möller 已提交
497 498
		goto err;
	}
N
Nils Larsch 已提交
499
	if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
B
Bodo Möller 已提交
500
	{
501 502 503
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}
504
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
505
	{
506
		if (!EC_POINT_get_affine_coordinates_GFp(group,
507 508
			point, X, NULL, ctx))
		{
509
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
510 511 512
			goto err;
		}
	}
513
#ifndef OPENSSL_NO_EC2M
514 515
	else /* NID_X9_62_characteristic_two_field */
	{
516
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
517 518
			point, X, NULL, ctx))
		{
519
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
520 521 522
			goto err;
		}
	}
523
#endif	
524
	if (!BN_nnmod(u1, X, order, ctx))
525 526
	{
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
B
Bodo Möller 已提交
527 528
		goto err;
	}
529 530 531 532 533
	/*  if the signature is correct u1 is equal to sig->r */
	ret = (BN_ucmp(u1, sig->r) == 0);
err:
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
534 535
	if (point)
		EC_POINT_free(point);
536
	return ret;
B
Bodo Möller 已提交
537
}