xref: /openbsd-src/lib/libcrypto/ecdsa/ecdsa.c (revision 6454157e90145eed221e43e6ee0c7eef925c68ee)
1*6454157eStb /* $OpenBSD: ecdsa.c,v 1.19 2024/04/15 15:49:37 tb Exp $ */
2b4a65d29Stb /* ====================================================================
3b4a65d29Stb  * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
4b4a65d29Stb  *
5b4a65d29Stb  * Redistribution and use in source and binary forms, with or without
6b4a65d29Stb  * modification, are permitted provided that the following conditions
7b4a65d29Stb  * are met:
8b4a65d29Stb  *
9b4a65d29Stb  * 1. Redistributions of source code must retain the above copyright
10b4a65d29Stb  *    notice, this list of conditions and the following disclaimer.
11b4a65d29Stb  *
12b4a65d29Stb  * 2. Redistributions in binary form must reproduce the above copyright
13b4a65d29Stb  *    notice, this list of conditions and the following disclaimer in
14b4a65d29Stb  *    the documentation and/or other materials provided with the
15b4a65d29Stb  *    distribution.
16b4a65d29Stb  *
17b4a65d29Stb  * 3. All advertising materials mentioning features or use of this
18b4a65d29Stb  *    software must display the following acknowledgment:
19b4a65d29Stb  *    "This product includes software developed by the OpenSSL Project
20b4a65d29Stb  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21b4a65d29Stb  *
22b4a65d29Stb  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23b4a65d29Stb  *    endorse or promote products derived from this software without
24b4a65d29Stb  *    prior written permission. For written permission, please contact
25b4a65d29Stb  *    licensing@OpenSSL.org.
26b4a65d29Stb  *
27b4a65d29Stb  * 5. Products derived from this software may not be called "OpenSSL"
28b4a65d29Stb  *    nor may "OpenSSL" appear in their names without prior written
29b4a65d29Stb  *    permission of the OpenSSL Project.
30b4a65d29Stb  *
31b4a65d29Stb  * 6. Redistributions of any form whatsoever must retain the following
32b4a65d29Stb  *    acknowledgment:
33b4a65d29Stb  *    "This product includes software developed by the OpenSSL Project
34b4a65d29Stb  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35b4a65d29Stb  *
36b4a65d29Stb  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37b4a65d29Stb  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38b4a65d29Stb  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39b4a65d29Stb  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40b4a65d29Stb  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41b4a65d29Stb  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42b4a65d29Stb  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43b4a65d29Stb  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44b4a65d29Stb  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45b4a65d29Stb  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46b4a65d29Stb  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47b4a65d29Stb  * OF THE POSSIBILITY OF SUCH DAMAGE.
48b4a65d29Stb  * ====================================================================
49b4a65d29Stb  *
50b4a65d29Stb  * This product includes cryptographic software written by Eric Young
51b4a65d29Stb  * (eay@cryptsoft.com).  This product includes software written by Tim
52b4a65d29Stb  * Hudson (tjh@cryptsoft.com).
53b4a65d29Stb  *
54b4a65d29Stb  */
55b4a65d29Stb 
565e179de8Stb #include <stddef.h>
575e179de8Stb #include <stdlib.h>
58b4a65d29Stb #include <string.h>
59b4a65d29Stb 
605e179de8Stb #include <openssl/asn1.h>
61b4a65d29Stb #include <openssl/asn1t.h>
62b4a65d29Stb #include <openssl/bn.h>
635e179de8Stb #include <openssl/ec.h>
64b4a65d29Stb #include <openssl/err.h>
65b4a65d29Stb 
66b4a65d29Stb #include "bn_local.h"
67b4a65d29Stb #include "ec_local.h"
68b4a65d29Stb #include "ecdsa_local.h"
69b4a65d29Stb 
70b4a65d29Stb static const ASN1_TEMPLATE ECDSA_SIG_seq_tt[] = {
71b4a65d29Stb 	{
72b4a65d29Stb 		.flags = 0,
73b4a65d29Stb 		.tag = 0,
74b4a65d29Stb 		.offset = offsetof(ECDSA_SIG, r),
75b4a65d29Stb 		.field_name = "r",
76b4a65d29Stb 		.item = &BIGNUM_it,
77b4a65d29Stb 	},
78b4a65d29Stb 	{
79b4a65d29Stb 		.flags = 0,
80b4a65d29Stb 		.tag = 0,
81b4a65d29Stb 		.offset = offsetof(ECDSA_SIG, s),
82b4a65d29Stb 		.field_name = "s",
83b4a65d29Stb 		.item = &BIGNUM_it,
84b4a65d29Stb 	},
85b4a65d29Stb };
86b4a65d29Stb 
87*6454157eStb static const ASN1_ITEM ECDSA_SIG_it = {
88b4a65d29Stb 	.itype = ASN1_ITYPE_SEQUENCE,
89b4a65d29Stb 	.utype = V_ASN1_SEQUENCE,
90b4a65d29Stb 	.templates = ECDSA_SIG_seq_tt,
91b4a65d29Stb 	.tcount = sizeof(ECDSA_SIG_seq_tt) / sizeof(ASN1_TEMPLATE),
92b4a65d29Stb 	.funcs = NULL,
93b4a65d29Stb 	.size = sizeof(ECDSA_SIG),
94b4a65d29Stb 	.sname = "ECDSA_SIG",
95b4a65d29Stb };
96b4a65d29Stb 
97b4a65d29Stb ECDSA_SIG *
d2i_ECDSA_SIG(ECDSA_SIG ** a,const unsigned char ** in,long len)98b4a65d29Stb d2i_ECDSA_SIG(ECDSA_SIG **a, const unsigned char **in, long len)
99b4a65d29Stb {
100b4a65d29Stb 	return (ECDSA_SIG *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
101b4a65d29Stb 	    &ECDSA_SIG_it);
102b4a65d29Stb }
103ea2baf45Sbeck LCRYPTO_ALIAS(d2i_ECDSA_SIG);
104b4a65d29Stb 
105b4a65d29Stb int
i2d_ECDSA_SIG(const ECDSA_SIG * a,unsigned char ** out)106b4a65d29Stb i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **out)
107b4a65d29Stb {
108b4a65d29Stb 	return ASN1_item_i2d((ASN1_VALUE *)a, out, &ECDSA_SIG_it);
109b4a65d29Stb }
110ea2baf45Sbeck LCRYPTO_ALIAS(i2d_ECDSA_SIG);
111b4a65d29Stb 
112b4a65d29Stb ECDSA_SIG *
ECDSA_SIG_new(void)113b4a65d29Stb ECDSA_SIG_new(void)
114b4a65d29Stb {
115b4a65d29Stb 	return (ECDSA_SIG *)ASN1_item_new(&ECDSA_SIG_it);
116b4a65d29Stb }
117ea2baf45Sbeck LCRYPTO_ALIAS(ECDSA_SIG_new);
118b4a65d29Stb 
119b4a65d29Stb void
ECDSA_SIG_free(ECDSA_SIG * a)120b4a65d29Stb ECDSA_SIG_free(ECDSA_SIG *a)
121b4a65d29Stb {
122b4a65d29Stb 	ASN1_item_free((ASN1_VALUE *)a, &ECDSA_SIG_it);
123b4a65d29Stb }
124ea2baf45Sbeck LCRYPTO_ALIAS(ECDSA_SIG_free);
125b4a65d29Stb 
126b4a65d29Stb void
ECDSA_SIG_get0(const ECDSA_SIG * sig,const BIGNUM ** pr,const BIGNUM ** ps)127b4a65d29Stb ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
128b4a65d29Stb {
129b4a65d29Stb 	if (pr != NULL)
130b4a65d29Stb 		*pr = sig->r;
131b4a65d29Stb 	if (ps != NULL)
132b4a65d29Stb 		*ps = sig->s;
133b4a65d29Stb }
134ea2baf45Sbeck LCRYPTO_ALIAS(ECDSA_SIG_get0);
135b4a65d29Stb 
136b4a65d29Stb const BIGNUM *
ECDSA_SIG_get0_r(const ECDSA_SIG * sig)137b4a65d29Stb ECDSA_SIG_get0_r(const ECDSA_SIG *sig)
138b4a65d29Stb {
139b4a65d29Stb 	return sig->r;
140b4a65d29Stb }
141ea2baf45Sbeck LCRYPTO_ALIAS(ECDSA_SIG_get0_r);
142b4a65d29Stb 
143b4a65d29Stb const BIGNUM *
ECDSA_SIG_get0_s(const ECDSA_SIG * sig)144b4a65d29Stb ECDSA_SIG_get0_s(const ECDSA_SIG *sig)
145b4a65d29Stb {
146b4a65d29Stb 	return sig->s;
147b4a65d29Stb }
148ea2baf45Sbeck LCRYPTO_ALIAS(ECDSA_SIG_get0_s);
149b4a65d29Stb 
150b4a65d29Stb int
ECDSA_SIG_set0(ECDSA_SIG * sig,BIGNUM * r,BIGNUM * s)151b4a65d29Stb ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
152b4a65d29Stb {
153b4a65d29Stb 	if (r == NULL || s == NULL)
154b4a65d29Stb 		return 0;
155b4a65d29Stb 
156b4a65d29Stb 	BN_free(sig->r);
157b4a65d29Stb 	BN_free(sig->s);
158b4a65d29Stb 	sig->r = r;
159b4a65d29Stb 	sig->s = s;
160b4a65d29Stb 	return 1;
161b4a65d29Stb }
162ea2baf45Sbeck LCRYPTO_ALIAS(ECDSA_SIG_set0);
163b4a65d29Stb 
164c0ee283eStb int
ECDSA_size(const EC_KEY * key)165e8c98450Stb ECDSA_size(const EC_KEY *key)
166c0ee283eStb {
167c0ee283eStb 	const EC_GROUP *group;
168c0ee283eStb 	const BIGNUM *order = NULL;
169c0ee283eStb 	ECDSA_SIG sig;
170c0ee283eStb 	int ret = 0;
171c0ee283eStb 
172e8c98450Stb 	if (key == NULL)
173c0ee283eStb 		goto err;
174c0ee283eStb 
175e8c98450Stb 	if ((group = EC_KEY_get0_group(key)) == NULL)
176c0ee283eStb 		goto err;
177c0ee283eStb 
178c0ee283eStb 	if ((order = EC_GROUP_get0_order(group)) == NULL)
179c0ee283eStb 		goto err;
180c0ee283eStb 
181c0ee283eStb 	sig.r = (BIGNUM *)order;
182c0ee283eStb 	sig.s = (BIGNUM *)order;
183c0ee283eStb 
184c0ee283eStb 	if ((ret = i2d_ECDSA_SIG(&sig, NULL)) < 0)
185c0ee283eStb 		ret = 0;
186c0ee283eStb 
187c0ee283eStb  err:
188c0ee283eStb 	return ret;
189c0ee283eStb }
190ea2baf45Sbeck LCRYPTO_ALIAS(ECDSA_size);
191c0ee283eStb 
192b4a65d29Stb /*
193b4a65d29Stb  * FIPS 186-5, section 6.4.1, step 2: convert hashed message into an integer.
194b4a65d29Stb  * Use the order_bits leftmost bits if it exceeds the group order.
195b4a65d29Stb  */
196b4a65d29Stb static int
ecdsa_prepare_digest(const unsigned char * digest,int digest_len,const EC_KEY * key,BIGNUM * e)197b4a65d29Stb ecdsa_prepare_digest(const unsigned char *digest, int digest_len,
198b4a65d29Stb     const EC_KEY *key, BIGNUM *e)
199b4a65d29Stb {
200b4a65d29Stb 	const EC_GROUP *group;
201b4a65d29Stb 	int digest_bits, order_bits;
202b4a65d29Stb 
203bd6cba7cStb 	if (BN_bin2bn(digest, digest_len, e) == NULL) {
20470458be1Stb 		ECerror(ERR_R_BN_LIB);
205b4a65d29Stb 		return 0;
206b4a65d29Stb 	}
207b4a65d29Stb 
208b4a65d29Stb 	if ((group = EC_KEY_get0_group(key)) == NULL)
209b4a65d29Stb 		return 0;
210b4a65d29Stb 	order_bits = EC_GROUP_order_bits(group);
211b4a65d29Stb 
212b4a65d29Stb 	digest_bits = 8 * digest_len;
213b4a65d29Stb 	if (digest_bits <= order_bits)
214b4a65d29Stb 		return 1;
215b4a65d29Stb 
216b4a65d29Stb 	return BN_rshift(e, e, digest_bits - order_bits);
217b4a65d29Stb }
218b4a65d29Stb 
219b4a65d29Stb int
ecdsa_sign(int type,const unsigned char * digest,int digest_len,unsigned char * signature,unsigned int * signature_len,const BIGNUM * kinv,const BIGNUM * r,EC_KEY * key)220b4a65d29Stb ecdsa_sign(int type, const unsigned char *digest, int digest_len,
221b4a65d29Stb     unsigned char *signature, unsigned int *signature_len, const BIGNUM *kinv,
222b4a65d29Stb     const BIGNUM *r, EC_KEY *key)
223b4a65d29Stb {
22429f18d75Stb 	ECDSA_SIG *sig = NULL;
225b4a65d29Stb 	int out_len = 0;
226b4a65d29Stb 	int ret = 0;
227b4a65d29Stb 
22829f18d75Stb 	if (kinv != NULL || r != NULL) {
22929f18d75Stb 		ECerror(EC_R_NOT_IMPLEMENTED);
23029f18d75Stb 		goto err;
23129f18d75Stb 	}
23229f18d75Stb 
23329f18d75Stb 	if ((sig = ECDSA_do_sign(digest, digest_len, key)) == NULL)
234b4a65d29Stb 		goto err;
235b4a65d29Stb 
236b4a65d29Stb 	if ((out_len = i2d_ECDSA_SIG(sig, &signature)) < 0) {
237b4a65d29Stb 		out_len = 0;
238b4a65d29Stb 		goto err;
239b4a65d29Stb 	}
240b4a65d29Stb 
241b4a65d29Stb 	ret = 1;
242b4a65d29Stb 
243b4a65d29Stb  err:
244b4a65d29Stb 	*signature_len = out_len;
245b4a65d29Stb 	ECDSA_SIG_free(sig);
246b4a65d29Stb 
247b4a65d29Stb 	return ret;
248b4a65d29Stb }
249b4a65d29Stb 
250218661deStb int
ECDSA_sign(int type,const unsigned char * digest,int digest_len,unsigned char * signature,unsigned int * signature_len,EC_KEY * key)251218661deStb ECDSA_sign(int type, const unsigned char *digest, int digest_len,
252218661deStb     unsigned char *signature, unsigned int *signature_len, EC_KEY *key)
253218661deStb {
254218661deStb 	if (key->meth->sign == NULL) {
255218661deStb 		ECerror(EC_R_NOT_IMPLEMENTED);
256218661deStb 		return 0;
257218661deStb 	}
258218661deStb 	return key->meth->sign(type, digest, digest_len, signature,
259218661deStb 	    signature_len, NULL, NULL, key);
260218661deStb }
261218661deStb LCRYPTO_ALIAS(ECDSA_sign);
262218661deStb 
263b4a65d29Stb /*
264b4a65d29Stb  * FIPS 186-5, section 6.4.1, steps 3-8 and 11: Generate k, calculate r and
265682ba1ecStb  * kinv. If r == 0, try again with a new random k.
266b4a65d29Stb  */
267b4a65d29Stb 
268b4a65d29Stb int
ecdsa_sign_setup(EC_KEY * key,BN_CTX * in_ctx,BIGNUM ** out_kinv,BIGNUM ** out_r)269b4a65d29Stb ecdsa_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv, BIGNUM **out_r)
270b4a65d29Stb {
271b4a65d29Stb 	const EC_GROUP *group;
272b4a65d29Stb 	EC_POINT *point = NULL;
273b4a65d29Stb 	BN_CTX *ctx = NULL;
274b4a65d29Stb 	BIGNUM *k = NULL, *r = NULL;
275b4a65d29Stb 	const BIGNUM *order;
276b4a65d29Stb 	BIGNUM *x;
277b4a65d29Stb 	int order_bits;
278b4a65d29Stb 	int ret = 0;
279b4a65d29Stb 
280b4a65d29Stb 	BN_free(*out_kinv);
281b4a65d29Stb 	*out_kinv = NULL;
282b4a65d29Stb 
283b4a65d29Stb 	BN_free(*out_r);
284b4a65d29Stb 	*out_r = NULL;
285b4a65d29Stb 
286b4a65d29Stb 	if (key == NULL) {
2874f33f08fStb 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
288b4a65d29Stb 		goto err;
289b4a65d29Stb 	}
290b4a65d29Stb 	if ((group = EC_KEY_get0_group(key)) == NULL) {
2914f33f08fStb 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
292b4a65d29Stb 		goto err;
293b4a65d29Stb 	}
294b4a65d29Stb 
295b4a65d29Stb 	if ((k = BN_new()) == NULL)
296b4a65d29Stb 		goto err;
297b4a65d29Stb 	if ((r = BN_new()) == NULL)
298b4a65d29Stb 		goto err;
299b4a65d29Stb 
300b4a65d29Stb 	if ((ctx = in_ctx) == NULL)
301b4a65d29Stb 		ctx = BN_CTX_new();
302b4a65d29Stb 	if (ctx == NULL) {
3034f33f08fStb 		ECerror(ERR_R_MALLOC_FAILURE);
304b4a65d29Stb 		goto err;
305b4a65d29Stb 	}
306b4a65d29Stb 
307b4a65d29Stb 	BN_CTX_start(ctx);
308b4a65d29Stb 
309b4a65d29Stb 	if ((x = BN_CTX_get(ctx)) == NULL)
310b4a65d29Stb 		goto err;
311b4a65d29Stb 
312b4a65d29Stb 	if ((point = EC_POINT_new(group)) == NULL) {
3134f33f08fStb 		ECerror(ERR_R_EC_LIB);
314b4a65d29Stb 		goto err;
315b4a65d29Stb 	}
316b4a65d29Stb 	if ((order = EC_GROUP_get0_order(group)) == NULL) {
3174f33f08fStb 		ECerror(ERR_R_EC_LIB);
318b4a65d29Stb 		goto err;
319b4a65d29Stb 	}
320b4a65d29Stb 
321b4a65d29Stb 	if (BN_cmp(order, BN_value_one()) <= 0) {
3224f33f08fStb 		ECerror(EC_R_INVALID_GROUP_ORDER);
323b4a65d29Stb 		goto err;
324b4a65d29Stb 	}
325b4a65d29Stb 
326b4a65d29Stb 	/* Reject curves with an order that is smaller than 80 bits. */
327b4a65d29Stb 	if ((order_bits = BN_num_bits(order)) < 80) {
3284f33f08fStb 		ECerror(EC_R_INVALID_GROUP_ORDER);
329b4a65d29Stb 		goto err;
330b4a65d29Stb 	}
331b4a65d29Stb 
332b4a65d29Stb 	/* Preallocate space. */
333b4a65d29Stb 	if (!BN_set_bit(k, order_bits) ||
334b4a65d29Stb 	    !BN_set_bit(r, order_bits) ||
335b4a65d29Stb 	    !BN_set_bit(x, order_bits))
336b4a65d29Stb 		goto err;
337b4a65d29Stb 
338b4a65d29Stb 	/* Step 11: repeat until r != 0. */
339b4a65d29Stb 	do {
340b4a65d29Stb 		/* Step 3: generate random k. */
34112347e81Stb 		if (!bn_rand_interval(k, 1, order))
342b4a65d29Stb 			goto err;
343b4a65d29Stb 
344b4a65d29Stb 		/* Step 5: P = k * G. */
345b4a65d29Stb 		if (!EC_POINT_mul(group, point, k, NULL, NULL, ctx)) {
3464f33f08fStb 			ECerror(ERR_R_EC_LIB);
347b4a65d29Stb 			goto err;
348b4a65d29Stb 		}
349b4a65d29Stb 		/* Steps 6 (and 7): from P = (x, y) retain the x-coordinate. */
350b4a65d29Stb 		if (!EC_POINT_get_affine_coordinates(group, point, x, NULL,
351b4a65d29Stb 		    ctx)) {
3524f33f08fStb 			ECerror(ERR_R_EC_LIB);
353b4a65d29Stb 			goto err;
354b4a65d29Stb 		}
355b4a65d29Stb 		/* Step 8: r = x (mod order). */
356b4a65d29Stb 		if (!BN_nnmod(r, x, order, ctx)) {
3574f33f08fStb 			ECerror(ERR_R_BN_LIB);
358b4a65d29Stb 			goto err;
359b4a65d29Stb 		}
360b4a65d29Stb 	} while (BN_is_zero(r));
361b4a65d29Stb 
362b4a65d29Stb 	/* Step 4: calculate kinv. */
363b4a65d29Stb 	if (BN_mod_inverse_ct(k, k, order, ctx) == NULL) {
3644f33f08fStb 		ECerror(ERR_R_BN_LIB);
365b4a65d29Stb 		goto err;
366b4a65d29Stb 	}
367b4a65d29Stb 
368b4a65d29Stb 	*out_kinv = k;
369b4a65d29Stb 	k = NULL;
370b4a65d29Stb 
371b4a65d29Stb 	*out_r = r;
372b4a65d29Stb 	r = NULL;
373b4a65d29Stb 
374b4a65d29Stb 	ret = 1;
375b4a65d29Stb 
376b4a65d29Stb  err:
377b4a65d29Stb 	BN_CTX_end(ctx);
378b4a65d29Stb 	if (ctx != in_ctx)
379b4a65d29Stb 		BN_CTX_free(ctx);
380b4a65d29Stb 	BN_free(k);
381b4a65d29Stb 	BN_free(r);
382b4a65d29Stb 	EC_POINT_free(point);
383b4a65d29Stb 
384b4a65d29Stb 	return ret;
385b4a65d29Stb }
386b4a65d29Stb 
387218661deStb static int
ECDSA_sign_setup(EC_KEY * key,BN_CTX * in_ctx,BIGNUM ** out_kinv,BIGNUM ** out_r)388218661deStb ECDSA_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv,
389218661deStb     BIGNUM **out_r)
390218661deStb {
391218661deStb 	if (key->meth->sign_setup == NULL) {
392218661deStb 		ECerror(EC_R_NOT_IMPLEMENTED);
393218661deStb 		return 0;
394218661deStb 	}
395218661deStb 	return key->meth->sign_setup(key, in_ctx, out_kinv, out_r);
396218661deStb }
397218661deStb 
398b4a65d29Stb /*
399b4a65d29Stb  * FIPS 186-5, section 6.4.1, step 9: compute s = inv(k)(e + xr) mod order.
400b4a65d29Stb  * In order to reduce the possibility of a side-channel attack, the following
401b4a65d29Stb  * is calculated using a random blinding value b in [1, order):
402b4a65d29Stb  * s = inv(b)(be + bxr)inv(k) mod order.
403b4a65d29Stb  */
404b4a65d29Stb 
405b4a65d29Stb static int
ecdsa_compute_s(BIGNUM ** out_s,const BIGNUM * e,const BIGNUM * kinv,const BIGNUM * r,const EC_KEY * key,BN_CTX * ctx)406b4a65d29Stb ecdsa_compute_s(BIGNUM **out_s, const BIGNUM *e, const BIGNUM *kinv,
407b4a65d29Stb     const BIGNUM *r, const EC_KEY *key, BN_CTX *ctx)
408b4a65d29Stb {
409b4a65d29Stb 	const EC_GROUP *group;
410b4a65d29Stb 	const BIGNUM *order, *priv_key;
411b4a65d29Stb 	BIGNUM *b, *binv, *be, *bxr;
412b4a65d29Stb 	BIGNUM *s = NULL;
413b4a65d29Stb 	int ret = 0;
414b4a65d29Stb 
415b4a65d29Stb 	*out_s = NULL;
416b4a65d29Stb 
417b4a65d29Stb 	BN_CTX_start(ctx);
418b4a65d29Stb 
419b4a65d29Stb 	if ((group = EC_KEY_get0_group(key)) == NULL) {
4204f33f08fStb 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
421b4a65d29Stb 		goto err;
422b4a65d29Stb 	}
423b4a65d29Stb 	if ((order = EC_GROUP_get0_order(group)) == NULL) {
4244f33f08fStb 		ECerror(ERR_R_EC_LIB);
425b4a65d29Stb 		goto err;
426b4a65d29Stb 	}
427b4a65d29Stb 	if ((priv_key = EC_KEY_get0_private_key(key)) == NULL) {
4284f33f08fStb 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
429b4a65d29Stb 		goto err;
430b4a65d29Stb 	}
431b4a65d29Stb 
432b4a65d29Stb 	if ((b = BN_CTX_get(ctx)) == NULL)
433b4a65d29Stb 		goto err;
434b4a65d29Stb 	if ((binv = BN_CTX_get(ctx)) == NULL)
435b4a65d29Stb 		goto err;
436b4a65d29Stb 	if ((be = BN_CTX_get(ctx)) == NULL)
437b4a65d29Stb 		goto err;
438b4a65d29Stb 	if ((bxr = BN_CTX_get(ctx)) == NULL)
439b4a65d29Stb 		goto err;
440b4a65d29Stb 
441b4a65d29Stb 	if ((s = BN_new()) == NULL)
442b4a65d29Stb 		goto err;
443b4a65d29Stb 
444b4a65d29Stb 	/*
445b4a65d29Stb 	 * In a valid ECDSA signature, r must be in [1, order). Since r can be
446b4a65d29Stb 	 * caller provided - either directly or by replacing sign_setup() - we
447b4a65d29Stb 	 * can't rely on this being the case.
448b4a65d29Stb 	 */
449b4a65d29Stb 	if (BN_cmp(r, BN_value_one()) < 0 || BN_cmp(r, order) >= 0) {
4501c55417bStb 		ECerror(EC_R_BAD_SIGNATURE);
451b4a65d29Stb 		goto err;
452b4a65d29Stb 	}
453b4a65d29Stb 
45412347e81Stb 	if (!bn_rand_interval(b, 1, order)) {
4554f33f08fStb 		ECerror(ERR_R_BN_LIB);
456b4a65d29Stb 		goto err;
457b4a65d29Stb 	}
458b4a65d29Stb 
459b4a65d29Stb 	if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) {
4604f33f08fStb 		ECerror(ERR_R_BN_LIB);
461b4a65d29Stb 		goto err;
462b4a65d29Stb 	}
463b4a65d29Stb 
464b4a65d29Stb 	if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) {
4654f33f08fStb 		ECerror(ERR_R_BN_LIB);
466b4a65d29Stb 		goto err;
467b4a65d29Stb 	}
468b4a65d29Stb 	if (!BN_mod_mul(bxr, bxr, r, order, ctx)) {
4694f33f08fStb 		ECerror(ERR_R_BN_LIB);
470b4a65d29Stb 		goto err;
471b4a65d29Stb 	}
472b4a65d29Stb 	if (!BN_mod_mul(be, b, e, order, ctx)) {
4734f33f08fStb 		ECerror(ERR_R_BN_LIB);
474b4a65d29Stb 		goto err;
475b4a65d29Stb 	}
476b4a65d29Stb 	if (!BN_mod_add(s, be, bxr, order, ctx)) {
4774f33f08fStb 		ECerror(ERR_R_BN_LIB);
478b4a65d29Stb 		goto err;
479b4a65d29Stb 	}
480b4a65d29Stb 	/* s = b(e + xr)k^-1 */
481b4a65d29Stb 	if (!BN_mod_mul(s, s, kinv, order, ctx)) {
4824f33f08fStb 		ECerror(ERR_R_BN_LIB);
483b4a65d29Stb 		goto err;
484b4a65d29Stb 	}
485b4a65d29Stb 	/* s = (e + xr)k^-1 */
486b4a65d29Stb 	if (!BN_mod_mul(s, s, binv, order, ctx)) {
4874f33f08fStb 		ECerror(ERR_R_BN_LIB);
488b4a65d29Stb 		goto err;
489b4a65d29Stb 	}
490b4a65d29Stb 
491b4a65d29Stb 	/* Step 11: if s == 0 start over. */
492b4a65d29Stb 	if (!BN_is_zero(s)) {
493b4a65d29Stb 		*out_s = s;
494b4a65d29Stb 		s = NULL;
495b4a65d29Stb 	}
496b4a65d29Stb 
497b4a65d29Stb 	ret = 1;
498b4a65d29Stb 
499b4a65d29Stb  err:
500b4a65d29Stb 	BN_CTX_end(ctx);
501b4a65d29Stb 	BN_free(s);
502b4a65d29Stb 
503b4a65d29Stb 	return ret;
504b4a65d29Stb }
505b4a65d29Stb 
506b4a65d29Stb /*
507b4a65d29Stb  * It is too expensive to check curve parameters on every sign operation.
508b4a65d29Stb  * Instead, cap the number of retries. A single retry is very unlikely, so
509b4a65d29Stb  * allowing 32 retries is amply enough.
510b4a65d29Stb  */
511b4a65d29Stb #define ECDSA_MAX_SIGN_ITERATIONS		32
512b4a65d29Stb 
513b4a65d29Stb /*
514b4a65d29Stb  * FIPS 186-5: Section 6.4.1: ECDSA signature generation, steps 2-12.
515b4a65d29Stb  * The caller provides the hash of the message, thus performs step 1.
516b4a65d29Stb  * Step 10, zeroing k and kinv, is done by BN_free().
517b4a65d29Stb  */
518b4a65d29Stb 
519b4a65d29Stb ECDSA_SIG *
ecdsa_sign_sig(const unsigned char * digest,int digest_len,const BIGNUM * in_kinv,const BIGNUM * in_r,EC_KEY * key)520b4a65d29Stb ecdsa_sign_sig(const unsigned char *digest, int digest_len,
521b4a65d29Stb     const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *key)
522b4a65d29Stb {
523b4a65d29Stb 	BN_CTX *ctx = NULL;
524b4a65d29Stb 	BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
525b4a65d29Stb 	BIGNUM *e;
526b4a65d29Stb 	int attempts = 0;
527b4a65d29Stb 	ECDSA_SIG *sig = NULL;
528b4a65d29Stb 
52929f18d75Stb 	if (in_kinv != NULL || in_r != NULL) {
53029f18d75Stb 		ECerror(EC_R_NOT_IMPLEMENTED);
53129f18d75Stb 		goto err;
53229f18d75Stb 	}
53329f18d75Stb 
534b4a65d29Stb 	if ((ctx = BN_CTX_new()) == NULL) {
5354f33f08fStb 		ECerror(ERR_R_MALLOC_FAILURE);
536b4a65d29Stb 		goto err;
537b4a65d29Stb 	}
538b4a65d29Stb 
539b4a65d29Stb 	BN_CTX_start(ctx);
540b4a65d29Stb 
541b4a65d29Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
542b4a65d29Stb 		goto err;
543b4a65d29Stb 
544b4a65d29Stb 	/* Step 2: convert hash into an integer. */
545b4a65d29Stb 	if (!ecdsa_prepare_digest(digest, digest_len, key, e))
546b4a65d29Stb 		goto err;
547b4a65d29Stb 
548b4a65d29Stb 	do {
549b4a65d29Stb 		/* Steps 3-8: calculate kinv and r. */
550b4a65d29Stb 		if (!ECDSA_sign_setup(key, ctx, &kinv, &r)) {
5511c55417bStb 			ECerror(ERR_R_EC_LIB);
552b4a65d29Stb 			goto err;
553b4a65d29Stb 		}
554b4a65d29Stb 
555b4a65d29Stb 		/*
556b4a65d29Stb 		 * Steps 9 and 11: if s is non-NULL, we have a valid signature.
557b4a65d29Stb 		 */
558b4a65d29Stb 		if (!ecdsa_compute_s(&s, e, kinv, r, key, ctx))
559b4a65d29Stb 			goto err;
560b4a65d29Stb 		if (s != NULL)
561b4a65d29Stb 			break;
562b4a65d29Stb 
563b4a65d29Stb 		if (++attempts > ECDSA_MAX_SIGN_ITERATIONS) {
5644f33f08fStb 			ECerror(EC_R_WRONG_CURVE_PARAMETERS);
565b4a65d29Stb 			goto err;
566b4a65d29Stb 		}
567b4a65d29Stb 	} while (1);
568b4a65d29Stb 
569b4a65d29Stb 	/* Step 12: output (r, s). */
570b4a65d29Stb 	if ((sig = ECDSA_SIG_new()) == NULL) {
5714f33f08fStb 		ECerror(ERR_R_MALLOC_FAILURE);
572b4a65d29Stb 		goto err;
573b4a65d29Stb 	}
574b4a65d29Stb 	if (!ECDSA_SIG_set0(sig, r, s)) {
575b4a65d29Stb 		ECDSA_SIG_free(sig);
576b4a65d29Stb 		goto err;
577b4a65d29Stb 	}
578b4a65d29Stb 	r = NULL;
579b4a65d29Stb 	s = NULL;
580b4a65d29Stb 
581b4a65d29Stb  err:
582b4a65d29Stb 	BN_CTX_end(ctx);
583b4a65d29Stb 	BN_CTX_free(ctx);
584b4a65d29Stb 	BN_free(kinv);
585b4a65d29Stb 	BN_free(r);
586b4a65d29Stb 	BN_free(s);
587b4a65d29Stb 
588b4a65d29Stb 	return sig;
589b4a65d29Stb }
590b4a65d29Stb 
591218661deStb ECDSA_SIG *
ECDSA_do_sign(const unsigned char * digest,int digest_len,EC_KEY * key)592218661deStb ECDSA_do_sign(const unsigned char *digest, int digest_len, EC_KEY *key)
593218661deStb {
594218661deStb 	if (key->meth->sign_sig == NULL) {
595218661deStb 		ECerror(EC_R_NOT_IMPLEMENTED);
596218661deStb 		return 0;
597218661deStb 	}
598218661deStb 	return key->meth->sign_sig(digest, digest_len, NULL, NULL, key);
599218661deStb }
600218661deStb LCRYPTO_ALIAS(ECDSA_do_sign);
601218661deStb 
602b4a65d29Stb int
ecdsa_verify(int type,const unsigned char * digest,int digest_len,const unsigned char * sigbuf,int sig_len,EC_KEY * key)603b4a65d29Stb ecdsa_verify(int type, const unsigned char *digest, int digest_len,
604b4a65d29Stb     const unsigned char *sigbuf, int sig_len, EC_KEY *key)
605b4a65d29Stb {
606b4a65d29Stb 	ECDSA_SIG *s;
607b4a65d29Stb 	unsigned char *der = NULL;
608b4a65d29Stb 	const unsigned char *p;
609b4a65d29Stb 	int der_len = 0;
610b4a65d29Stb 	int ret = -1;
611b4a65d29Stb 
612b4a65d29Stb 	if ((s = ECDSA_SIG_new()) == NULL)
613b4a65d29Stb 		goto err;
614b4a65d29Stb 
615b4a65d29Stb 	p = sigbuf;
616b4a65d29Stb 	if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
617b4a65d29Stb 		goto err;
618b4a65d29Stb 
6192979b3a0Stb 	/* Ensure signature uses DER and doesn't have trailing garbage. */
620b4a65d29Stb 	if ((der_len = i2d_ECDSA_SIG(s, &der)) != sig_len)
621b4a65d29Stb 		goto err;
622b4a65d29Stb 	if (timingsafe_memcmp(sigbuf, der, der_len))
623b4a65d29Stb 		goto err;
624b4a65d29Stb 
625b4a65d29Stb 	ret = ECDSA_do_verify(digest, digest_len, s, key);
626b4a65d29Stb 
627b4a65d29Stb  err:
628b4a65d29Stb 	freezero(der, der_len);
629b4a65d29Stb 	ECDSA_SIG_free(s);
630b4a65d29Stb 
631b4a65d29Stb 	return ret;
632b4a65d29Stb }
633b4a65d29Stb 
634218661deStb int
ECDSA_verify(int type,const unsigned char * digest,int digest_len,const unsigned char * sigbuf,int sig_len,EC_KEY * key)635218661deStb ECDSA_verify(int type, const unsigned char *digest, int digest_len,
636218661deStb     const unsigned char *sigbuf, int sig_len, EC_KEY *key)
637218661deStb {
638218661deStb 	if (key->meth->verify == NULL) {
639218661deStb 		ECerror(EC_R_NOT_IMPLEMENTED);
640218661deStb 		return 0;
641218661deStb 	}
642218661deStb 	return key->meth->verify(type, digest, digest_len, sigbuf, sig_len, key);
643218661deStb }
644218661deStb LCRYPTO_ALIAS(ECDSA_verify);
645218661deStb 
646b4a65d29Stb /*
647b4a65d29Stb  * FIPS 186-5, section 6.4.2: ECDSA signature verification.
648b4a65d29Stb  * The caller provides us with the hash of the message, so has performed step 2.
649b4a65d29Stb  */
650b4a65d29Stb 
651b4a65d29Stb int
ecdsa_verify_sig(const unsigned char * digest,int digest_len,const ECDSA_SIG * sig,EC_KEY * key)652b4a65d29Stb ecdsa_verify_sig(const unsigned char *digest, int digest_len,
653b4a65d29Stb     const ECDSA_SIG *sig, EC_KEY *key)
654b4a65d29Stb {
655b4a65d29Stb 	const EC_GROUP *group;
656b4a65d29Stb 	const EC_POINT *pub_key;
657b4a65d29Stb 	EC_POINT *point = NULL;
658b4a65d29Stb 	const BIGNUM *order;
659b4a65d29Stb 	BN_CTX *ctx = NULL;
660b4a65d29Stb 	BIGNUM *e, *sinv, *u, *v, *x;
661b4a65d29Stb 	int ret = -1;
662b4a65d29Stb 
663b4a65d29Stb 	if (key == NULL || sig == NULL) {
6641c55417bStb 		ECerror(EC_R_MISSING_PARAMETERS);
665b4a65d29Stb 		goto err;
666b4a65d29Stb 	}
667b4a65d29Stb 	if ((group = EC_KEY_get0_group(key)) == NULL) {
6681c55417bStb 		ECerror(EC_R_MISSING_PARAMETERS);
669b4a65d29Stb 		goto err;
670b4a65d29Stb 	}
671b4a65d29Stb 	if ((pub_key = EC_KEY_get0_public_key(key)) == NULL) {
6721c55417bStb 		ECerror(EC_R_MISSING_PARAMETERS);
673b4a65d29Stb 		goto err;
674b4a65d29Stb 	}
675b4a65d29Stb 
676b4a65d29Stb 	if ((ctx = BN_CTX_new()) == NULL) {
6774f33f08fStb 		ECerror(ERR_R_MALLOC_FAILURE);
678b4a65d29Stb 		goto err;
679b4a65d29Stb 	}
680b4a65d29Stb 
681b4a65d29Stb 	BN_CTX_start(ctx);
682b4a65d29Stb 
683b4a65d29Stb 	if ((e = BN_CTX_get(ctx)) == NULL)
684b4a65d29Stb 		goto err;
685b4a65d29Stb 	if ((sinv = BN_CTX_get(ctx)) == NULL)
686b4a65d29Stb 		goto err;
687b4a65d29Stb 	if ((u = BN_CTX_get(ctx)) == NULL)
688b4a65d29Stb 		goto err;
689b4a65d29Stb 	if ((v = BN_CTX_get(ctx)) == NULL)
690b4a65d29Stb 		goto err;
691b4a65d29Stb 	if ((x = BN_CTX_get(ctx)) == NULL)
692b4a65d29Stb 		goto err;
693b4a65d29Stb 
694b4a65d29Stb 	if ((order = EC_GROUP_get0_order(group)) == NULL) {
6954f33f08fStb 		ECerror(ERR_R_EC_LIB);
696b4a65d29Stb 		goto err;
697b4a65d29Stb 	}
698b4a65d29Stb 
699b4a65d29Stb 	/* Step 1: verify that r and s are in the range [1, order). */
700b4a65d29Stb 	if (BN_cmp(sig->r, BN_value_one()) < 0 || BN_cmp(sig->r, order) >= 0) {
7011c55417bStb 		ECerror(EC_R_BAD_SIGNATURE);
702b4a65d29Stb 		ret = 0;
703b4a65d29Stb 		goto err;
704b4a65d29Stb 	}
705b4a65d29Stb 	if (BN_cmp(sig->s, BN_value_one()) < 0 || BN_cmp(sig->s, order) >= 0) {
7061c55417bStb 		ECerror(EC_R_BAD_SIGNATURE);
707b4a65d29Stb 		ret = 0;
708b4a65d29Stb 		goto err;
709b4a65d29Stb 	}
710b4a65d29Stb 
711b4a65d29Stb 	/* Step 3: convert the hash into an integer. */
712b4a65d29Stb 	if (!ecdsa_prepare_digest(digest, digest_len, key, e))
713b4a65d29Stb 		goto err;
714b4a65d29Stb 
715b4a65d29Stb 	/* Step 4: compute the inverse of s modulo order. */
716b4a65d29Stb 	if (BN_mod_inverse_ct(sinv, sig->s, order, ctx) == NULL) {
7174f33f08fStb 		ECerror(ERR_R_BN_LIB);
718b4a65d29Stb 		goto err;
719b4a65d29Stb 	}
720b4a65d29Stb 	/* Step 5: compute u = s^-1 * e and v = s^-1 * r (modulo order). */
721b4a65d29Stb 	if (!BN_mod_mul(u, e, sinv, order, ctx)) {
7224f33f08fStb 		ECerror(ERR_R_BN_LIB);
723b4a65d29Stb 		goto err;
724b4a65d29Stb 	}
725b4a65d29Stb 	if (!BN_mod_mul(v, sig->r, sinv, order, ctx)) {
7264f33f08fStb 		ECerror(ERR_R_BN_LIB);
727b4a65d29Stb 		goto err;
728b4a65d29Stb 	}
729b4a65d29Stb 
730b4a65d29Stb 	/*
731b4a65d29Stb 	 * Steps 6 and 7: compute R = G * u + pub_key * v = (x, y). Reject if
732b4a65d29Stb 	 * it's the point at infinity - getting affine coordinates fails. Keep
733b4a65d29Stb 	 * the x coordinate.
734b4a65d29Stb 	 */
735b4a65d29Stb 	if ((point = EC_POINT_new(group)) == NULL) {
7364f33f08fStb 		ECerror(ERR_R_MALLOC_FAILURE);
737b4a65d29Stb 		goto err;
738b4a65d29Stb 	}
739b4a65d29Stb 	if (!EC_POINT_mul(group, point, u, pub_key, v, ctx)) {
7404f33f08fStb 		ECerror(ERR_R_EC_LIB);
741b4a65d29Stb 		goto err;
742b4a65d29Stb 	}
743b4a65d29Stb 	if (!EC_POINT_get_affine_coordinates(group, point, x, NULL, ctx)) {
7444f33f08fStb 		ECerror(ERR_R_EC_LIB);
745b4a65d29Stb 		goto err;
746b4a65d29Stb 	}
747b4a65d29Stb 	/* Step 8: convert x to a number in [0, order). */
748b4a65d29Stb 	if (!BN_nnmod(x, x, order, ctx)) {
7494f33f08fStb 		ECerror(ERR_R_BN_LIB);
750b4a65d29Stb 		goto err;
751b4a65d29Stb 	}
752b4a65d29Stb 
753b4a65d29Stb 	/* Step 9: the signature is valid iff the x-coordinate is equal to r. */
754b4a65d29Stb 	ret = (BN_cmp(x, sig->r) == 0);
755b4a65d29Stb 
756b4a65d29Stb  err:
757b4a65d29Stb 	BN_CTX_end(ctx);
758b4a65d29Stb 	BN_CTX_free(ctx);
759b4a65d29Stb 	EC_POINT_free(point);
760b4a65d29Stb 
761b4a65d29Stb 	return ret;
762b4a65d29Stb }
763b4a65d29Stb 
764b4a65d29Stb int
ECDSA_do_verify(const unsigned char * digest,int digest_len,const ECDSA_SIG * sig,EC_KEY * key)765b4a65d29Stb ECDSA_do_verify(const unsigned char *digest, int digest_len,
766b4a65d29Stb     const ECDSA_SIG *sig, EC_KEY *key)
767b4a65d29Stb {
768b4a65d29Stb 	if (key->meth->verify_sig == NULL) {
7691c55417bStb 		ECerror(EC_R_NOT_IMPLEMENTED);
770b4a65d29Stb 		return 0;
771b4a65d29Stb 	}
772b4a65d29Stb 	return key->meth->verify_sig(digest, digest_len, sig, key);
773b4a65d29Stb }
774ea2baf45Sbeck LCRYPTO_ALIAS(ECDSA_do_verify);
775