]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/ecdsa/ecs_ossl.c
Add PRNG security strength checking.
[thirdparty/openssl.git] / crypto / ecdsa / ecs_ossl.c
CommitLineData
4d94ae00 1/* crypto/ecdsa/ecs_ossl.c */
c6700d27
GT
2/*
3 * Written by Nils Larsch for the OpenSSL project
4 */
4d94ae00 5/* ====================================================================
c6700d27 6 * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved.
4d94ae00
BM
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 */
0bee0e62 58
fe26d066
DSH
59#define OPENSSL_FIPSAPI
60
6a50d0a4 61#include "ecs_locl.h"
0bee0e62 62#include <openssl/err.h>
14a7cfb3 63#include <openssl/obj_mac.h>
0f814687 64#include <openssl/bn.h>
4d94ae00 65
14a7cfb3 66static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
9dd84053 67 const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
14a7cfb3
BM
68static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
69 BIGNUM **rp);
70static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
a0bee97e 71 const ECDSA_SIG *sig, EC_KEY *eckey);
4d94ae00
BM
72
73static ECDSA_METHOD openssl_ecdsa_meth = {
14a7cfb3
BM
74 "OpenSSL ECDSA method",
75 ecdsa_do_sign,
76 ecdsa_sign_setup,
77 ecdsa_do_verify,
78#if 0
79 NULL, /* init */
80 NULL, /* finish */
81#endif
82 0, /* flags */
83 NULL /* app_data */
4d94ae00
BM
84};
85
86const ECDSA_METHOD *ECDSA_OpenSSL(void)
87{
88 return &openssl_ecdsa_meth;
89}
90
14a7cfb3
BM
91static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
92 BIGNUM **rp)
4d94ae00
BM
93{
94 BN_CTX *ctx = NULL;
c6700d27 95 BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
4d94ae00 96 EC_POINT *tmp_point=NULL;
9dd84053 97 const EC_GROUP *group;
14a7cfb3 98 int ret = 0;
9dd84053
NL
99
100 if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
4d94ae00 101 {
14a7cfb3 102 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
4d94ae00
BM
103 return 0;
104 }
a74333f9 105
4d94ae00
BM
106 if (ctx_in == NULL)
107 {
c6700d27 108 if ((ctx = BN_CTX_new()) == NULL)
14a7cfb3 109 {
c6700d27
GT
110 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
111 return 0;
14a7cfb3 112 }
4d94ae00
BM
113 }
114 else
c6700d27 115 ctx = ctx_in;
4d94ae00 116
c6700d27
GT
117 k = BN_new(); /* this value is later returned in *kinvp */
118 r = BN_new(); /* this value is later returned in *rp */
119 order = BN_new();
120 X = BN_new();
121 if (!k || !r || !order || !X)
4d94ae00 122 {
c6700d27
GT
123 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
124 goto err;
14a7cfb3 125 }
c6700d27 126 if ((tmp_point = EC_POINT_new(group)) == NULL)
14a7cfb3
BM
127 {
128 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
4d94ae00
BM
129 goto err;
130 }
c6700d27 131 if (!EC_GROUP_get_order(group, order, ctx))
4d94ae00 132 {
14a7cfb3 133 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
4d94ae00
BM
134 goto err;
135 }
cac4fb58
DSH
136
137#ifdef OPENSSL_FIPS
138 if (!fips_check_ec_prng(eckey))
139 goto err;
140#endif
4d94ae00
BM
141
142 do
143 {
144 /* get random k */
4d94ae00 145 do
c6700d27 146 if (!BN_rand_range(k, order))
4d94ae00 147 {
14a7cfb3
BM
148 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
149 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
4d94ae00
BM
150 goto err;
151 }
c6700d27 152 while (BN_is_zero(k));
4d94ae00
BM
153
154 /* compute r the x-coordinate of generator * k */
c6700d27 155 if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
14a7cfb3
BM
156 {
157 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
158 goto err;
159 }
c6700d27 160 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
14a7cfb3 161 {
c6700d27 162 if (!EC_POINT_get_affine_coordinates_GFp(group,
14a7cfb3
BM
163 tmp_point, X, NULL, ctx))
164 {
c6700d27 165 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
14a7cfb3
BM
166 goto err;
167 }
168 }
b3310161 169#ifndef OPENSSL_NO_EC2M
14a7cfb3
BM
170 else /* NID_X9_62_characteristic_two_field */
171 {
c6700d27 172 if (!EC_POINT_get_affine_coordinates_GF2m(group,
14a7cfb3
BM
173 tmp_point, X, NULL, ctx))
174 {
c6700d27 175 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
14a7cfb3
BM
176 goto err;
177 }
178 }
b3310161 179#endif
c6700d27 180 if (!BN_nnmod(r, X, order, ctx))
4d94ae00 181 {
14a7cfb3 182 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
4d94ae00
BM
183 goto err;
184 }
4d94ae00
BM
185 }
186 while (BN_is_zero(r));
187
188 /* compute the inverse of k */
c6700d27 189 if (!BN_mod_inverse(k, k, order, ctx))
14a7cfb3
BM
190 {
191 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
192 goto err;
193 }
c6700d27
GT
194 /* clear old values if necessary */
195 if (*rp != NULL)
4d94ae00 196 BN_clear_free(*rp);
c6700d27 197 if (*kinvp != NULL)
4d94ae00 198 BN_clear_free(*kinvp);
c6700d27
GT
199 /* save the pre-computed values */
200 *rp = r;
201 *kinvp = k;
4d94ae00
BM
202 ret = 1;
203err:
204 if (!ret)
205 {
c6700d27 206 if (k != NULL) BN_clear_free(k);
4d94ae00
BM
207 if (r != NULL) BN_clear_free(r);
208 }
209 if (ctx_in == NULL)
210 BN_CTX_free(ctx);
4d94ae00 211 if (order != NULL)
c6700d27 212 BN_free(order);
4d94ae00
BM
213 if (tmp_point != NULL)
214 EC_POINT_free(tmp_point);
c6700d27
GT
215 if (X)
216 BN_clear_free(X);
4d94ae00
BM
217 return(ret);
218}
219
220
14a7cfb3 221static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
9dd84053 222 const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
4d94ae00 223{
606c46fb 224 int ok = 0, i;
9dd84053
NL
225 BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
226 const BIGNUM *ckinv;
c6700d27 227 BN_CTX *ctx = NULL;
9dd84053 228 const EC_GROUP *group;
c6700d27 229 ECDSA_SIG *ret;
14a7cfb3 230 ECDSA_DATA *ecdsa;
9dd84053 231 const BIGNUM *priv_key;
14a7cfb3 232
9dd84053
NL
233 ecdsa = ecdsa_check(eckey);
234 group = EC_KEY_get0_group(eckey);
235 priv_key = EC_KEY_get0_private_key(eckey);
236
237 if (group == NULL || priv_key == NULL || ecdsa == NULL)
4d94ae00 238 {
14a7cfb3 239 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
c6700d27 240 return NULL;
4d94ae00 241 }
4d94ae00 242
cac4fb58
DSH
243#ifdef OPENSSL_FIPS
244 if (!fips_check_ec_prng(eckey))
245 return NULL;
246#endif
247
c6700d27
GT
248 ret = ECDSA_SIG_new();
249 if (!ret)
250 {
251 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
252 return NULL;
253 }
254 s = ret->s;
255
14a7cfb3 256 if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
c6700d27 257 (tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
14a7cfb3
BM
258 {
259 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
260 goto err;
261 }
4d94ae00 262
c6700d27 263 if (!EC_GROUP_get_order(group, order, ctx))
4d94ae00 264 {
14a7cfb3 265 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
4d94ae00
BM
266 goto err;
267 }
606c46fb
DSH
268 i = BN_num_bits(order);
269 /* Need to truncate digest if it is too long: first truncate whole
270 * bytes.
271 */
272 if (8 * dgst_len > i)
273 dgst_len = (i + 7)/8;
274 if (!BN_bin2bn(dgst, dgst_len, m))
4d94ae00 275 {
606c46fb 276 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
4d94ae00
BM
277 goto err;
278 }
606c46fb
DSH
279 /* If still too long truncate remaining bits with a shift */
280 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
14a7cfb3
BM
281 {
282 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
283 goto err;
284 }
4d94ae00
BM
285 do
286 {
9dd84053 287 if (in_kinv == NULL || in_r == NULL)
4d94ae00 288 {
fe26d066
DSH
289 if (!ecdsa->meth->ecdsa_sign_setup(eckey, ctx,
290 &kinv, &ret->r))
14a7cfb3 291 {
c6700d27 292 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
14a7cfb3
BM
293 goto err;
294 }
9dd84053 295 ckinv = kinv;
4d94ae00
BM
296 }
297 else
298 {
9dd84053
NL
299 ckinv = in_kinv;
300 if (BN_copy(ret->r, in_r) == NULL)
301 {
302 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
303 goto err;
304 }
4d94ae00
BM
305 }
306
9dd84053 307 if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
14a7cfb3
BM
308 {
309 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
310 goto err;
311 }
c6700d27 312 if (!BN_mod_add_quick(s, tmp, m, order))
14a7cfb3
BM
313 {
314 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
315 goto err;
316 }
9dd84053 317 if (!BN_mod_mul(s, s, ckinv, order, ctx))
14a7cfb3
BM
318 {
319 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
320 goto err;
321 }
2fc281d0
NL
322 if (BN_is_zero(s))
323 {
324 /* if kinv and r have been supplied by the caller
325 * don't to generate new kinv and r values */
326 if (in_kinv != NULL && in_r != NULL)
327 {
328 ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
329 goto err;
330 }
331 }
332 else
333 /* s != 0 => we have a valid signature */
334 break;
4d94ae00 335 }
2fc281d0 336 while (1);
4d94ae00 337
c6700d27
GT
338 ok = 1;
339err:
340 if (!ok)
3613e6fc
BM
341 {
342 ECDSA_SIG_free(ret);
343 ret = NULL;
3613e6fc 344 }
14a7cfb3
BM
345 if (ctx)
346 BN_CTX_free(ctx);
347 if (m)
348 BN_clear_free(m);
349 if (tmp)
350 BN_clear_free(tmp);
351 if (order)
c6700d27 352 BN_free(order);
14a7cfb3
BM
353 if (kinv)
354 BN_clear_free(kinv);
c6700d27 355 return ret;
4d94ae00
BM
356}
357
14a7cfb3 358static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
a0bee97e 359 const ECDSA_SIG *sig, EC_KEY *eckey)
4d94ae00 360{
606c46fb 361 int ret = -1, i;
c6700d27
GT
362 BN_CTX *ctx;
363 BIGNUM *order, *u1, *u2, *m, *X;
364 EC_POINT *point = NULL;
9dd84053
NL
365 const EC_GROUP *group;
366 const EC_POINT *pub_key;
367
c6700d27 368 /* check input values */
9dd84053
NL
369 if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
370 (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
4d94ae00 371 {
14a7cfb3 372 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
4d94ae00
BM
373 return -1;
374 }
375
c6700d27
GT
376 ctx = BN_CTX_new();
377 if (!ctx)
14a7cfb3
BM
378 {
379 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
c6700d27 380 return -1;
14a7cfb3 381 }
c6700d27
GT
382 BN_CTX_start(ctx);
383 order = BN_CTX_get(ctx);
384 u1 = BN_CTX_get(ctx);
385 u2 = BN_CTX_get(ctx);
386 m = BN_CTX_get(ctx);
387 X = BN_CTX_get(ctx);
388 if (!X)
14a7cfb3
BM
389 {
390 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
391 goto err;
392 }
c6700d27
GT
393
394 if (!EC_GROUP_get_order(group, order, ctx))
4d94ae00 395 {
c6700d27 396 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
4d94ae00
BM
397 goto err;
398 }
c6700d27 399
ff22e913 400 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
c6700d27 401 BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
ff22e913 402 BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0)
4d94ae00 403 {
14a7cfb3 404 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
c6700d27 405 ret = 0; /* signature is invalid */
4d94ae00
BM
406 goto err;
407 }
4d94ae00 408 /* calculate tmp1 = inv(S) mod order */
c6700d27 409 if (!BN_mod_inverse(u2, sig->s, order, ctx))
14a7cfb3
BM
410 {
411 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
412 goto err;
413 }
4d94ae00 414 /* digest -> m */
606c46fb
DSH
415 i = BN_num_bits(order);
416 /* Need to truncate digest if it is too long: first truncate whole
417 * bytes.
418 */
419 if (8 * dgst_len > i)
420 dgst_len = (i + 7)/8;
c6700d27 421 if (!BN_bin2bn(dgst, dgst_len, m))
14a7cfb3
BM
422 {
423 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
424 goto err;
425 }
606c46fb
DSH
426 /* If still too long truncate remaining bits with a shift */
427 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
428 {
429 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
430 goto err;
431 }
4d94ae00 432 /* u1 = m * tmp mod order */
c6700d27 433 if (!BN_mod_mul(u1, m, u2, order, ctx))
14a7cfb3
BM
434 {
435 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
436 goto err;
437 }
4d94ae00 438 /* u2 = r * w mod q */
c6700d27 439 if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
14a7cfb3
BM
440 {
441 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
442 goto err;
443 }
4d94ae00 444
c6700d27 445 if ((point = EC_POINT_new(group)) == NULL)
4d94ae00 446 {
14a7cfb3 447 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
4d94ae00
BM
448 goto err;
449 }
9dd84053 450 if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
4d94ae00 451 {
14a7cfb3
BM
452 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
453 goto err;
454 }
c6700d27 455 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
14a7cfb3 456 {
c6700d27 457 if (!EC_POINT_get_affine_coordinates_GFp(group,
14a7cfb3
BM
458 point, X, NULL, ctx))
459 {
aa4ce731 460 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
14a7cfb3
BM
461 goto err;
462 }
463 }
b3310161 464#ifndef OPENSSL_NO_EC2M
14a7cfb3
BM
465 else /* NID_X9_62_characteristic_two_field */
466 {
c6700d27 467 if (!EC_POINT_get_affine_coordinates_GF2m(group,
14a7cfb3
BM
468 point, X, NULL, ctx))
469 {
aa4ce731 470 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
14a7cfb3
BM
471 goto err;
472 }
473 }
b3310161 474#endif
c6700d27 475 if (!BN_nnmod(u1, X, order, ctx))
14a7cfb3
BM
476 {
477 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
4d94ae00
BM
478 goto err;
479 }
c6700d27
GT
480 /* if the signature is correct u1 is equal to sig->r */
481 ret = (BN_ucmp(u1, sig->r) == 0);
482err:
483 BN_CTX_end(ctx);
484 BN_CTX_free(ctx);
14a7cfb3
BM
485 if (point)
486 EC_POINT_free(point);
c6700d27 487 return ret;
4d94ae00 488}
fe26d066
DSH
489
490#ifdef OPENSSL_FIPSCANISTER
491/* FIPS stanadlone version of ecdsa_check: just return FIPS method */
492ECDSA_DATA *fips_ecdsa_check(EC_KEY *key)
493 {
494 static ECDSA_DATA rv = {
495 0,0,0,
496 &openssl_ecdsa_meth
497 };
498 return &rv;
499 }
500/* Standalone digest sign and verify */
501int FIPS_ecdsa_verify_digest(EC_KEY *key,
502 const unsigned char *dig, int dlen, ECDSA_SIG *s)
503 {
504 ECDSA_DATA *ecdsa = ecdsa_check(key);
505 if (ecdsa == NULL)
506 return 0;
507 return ecdsa->meth->ecdsa_do_verify(dig, dlen, s, key);
508 }
509ECDSA_SIG * FIPS_ecdsa_sign_digest(EC_KEY *key,
510 const unsigned char *dig, int dlen)
511 {
512 ECDSA_DATA *ecdsa = ecdsa_check(key);
513 if (ecdsa == NULL)
514 return NULL;
515 return ecdsa->meth->ecdsa_do_sign(dig, dlen, NULL, NULL, key);
516 }
517#endif