Branch data Line data Source code
1 : : /* crypto/ecdsa/ecs_ossl.c */
2 : : /*
3 : : * Written by Nils Larsch for the OpenSSL project
4 : : */
5 : : /* ====================================================================
6 : : * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved.
7 : : *
8 : : * Redistribution and use in source and binary forms, with or without
9 : : * modification, are permitted provided that the following conditions
10 : : * are met:
11 : : *
12 : : * 1. Redistributions of source code must retain the above copyright
13 : : * notice, this list of conditions and the following disclaimer.
14 : : *
15 : : * 2. Redistributions in binary form must reproduce the above copyright
16 : : * notice, this list of conditions and the following disclaimer in
17 : : * the documentation and/or other materials provided with the
18 : : * distribution.
19 : : *
20 : : * 3. All advertising materials mentioning features or use of this
21 : : * software must display the following acknowledgment:
22 : : * "This product includes software developed by the OpenSSL Project
23 : : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 : : *
25 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 : : * endorse or promote products derived from this software without
27 : : * prior written permission. For written permission, please contact
28 : : * openssl-core@OpenSSL.org.
29 : : *
30 : : * 5. Products derived from this software may not be called "OpenSSL"
31 : : * nor may "OpenSSL" appear in their names without prior written
32 : : * permission of the OpenSSL Project.
33 : : *
34 : : * 6. Redistributions of any form whatsoever must retain the following
35 : : * acknowledgment:
36 : : * "This product includes software developed by the OpenSSL Project
37 : : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 : : *
39 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
51 : : * ====================================================================
52 : : *
53 : : * This product includes cryptographic software written by Eric Young
54 : : * (eay@cryptsoft.com). This product includes software written by Tim
55 : : * Hudson (tjh@cryptsoft.com).
56 : : *
57 : : */
58 : :
59 : : #define OPENSSL_FIPSAPI
60 : :
61 : : #include "ecs_locl.h"
62 : : #include <openssl/err.h>
63 : : #include <openssl/obj_mac.h>
64 : : #include <openssl/bn.h>
65 : : #include <openssl/rand.h>
66 : :
67 : : static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
68 : : const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
69 : : static int ecdsa_sign_setup_no_digest(EC_KEY *eckey,
70 : : BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
71 : : static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
72 : : BIGNUM **kinvp, BIGNUM **rp,
73 : : const unsigned char *dgst, int dlen);
74 : : static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
75 : : const ECDSA_SIG *sig, EC_KEY *eckey);
76 : :
77 : : static ECDSA_METHOD openssl_ecdsa_meth = {
78 : : "OpenSSL ECDSA method",
79 : : ecdsa_do_sign,
80 : : ecdsa_sign_setup_no_digest,
81 : : ecdsa_do_verify,
82 : : #if 0
83 : : NULL, /* init */
84 : : NULL, /* finish */
85 : : #endif
86 : : ECDSA_FLAG_FIPS_METHOD, /* flags */
87 : : NULL /* app_data */
88 : : };
89 : :
90 : 1 : const ECDSA_METHOD *ECDSA_OpenSSL(void)
91 : : {
92 : 1 : return &openssl_ecdsa_meth;
93 : : }
94 : :
95 : 4 : static int ecdsa_sign_setup_no_digest(EC_KEY *eckey,
96 : : BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) {
97 : 4 : return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
98 : : }
99 : :
100 : 71 : static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
101 : : BIGNUM **kinvp, BIGNUM **rp,
102 : : const unsigned char *dgst, int dlen)
103 : : {
104 : 71 : BN_CTX *ctx = NULL;
105 : 71 : BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
106 : 71 : EC_POINT *tmp_point=NULL;
107 : : const EC_GROUP *group;
108 : 71 : int ret = 0;
109 : :
110 [ + - ][ - + ]: 71 : if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
111 : : {
112 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
113 : 0 : return 0;
114 : : }
115 : :
116 [ + + ]: 71 : if (ctx_in == NULL)
117 : : {
118 [ - + ]: 4 : if ((ctx = BN_CTX_new()) == NULL)
119 : : {
120 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
121 : 0 : return 0;
122 : : }
123 : : }
124 : : else
125 : : ctx = ctx_in;
126 : :
127 : 71 : k = BN_new(); /* this value is later returned in *kinvp */
128 : 71 : r = BN_new(); /* this value is later returned in *rp */
129 : 71 : order = BN_new();
130 : 71 : X = BN_new();
131 [ + - ][ - + ]: 71 : if (!k || !r || !order || !X)
132 : : {
133 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
134 : 0 : goto err;
135 : : }
136 [ - + ]: 71 : if ((tmp_point = EC_POINT_new(group)) == NULL)
137 : : {
138 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
139 : 0 : goto err;
140 : : }
141 [ - + ]: 71 : if (!EC_GROUP_get_order(group, order, ctx))
142 : : {
143 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
144 : 71 : goto err;
145 : : }
146 : :
147 : : #ifdef OPENSSL_FIPS
148 : : if (!fips_check_ec_prng(eckey))
149 : : goto err;
150 : : #endif
151 : :
152 : : do
153 : : {
154 : : /* get random k */
155 : : do
156 : : #ifndef OPENSSL_NO_SHA512
157 [ + + ]: 71 : if (dgst != NULL)
158 : : {
159 [ - + ]: 67 : if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
160 : : dgst, dlen, ctx))
161 : : {
162 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
163 : : ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
164 : 0 : goto err;
165 : : }
166 : : }
167 : : else
168 : : #endif
169 : : {
170 [ - + ]: 4 : if (!BN_rand_range(k, order))
171 : : {
172 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
173 : : ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
174 : 0 : goto err;
175 : : }
176 : : }
177 [ - + ]: 71 : while (BN_is_zero(k));
178 : :
179 : : /* We do not want timing information to leak the length of k,
180 : : * so we compute G*k using an equivalent scalar of fixed
181 : : * bit-length. */
182 : :
183 [ + - ]: 71 : if (!BN_add(k, k, order)) goto err;
184 [ + + ]: 71 : if (BN_num_bits(k) <= BN_num_bits(order))
185 [ + - ]: 40 : if (!BN_add(k, k, order)) goto err;
186 : :
187 : : /* compute r the x-coordinate of generator * k */
188 [ - + ]: 71 : if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
189 : : {
190 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
191 : 0 : goto err;
192 : : }
193 [ + + ]: 71 : if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
194 : : {
195 [ - + ]: 35 : if (!EC_POINT_get_affine_coordinates_GFp(group,
196 : : tmp_point, X, NULL, ctx))
197 : : {
198 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
199 : 0 : goto err;
200 : : }
201 : : }
202 : : #ifndef OPENSSL_NO_EC2M
203 : : else /* NID_X9_62_characteristic_two_field */
204 : : {
205 [ - + ]: 36 : if (!EC_POINT_get_affine_coordinates_GF2m(group,
206 : : tmp_point, X, NULL, ctx))
207 : : {
208 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
209 : 0 : goto err;
210 : : }
211 : : }
212 : : #endif
213 [ - + ]: 71 : if (!BN_nnmod(r, X, order, ctx))
214 : : {
215 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
216 : 0 : goto err;
217 : : }
218 : : }
219 [ - + ]: 71 : while (BN_is_zero(r));
220 : :
221 : : /* compute the inverse of k */
222 [ - + ]: 71 : if (!BN_mod_inverse(k, k, order, ctx))
223 : : {
224 : 0 : ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
225 : 0 : goto err;
226 : : }
227 : : /* clear old values if necessary */
228 [ + + ]: 71 : if (*rp != NULL)
229 : 67 : BN_clear_free(*rp);
230 [ - + ]: 71 : if (*kinvp != NULL)
231 : 0 : BN_clear_free(*kinvp);
232 : : /* save the pre-computed values */
233 : 71 : *rp = r;
234 : 71 : *kinvp = k;
235 : 71 : ret = 1;
236 : : err:
237 [ - + ]: 71 : if (!ret)
238 : : {
239 [ # # ]: 0 : if (k != NULL) BN_clear_free(k);
240 [ # # ]: 0 : if (r != NULL) BN_clear_free(r);
241 : : }
242 [ + + ]: 71 : if (ctx_in == NULL)
243 : 4 : BN_CTX_free(ctx);
244 [ + - ]: 71 : if (order != NULL)
245 : 71 : BN_free(order);
246 [ + - ]: 71 : if (tmp_point != NULL)
247 : 71 : EC_POINT_free(tmp_point);
248 [ + - ]: 71 : if (X)
249 : 71 : BN_clear_free(X);
250 : 71 : return(ret);
251 : : }
252 : :
253 : :
254 : 71 : static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
255 : : const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
256 : : {
257 : 71 : int ok = 0, i;
258 : 71 : BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
259 : : const BIGNUM *ckinv;
260 : 71 : BN_CTX *ctx = NULL;
261 : : const EC_GROUP *group;
262 : : ECDSA_SIG *ret;
263 : : ECDSA_DATA *ecdsa;
264 : : const BIGNUM *priv_key;
265 : :
266 : : #ifdef OPENSSL_FIPS
267 : : if(FIPS_selftest_failed())
268 : : {
269 : : FIPSerr(FIPS_F_ECDSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED);
270 : : return NULL;
271 : : }
272 : : #endif
273 : :
274 : 71 : ecdsa = ecdsa_check(eckey);
275 : 71 : group = EC_KEY_get0_group(eckey);
276 : 71 : priv_key = EC_KEY_get0_private_key(eckey);
277 : :
278 [ + - ][ - + ]: 71 : if (group == NULL || priv_key == NULL || ecdsa == NULL)
279 : : {
280 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
281 : 0 : return NULL;
282 : : }
283 : :
284 : : #ifdef OPENSSL_FIPS
285 : : if (!fips_check_ec_prng(eckey))
286 : : return NULL;
287 : : #endif
288 : :
289 : 71 : ret = ECDSA_SIG_new();
290 [ - + ]: 71 : if (!ret)
291 : : {
292 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
293 : 0 : return NULL;
294 : : }
295 : 71 : s = ret->s;
296 : :
297 [ + - ][ + - ]: 71 : if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
[ + - ]
298 [ - + ]: 71 : (tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
299 : : {
300 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
301 : 0 : goto err;
302 : : }
303 : :
304 [ - + ]: 71 : if (!EC_GROUP_get_order(group, order, ctx))
305 : : {
306 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
307 : 0 : goto err;
308 : : }
309 : 71 : i = BN_num_bits(order);
310 : : /* Need to truncate digest if it is too long: first truncate whole
311 : : * bytes.
312 : : */
313 [ - + ]: 71 : if (8 * dgst_len > i)
314 : 0 : dgst_len = (i + 7)/8;
315 [ - + ]: 71 : if (!BN_bin2bn(dgst, dgst_len, m))
316 : : {
317 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
318 : 0 : goto err;
319 : : }
320 : : /* If still too long truncate remaining bits with a shift */
321 [ - + ][ # # ]: 71 : if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
322 : : {
323 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
324 : 71 : goto err;
325 : : }
326 : : do
327 : : {
328 [ + + ]: 71 : if (in_kinv == NULL || in_r == NULL)
329 : : {
330 [ - + ]: 67 : if (!ecdsa_sign_setup(
331 : : eckey, ctx, &kinv, &ret->r, dgst, dgst_len))
332 : : {
333 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
334 : 0 : goto err;
335 : : }
336 : 67 : ckinv = kinv;
337 : : }
338 : : else
339 : : {
340 : 4 : ckinv = in_kinv;
341 [ - + ]: 4 : if (BN_copy(ret->r, in_r) == NULL)
342 : : {
343 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
344 : 0 : goto err;
345 : : }
346 : : }
347 : :
348 [ - + ]: 71 : if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
349 : : {
350 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
351 : 0 : goto err;
352 : : }
353 [ - + ]: 71 : if (!BN_mod_add_quick(s, tmp, m, order))
354 : : {
355 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
356 : 0 : goto err;
357 : : }
358 [ - + ]: 71 : if (!BN_mod_mul(s, s, ckinv, order, ctx))
359 : : {
360 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
361 : 0 : goto err;
362 : : }
363 [ - + ]: 71 : if (BN_is_zero(s))
364 : : {
365 : : /* if kinv and r have been supplied by the caller
366 : : * don't to generate new kinv and r values */
367 [ # # ]: 0 : if (in_kinv != NULL && in_r != NULL)
368 : : {
369 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
370 : 0 : goto err;
371 : : }
372 : : }
373 : : else
374 : : /* s != 0 => we have a valid signature */
375 : : break;
376 : : }
377 : : while (1);
378 : :
379 : : ok = 1;
380 : : err:
381 [ - + ]: 71 : if (!ok)
382 : : {
383 : 0 : ECDSA_SIG_free(ret);
384 : 0 : ret = NULL;
385 : : }
386 [ + - ]: 71 : if (ctx)
387 : 71 : BN_CTX_free(ctx);
388 [ + - ]: 71 : if (m)
389 : 71 : BN_clear_free(m);
390 [ + - ]: 71 : if (tmp)
391 : 71 : BN_clear_free(tmp);
392 [ + - ]: 71 : if (order)
393 : 71 : BN_free(order);
394 [ + + ]: 71 : if (kinv)
395 : 67 : BN_clear_free(kinv);
396 : 71 : return ret;
397 : : }
398 : :
399 : 339 : static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
400 : : const ECDSA_SIG *sig, EC_KEY *eckey)
401 : : {
402 : 339 : int ret = -1, i;
403 : : BN_CTX *ctx;
404 : : BIGNUM *order, *u1, *u2, *m, *X;
405 : 339 : EC_POINT *point = NULL;
406 : : const EC_GROUP *group;
407 : : const EC_POINT *pub_key;
408 : :
409 : : #ifdef OPENSSL_FIPS
410 : : if(FIPS_selftest_failed())
411 : : {
412 : : FIPSerr(FIPS_F_ECDSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED);
413 : : return -1;
414 : : }
415 : : #endif
416 : :
417 : : /* check input values */
418 [ + - ][ + - ]: 339 : if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
[ + - ]
419 [ - + ]: 339 : (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
420 : : {
421 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
422 : 0 : return -1;
423 : : }
424 : :
425 : 339 : ctx = BN_CTX_new();
426 [ - + ]: 339 : if (!ctx)
427 : : {
428 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
429 : 0 : return -1;
430 : : }
431 : 339 : BN_CTX_start(ctx);
432 : 339 : order = BN_CTX_get(ctx);
433 : 339 : u1 = BN_CTX_get(ctx);
434 : 339 : u2 = BN_CTX_get(ctx);
435 : 339 : m = BN_CTX_get(ctx);
436 : 339 : X = BN_CTX_get(ctx);
437 [ - + ]: 339 : if (!X)
438 : : {
439 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
440 : 0 : goto err;
441 : : }
442 : :
443 [ - + ]: 339 : if (!EC_GROUP_get_order(group, order, ctx))
444 : : {
445 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
446 : 0 : goto err;
447 : : }
448 : :
449 [ + - ]: 678 : if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
[ + - + + ]
450 [ + - ][ + - ]: 677 : BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
451 [ + + ]: 338 : BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0)
452 : : {
453 : 2 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
454 : 2 : ret = 0; /* signature is invalid */
455 : 2 : goto err;
456 : : }
457 : : /* calculate tmp1 = inv(S) mod order */
458 [ - + ]: 337 : if (!BN_mod_inverse(u2, sig->s, order, ctx))
459 : : {
460 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
461 : 0 : goto err;
462 : : }
463 : : /* digest -> m */
464 : 337 : i = BN_num_bits(order);
465 : : /* Need to truncate digest if it is too long: first truncate whole
466 : : * bytes.
467 : : */
468 [ - + ]: 337 : if (8 * dgst_len > i)
469 : 0 : dgst_len = (i + 7)/8;
470 [ - + ]: 337 : if (!BN_bin2bn(dgst, dgst_len, m))
471 : : {
472 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
473 : 0 : goto err;
474 : : }
475 : : /* If still too long truncate remaining bits with a shift */
476 [ - + ][ # # ]: 337 : if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
477 : : {
478 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
479 : 0 : goto err;
480 : : }
481 : : /* u1 = m * tmp mod order */
482 [ - + ]: 337 : if (!BN_mod_mul(u1, m, u2, order, ctx))
483 : : {
484 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
485 : 0 : goto err;
486 : : }
487 : : /* u2 = r * w mod q */
488 [ - + ]: 337 : if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
489 : : {
490 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
491 : 0 : goto err;
492 : : }
493 : :
494 [ - + ]: 337 : if ((point = EC_POINT_new(group)) == NULL)
495 : : {
496 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
497 : 0 : goto err;
498 : : }
499 [ - + ]: 337 : if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
500 : : {
501 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
502 : 0 : goto err;
503 : : }
504 [ + + ]: 337 : if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
505 : : {
506 [ - + ]: 167 : if (!EC_POINT_get_affine_coordinates_GFp(group,
507 : : point, X, NULL, ctx))
508 : : {
509 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
510 : 0 : goto err;
511 : : }
512 : : }
513 : : #ifndef OPENSSL_NO_EC2M
514 : : else /* NID_X9_62_characteristic_two_field */
515 : : {
516 [ - + ]: 170 : if (!EC_POINT_get_affine_coordinates_GF2m(group,
517 : : point, X, NULL, ctx))
518 : : {
519 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
520 : 0 : goto err;
521 : : }
522 : : }
523 : : #endif
524 [ - + ]: 337 : if (!BN_nnmod(u1, X, order, ctx))
525 : : {
526 : 0 : ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
527 : 0 : goto err;
528 : : }
529 : : /* if the signature is correct u1 is equal to sig->r */
530 : 337 : ret = (BN_ucmp(u1, sig->r) == 0);
531 : : err:
532 : 339 : BN_CTX_end(ctx);
533 : 339 : BN_CTX_free(ctx);
534 [ + + ]: 339 : if (point)
535 : 337 : EC_POINT_free(point);
536 : 339 : return ret;
537 : : }
538 : :
539 : : #ifdef OPENSSL_FIPSCANISTER
540 : : /* FIPS stanadlone version of ecdsa_check: just return FIPS method */
541 : : ECDSA_DATA *fips_ecdsa_check(EC_KEY *key)
542 : : {
543 : : static ECDSA_DATA rv = {
544 : : 0,0,0,
545 : : &openssl_ecdsa_meth
546 : : };
547 : : return &rv;
548 : : }
549 : : /* Standalone digest sign and verify */
550 : : int FIPS_ecdsa_verify_digest(EC_KEY *key,
551 : : const unsigned char *dig, int dlen, ECDSA_SIG *s)
552 : : {
553 : : ECDSA_DATA *ecdsa = ecdsa_check(key);
554 : : if (ecdsa == NULL)
555 : : return 0;
556 : : return ecdsa->meth->ecdsa_do_verify(dig, dlen, s, key);
557 : : }
558 : : ECDSA_SIG * FIPS_ecdsa_sign_digest(EC_KEY *key,
559 : : const unsigned char *dig, int dlen)
560 : : {
561 : : ECDSA_DATA *ecdsa = ecdsa_check(key);
562 : : if (ecdsa == NULL)
563 : : return NULL;
564 : : return ecdsa->meth->ecdsa_do_sign(dig, dlen, NULL, NULL, key);
565 : : }
566 : : #endif
|