xref: /freebsd/crypto/libecc/src/sig/sig_algs.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
1*f0865ec9SKyle Evans /*
2*f0865ec9SKyle Evans  *  Copyright (C) 2017 - This file is part of libecc project
3*f0865ec9SKyle Evans  *
4*f0865ec9SKyle Evans  *  Authors:
5*f0865ec9SKyle Evans  *	Ryad BENADJILA <ryadbenadjila@gmail.com>
6*f0865ec9SKyle Evans  *	Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7*f0865ec9SKyle Evans  *	Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
8*f0865ec9SKyle Evans  *
9*f0865ec9SKyle Evans  *  Contributors:
10*f0865ec9SKyle Evans  *	Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
11*f0865ec9SKyle Evans  *	Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
12*f0865ec9SKyle Evans  *
13*f0865ec9SKyle Evans  *  This software is licensed under a dual BSD and GPL v2 license.
14*f0865ec9SKyle Evans  *  See LICENSE file at the root folder of the project.
15*f0865ec9SKyle Evans  */
16*f0865ec9SKyle Evans #include <libecc/sig/sig_algs.h>
17*f0865ec9SKyle Evans 
18*f0865ec9SKyle Evans /*
19*f0865ec9SKyle Evans  * Generic private key generation (generate a scalar in ]0,q[
20*f0865ec9SKyle Evans  * Common accross many schemes, but might diverge for some.
21*f0865ec9SKyle Evans  */
generic_gen_priv_key(ec_priv_key * priv_key)22*f0865ec9SKyle Evans int generic_gen_priv_key(ec_priv_key *priv_key)
23*f0865ec9SKyle Evans {
24*f0865ec9SKyle Evans 	nn_src_t q;
25*f0865ec9SKyle Evans 	int ret;
26*f0865ec9SKyle Evans 
27*f0865ec9SKyle Evans 	ret = priv_key_check_initialized(priv_key); EG(ret, err);
28*f0865ec9SKyle Evans 
29*f0865ec9SKyle Evans 	q = &(priv_key->params->ec_gen_order);
30*f0865ec9SKyle Evans 
31*f0865ec9SKyle Evans 	/* Get a random value in ]0,q[ where q is the group generator order */
32*f0865ec9SKyle Evans 	ret = nn_get_random_mod(&(priv_key->x), q);
33*f0865ec9SKyle Evans 
34*f0865ec9SKyle Evans err:
35*f0865ec9SKyle Evans 	return ret;
36*f0865ec9SKyle Evans }
37*f0865ec9SKyle Evans 
38*f0865ec9SKyle Evans /* Private key generation function per signature scheme */
gen_priv_key(ec_priv_key * priv_key)39*f0865ec9SKyle Evans int gen_priv_key(ec_priv_key *priv_key)
40*f0865ec9SKyle Evans {
41*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
42*f0865ec9SKyle Evans 	int ret;
43*f0865ec9SKyle Evans 	u8 i;
44*f0865ec9SKyle Evans 
45*f0865ec9SKyle Evans 	ret = priv_key_check_initialized(priv_key); EG(ret, err);
46*f0865ec9SKyle Evans 
47*f0865ec9SKyle Evans 	ret = -1;
48*f0865ec9SKyle Evans 	for (i = 0, sm = &ec_sig_maps[i];
49*f0865ec9SKyle Evans 	     sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) {
50*f0865ec9SKyle Evans 		if (sm->type == priv_key->key_type) {
51*f0865ec9SKyle Evans 			/* NOTE: since sm is initalized with a structure
52*f0865ec9SKyle Evans 			 * coming from a const source, we can safely call
53*f0865ec9SKyle Evans 			 * the callback here, but better safe than sorry.
54*f0865ec9SKyle Evans 			 */
55*f0865ec9SKyle Evans 			MUST_HAVE((sm->gen_priv_key != NULL), ret, err);
56*f0865ec9SKyle Evans 			ret = sm->gen_priv_key(priv_key);
57*f0865ec9SKyle Evans 			break;
58*f0865ec9SKyle Evans 		}
59*f0865ec9SKyle Evans 	}
60*f0865ec9SKyle Evans 
61*f0865ec9SKyle Evans err:
62*f0865ec9SKyle Evans 	return ret;
63*f0865ec9SKyle Evans }
64*f0865ec9SKyle Evans 
65*f0865ec9SKyle Evans /*
66*f0865ec9SKyle Evans  * Generic function to init a uninitialized public key from an initialized
67*f0865ec9SKyle Evans  * private key. The function uses the expected logic to derive the key
68*f0865ec9SKyle Evans  * (e.g. Y=xG, Y=(x^-1)G, etc). It returns -1 on error (i.e. if the signature
69*f0865ec9SKyle Evans  * alg is unknown) in which case the public key has not been initialized.
70*f0865ec9SKyle Evans  * It returns 0 on success.
71*f0865ec9SKyle Evans  */
init_pubkey_from_privkey(ec_pub_key * pub_key,ec_priv_key * priv_key)72*f0865ec9SKyle Evans int init_pubkey_from_privkey(ec_pub_key *pub_key, ec_priv_key *priv_key)
73*f0865ec9SKyle Evans {
74*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
75*f0865ec9SKyle Evans 	int ret;
76*f0865ec9SKyle Evans 	u8 i;
77*f0865ec9SKyle Evans 
78*f0865ec9SKyle Evans 	ret = priv_key_check_initialized(priv_key); EG(ret, err);
79*f0865ec9SKyle Evans 
80*f0865ec9SKyle Evans 	ret = -1;
81*f0865ec9SKyle Evans 	for (i = 0, sm = &ec_sig_maps[i];
82*f0865ec9SKyle Evans 	     sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) {
83*f0865ec9SKyle Evans 		if (sm->type == priv_key->key_type) {
84*f0865ec9SKyle Evans 			/* NOTE: since sm is initalized with a structure
85*f0865ec9SKyle Evans 			 * coming from a const source, we can safely call
86*f0865ec9SKyle Evans 			 * the callback here, but better safe than sorry.
87*f0865ec9SKyle Evans 			 */
88*f0865ec9SKyle Evans 			MUST_HAVE((sm->init_pub_key != NULL), ret, err);
89*f0865ec9SKyle Evans 			ret = sm->init_pub_key(pub_key, priv_key);
90*f0865ec9SKyle Evans 			break;
91*f0865ec9SKyle Evans 		}
92*f0865ec9SKyle Evans 	}
93*f0865ec9SKyle Evans 
94*f0865ec9SKyle Evans err:
95*f0865ec9SKyle Evans 	return ret;
96*f0865ec9SKyle Evans }
97*f0865ec9SKyle Evans 
98*f0865ec9SKyle Evans /*
99*f0865ec9SKyle Evans  * On success, 0 is returned and out parameter 'sig_mapping' provides a
100*f0865ec9SKyle Evans  * pointer to the ec_sig_mapping matching given input parameter
101*f0865ec9SKyle Evans  * 'sig_name' (a null-terminated string, e.g. "ECDSA"). -1 is returned on error
102*f0865ec9SKyle Evans  * in which case 'sig_mapping' is not meaningful.
103*f0865ec9SKyle Evans  */
get_sig_by_name(const char * ec_sig_name,const ec_sig_mapping ** sig_mapping)104*f0865ec9SKyle Evans int get_sig_by_name(const char *ec_sig_name, const ec_sig_mapping **sig_mapping)
105*f0865ec9SKyle Evans {
106*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
107*f0865ec9SKyle Evans 	int ret, check;
108*f0865ec9SKyle Evans 	u8 i;
109*f0865ec9SKyle Evans 
110*f0865ec9SKyle Evans 	MUST_HAVE((ec_sig_name != NULL), ret, err);
111*f0865ec9SKyle Evans 	MUST_HAVE((sig_mapping != NULL), ret, err);
112*f0865ec9SKyle Evans 
113*f0865ec9SKyle Evans 	ret = -1;
114*f0865ec9SKyle Evans 	for (i = 0, sm = &ec_sig_maps[i];
115*f0865ec9SKyle Evans 	     sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) {
116*f0865ec9SKyle Evans 		if((!are_str_equal(ec_sig_name, sm->name, &check)) && check){
117*f0865ec9SKyle Evans 			(*sig_mapping) = sm;
118*f0865ec9SKyle Evans 			ret = 0;
119*f0865ec9SKyle Evans 			break;
120*f0865ec9SKyle Evans 		}
121*f0865ec9SKyle Evans 	}
122*f0865ec9SKyle Evans 
123*f0865ec9SKyle Evans err:
124*f0865ec9SKyle Evans 	return ret;
125*f0865ec9SKyle Evans }
126*f0865ec9SKyle Evans 
127*f0865ec9SKyle Evans /*
128*f0865ec9SKyle Evans  * On success, 0 is returned and out parameter 'sig_mapping' provides a
129*f0865ec9SKyle Evans  * pointer to the ec_sig_mapping matching given input parameter
130*f0865ec9SKyle Evans  * 'sig_type' (e.g. ECDSA, ECSDA). -1 is returned on error in which
131*f0865ec9SKyle Evans  * case 'sig_mapping' is not meaningful.
132*f0865ec9SKyle Evans  */
get_sig_by_type(ec_alg_type sig_type,const ec_sig_mapping ** sig_mapping)133*f0865ec9SKyle Evans int get_sig_by_type(ec_alg_type sig_type, const ec_sig_mapping **sig_mapping)
134*f0865ec9SKyle Evans {
135*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
136*f0865ec9SKyle Evans 	int ret;
137*f0865ec9SKyle Evans 	u8 i;
138*f0865ec9SKyle Evans 
139*f0865ec9SKyle Evans 	MUST_HAVE((sig_mapping != NULL), ret, err);
140*f0865ec9SKyle Evans 
141*f0865ec9SKyle Evans 	ret = -1;
142*f0865ec9SKyle Evans 	for (i = 0, sm = &ec_sig_maps[i];
143*f0865ec9SKyle Evans 	     sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) {
144*f0865ec9SKyle Evans 		if (sm->type == sig_type) {
145*f0865ec9SKyle Evans 			(*sig_mapping) = sm;
146*f0865ec9SKyle Evans 			ret = 0;
147*f0865ec9SKyle Evans 			break;
148*f0865ec9SKyle Evans 		}
149*f0865ec9SKyle Evans 	}
150*f0865ec9SKyle Evans 
151*f0865ec9SKyle Evans err:
152*f0865ec9SKyle Evans 	return ret;
153*f0865ec9SKyle Evans }
154*f0865ec9SKyle Evans 
155*f0865ec9SKyle Evans /*
156*f0865ec9SKyle Evans  * Here, we provide a helper that sanity checks the provided signature
157*f0865ec9SKyle Evans  * mapping against the constant ones. 0 is returned on success, -1 on
158*f0865ec9SKyle Evans  * error.
159*f0865ec9SKyle Evans  */
ec_sig_mapping_callbacks_sanity_check(const ec_sig_mapping * sig)160*f0865ec9SKyle Evans int ec_sig_mapping_callbacks_sanity_check(const ec_sig_mapping *sig)
161*f0865ec9SKyle Evans {
162*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
163*f0865ec9SKyle Evans 	int ret = -1, check;
164*f0865ec9SKyle Evans 	u8 i;
165*f0865ec9SKyle Evans 
166*f0865ec9SKyle Evans 	MUST_HAVE((sig != NULL), ret, err);
167*f0865ec9SKyle Evans 
168*f0865ec9SKyle Evans 	/* We just check is our mapping is indeed
169*f0865ec9SKyle Evans 	 * one of the registered mappings.
170*f0865ec9SKyle Evans 	 */
171*f0865ec9SKyle Evans 	for (i = 0, sm = &ec_sig_maps[i];
172*f0865ec9SKyle Evans 	     sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) {
173*f0865ec9SKyle Evans 		if (sm->type == sig->type){
174*f0865ec9SKyle Evans 			if ((!are_str_equal_nlen(sm->name, sig->name, MAX_SIG_ALG_NAME_LEN, &check)) && (!check)){
175*f0865ec9SKyle Evans 				goto err;
176*f0865ec9SKyle Evans 			} else if (sm->siglen != sig->siglen){
177*f0865ec9SKyle Evans 				goto err;
178*f0865ec9SKyle Evans 			} else if (sm->gen_priv_key != sig->gen_priv_key){
179*f0865ec9SKyle Evans 				goto err;
180*f0865ec9SKyle Evans 			} else if (sm->init_pub_key != sig->init_pub_key){
181*f0865ec9SKyle Evans 				goto err;
182*f0865ec9SKyle Evans 			} else if (sm->sign_init != sig->sign_init){
183*f0865ec9SKyle Evans 				goto err;
184*f0865ec9SKyle Evans 			} else if (sm->sign_update != sig->sign_update){
185*f0865ec9SKyle Evans 				goto err;
186*f0865ec9SKyle Evans 			} else if (sm->sign_finalize != sig->sign_finalize){
187*f0865ec9SKyle Evans 				goto err;
188*f0865ec9SKyle Evans 			} else if (sm->sign != sig->sign){
189*f0865ec9SKyle Evans 				goto err;
190*f0865ec9SKyle Evans 			} else if (sm->verify_init != sig->verify_init){
191*f0865ec9SKyle Evans 				goto err;
192*f0865ec9SKyle Evans 			} else if (sm->verify_update != sig->verify_update){
193*f0865ec9SKyle Evans 				goto err;
194*f0865ec9SKyle Evans 			} else if (sm->verify_finalize != sig->verify_finalize){
195*f0865ec9SKyle Evans 				goto err;
196*f0865ec9SKyle Evans 			} else if (sm->verify != sig->verify){
197*f0865ec9SKyle Evans 				goto err;
198*f0865ec9SKyle Evans 			} else{
199*f0865ec9SKyle Evans 				ret = 0;
200*f0865ec9SKyle Evans 			}
201*f0865ec9SKyle Evans 		}
202*f0865ec9SKyle Evans 	}
203*f0865ec9SKyle Evans 
204*f0865ec9SKyle Evans err:
205*f0865ec9SKyle Evans 	return ret;
206*f0865ec9SKyle Evans }
207*f0865ec9SKyle Evans 
208*f0865ec9SKyle Evans /*
209*f0865ec9SKyle Evans  * Sanity checks of a signature context to see if everything seems OK. 0 is
210*f0865ec9SKyle Evans  * returned on cucces, -1 on error.
211*f0865ec9SKyle Evans  */
ec_sig_ctx_callbacks_sanity_check(const struct ec_sign_context * sig_ctx)212*f0865ec9SKyle Evans int ec_sig_ctx_callbacks_sanity_check(const struct ec_sign_context *sig_ctx)
213*f0865ec9SKyle Evans {
214*f0865ec9SKyle Evans 	int ret;
215*f0865ec9SKyle Evans 
216*f0865ec9SKyle Evans 	MUST_HAVE((sig_ctx != NULL) && (sig_ctx->ctx_magic == SIG_SIGN_MAGIC), ret, err);
217*f0865ec9SKyle Evans 
218*f0865ec9SKyle Evans 	ret = hash_mapping_callbacks_sanity_check(sig_ctx->h); EG(ret, err);
219*f0865ec9SKyle Evans 	ret = ec_sig_mapping_callbacks_sanity_check(sig_ctx->sig);
220*f0865ec9SKyle Evans 
221*f0865ec9SKyle Evans err:
222*f0865ec9SKyle Evans 	return ret;
223*f0865ec9SKyle Evans }
224*f0865ec9SKyle Evans 
225*f0865ec9SKyle Evans /*
226*f0865ec9SKyle Evans  * Sanity check of a verification context to see if everything seems
227*f0865ec9SKyle Evans  * OK. 0 is returned on success, -1 on error.
228*f0865ec9SKyle Evans  */
ec_verify_ctx_callbacks_sanity_check(const struct ec_verify_context * verify_ctx)229*f0865ec9SKyle Evans int ec_verify_ctx_callbacks_sanity_check(const struct ec_verify_context *verify_ctx)
230*f0865ec9SKyle Evans {
231*f0865ec9SKyle Evans 	int ret;
232*f0865ec9SKyle Evans 
233*f0865ec9SKyle Evans 	MUST_HAVE((verify_ctx != NULL) && (verify_ctx->ctx_magic == SIG_VERIFY_MAGIC), ret, err);
234*f0865ec9SKyle Evans 
235*f0865ec9SKyle Evans 	ret = hash_mapping_callbacks_sanity_check(verify_ctx->h); EG(ret, err);
236*f0865ec9SKyle Evans 	ret = ec_sig_mapping_callbacks_sanity_check(verify_ctx->sig);
237*f0865ec9SKyle Evans 
238*f0865ec9SKyle Evans err:
239*f0865ec9SKyle Evans 	return ret;
240*f0865ec9SKyle Evans }
241*f0865ec9SKyle Evans 
242*f0865ec9SKyle Evans 
243*f0865ec9SKyle Evans /*
244*f0865ec9SKyle Evans  * Compute generic effective signature length (in bytes) depending on the curve
245*f0865ec9SKyle Evans  * parameters, the signature algorithm and the hash function. On success, 0 is
246*f0865ec9SKyle Evans  * returned and The signature length is returned using 'siglen' parameter. -1 is
247*f0865ec9SKyle Evans  * returned on error.
248*f0865ec9SKyle Evans  */
ec_get_sig_len(const ec_params * params,ec_alg_type sig_type,hash_alg_type hash_type,u8 * siglen)249*f0865ec9SKyle Evans int ec_get_sig_len(const ec_params *params, ec_alg_type sig_type,
250*f0865ec9SKyle Evans 		   hash_alg_type hash_type, u8 *siglen)
251*f0865ec9SKyle Evans {
252*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
253*f0865ec9SKyle Evans 	u8 digest_size = 0;
254*f0865ec9SKyle Evans 	u8 block_size = 0;
255*f0865ec9SKyle Evans 	int ret;
256*f0865ec9SKyle Evans 	u8 i;
257*f0865ec9SKyle Evans 
258*f0865ec9SKyle Evans 	MUST_HAVE(((params != NULL) && (siglen != NULL)), ret, err);
259*f0865ec9SKyle Evans 
260*f0865ec9SKyle Evans 	ret = get_hash_sizes(hash_type, &digest_size, &block_size); EG(ret, err);
261*f0865ec9SKyle Evans 
262*f0865ec9SKyle Evans 	ret = -1;
263*f0865ec9SKyle Evans 	for (i = 0, sm = &ec_sig_maps[i];
264*f0865ec9SKyle Evans 	     sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) {
265*f0865ec9SKyle Evans 		if (sm->type == sig_type) {
266*f0865ec9SKyle Evans 			/* NOTE: since sm is initalized with a structure
267*f0865ec9SKyle Evans 			 * coming from a const source, we can safely call
268*f0865ec9SKyle Evans 			 * the callback here, but better safe than sorry.
269*f0865ec9SKyle Evans 			 */
270*f0865ec9SKyle Evans 			MUST_HAVE((sm->siglen != NULL), ret, err);
271*f0865ec9SKyle Evans 			ret = sm->siglen(params->ec_fp.p_bitlen,
272*f0865ec9SKyle Evans 					 params->ec_gen_order_bitlen,
273*f0865ec9SKyle Evans 					 digest_size, block_size, siglen);
274*f0865ec9SKyle Evans 			break;
275*f0865ec9SKyle Evans 		}
276*f0865ec9SKyle Evans 	}
277*f0865ec9SKyle Evans 
278*f0865ec9SKyle Evans err:
279*f0865ec9SKyle Evans 	return ret;
280*f0865ec9SKyle Evans }
281*f0865ec9SKyle Evans 
282*f0865ec9SKyle Evans /* Generic signature */
283*f0865ec9SKyle Evans 
284*f0865ec9SKyle Evans /*
285*f0865ec9SKyle Evans  * Core version of generic signature initialization function. Its purpose
286*f0865ec9SKyle Evans  * is to initialize given sign context structure 'ctx' based on given key pair,
287*f0865ec9SKyle Evans  * nn random function, signature and hash types. This version allows passing
288*f0865ec9SKyle Evans  * a specific nn random function. It returns 0 on success, -1 on error.
289*f0865ec9SKyle Evans  *
290*f0865ec9SKyle Evans  * The random function is expected to initialize a nn 'out' with a value taken
291*f0865ec9SKyle Evans  * uniformly at random in [1, q-1]. It returns 0 on success and -1 on error. See
292*f0865ec9SKyle Evans  * nn_get_random_mod() in nn_rand.c for a function that fits the dscription.
293*f0865ec9SKyle Evans  */
_ec_sign_init(struct ec_sign_context * ctx,const ec_key_pair * key_pair,int (* rand)(nn_t out,nn_src_t q),ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)294*f0865ec9SKyle Evans int _ec_sign_init(struct ec_sign_context *ctx,
295*f0865ec9SKyle Evans 		  const ec_key_pair *key_pair,
296*f0865ec9SKyle Evans 		  int (*rand) (nn_t out, nn_src_t q),
297*f0865ec9SKyle Evans 		  ec_alg_type sig_type, hash_alg_type hash_type,
298*f0865ec9SKyle Evans 		  const u8 *adata, u16 adata_len)
299*f0865ec9SKyle Evans {
300*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
301*f0865ec9SKyle Evans 	const hash_mapping *hm;
302*f0865ec9SKyle Evans 	int ret;
303*f0865ec9SKyle Evans 	u8 i;
304*f0865ec9SKyle Evans 
305*f0865ec9SKyle Evans 	MUST_HAVE((ctx != NULL), ret, err);
306*f0865ec9SKyle Evans 
307*f0865ec9SKyle Evans 	ret = key_pair_check_initialized_and_type(key_pair, sig_type); EG(ret, err);
308*f0865ec9SKyle Evans 
309*f0865ec9SKyle Evans 	/* We first need to get the specific hash structure */
310*f0865ec9SKyle Evans 	ret = -1;
311*f0865ec9SKyle Evans 	for (i = 0, hm = &hash_maps[i];
312*f0865ec9SKyle Evans 	     hm->type != UNKNOWN_HASH_ALG; hm = &hash_maps[++i]) {
313*f0865ec9SKyle Evans 		if (hm->type == hash_type) {
314*f0865ec9SKyle Evans 			ret = 0;
315*f0865ec9SKyle Evans 			break;
316*f0865ec9SKyle Evans 		}
317*f0865ec9SKyle Evans 	}
318*f0865ec9SKyle Evans 	if (ret) {
319*f0865ec9SKyle Evans 		goto err;
320*f0865ec9SKyle Evans 	}
321*f0865ec9SKyle Evans 
322*f0865ec9SKyle Evans 	/* Now, let's try and get the specific key alg which was requested */
323*f0865ec9SKyle Evans 	ret = -1;
324*f0865ec9SKyle Evans 	for (i = 0, sm = &ec_sig_maps[i];
325*f0865ec9SKyle Evans 	     sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) {
326*f0865ec9SKyle Evans 		if ((sm->type == sig_type) && (sm->sign_init != NULL)) {
327*f0865ec9SKyle Evans 			ret = 0;
328*f0865ec9SKyle Evans 			break;
329*f0865ec9SKyle Evans 		}
330*f0865ec9SKyle Evans 	}
331*f0865ec9SKyle Evans 	if (ret) {
332*f0865ec9SKyle Evans 		goto err;
333*f0865ec9SKyle Evans 	}
334*f0865ec9SKyle Evans 
335*f0865ec9SKyle Evans #ifdef NO_KNOWN_VECTORS
336*f0865ec9SKyle Evans 	/*
337*f0865ec9SKyle Evans 	 * NOTE: when we do not need self tests for known vectors,
338*f0865ec9SKyle Evans 	 * we can be strict about random function handler!
339*f0865ec9SKyle Evans 	 * We only use our internal method to provide random integers
340*f0865ec9SKyle Evans 	 * (which avoids honest mistakes ...).
341*f0865ec9SKyle Evans 	 *
342*f0865ec9SKyle Evans 	 * This also allows us to avoid the corruption of such a pointer
343*f0865ec9SKyle Evans 	 * in our signature contexts.
344*f0865ec9SKyle Evans 	 */
345*f0865ec9SKyle Evans 	if (rand) {
346*f0865ec9SKyle Evans 		MUST_HAVE((rand == nn_get_random_mod), ret, err);
347*f0865ec9SKyle Evans 	}
348*f0865ec9SKyle Evans 	rand = nn_get_random_mod;
349*f0865ec9SKyle Evans #else
350*f0865ec9SKyle Evans 	/* Use given random function if provided or fallback to ours */
351*f0865ec9SKyle Evans 	if (!rand) {
352*f0865ec9SKyle Evans 		rand = nn_get_random_mod;
353*f0865ec9SKyle Evans 	}
354*f0865ec9SKyle Evans #endif
355*f0865ec9SKyle Evans 	/* Sanity checks on our mappings */
356*f0865ec9SKyle Evans 	ret = hash_mapping_sanity_check(hm); EG(ret, err);
357*f0865ec9SKyle Evans 	ret = sig_mapping_sanity_check(sm); EG(ret, err);
358*f0865ec9SKyle Evans 
359*f0865ec9SKyle Evans 	/* Initialize context for specific signature function */
360*f0865ec9SKyle Evans 	ret = local_memset(ctx, 0, sizeof(struct ec_sign_context)); EG(ret, err);
361*f0865ec9SKyle Evans 	ctx->key_pair = key_pair;
362*f0865ec9SKyle Evans 	ctx->rand = rand;
363*f0865ec9SKyle Evans 	ctx->h = hm;
364*f0865ec9SKyle Evans 	ctx->sig = sm;
365*f0865ec9SKyle Evans 	ctx->adata = adata;
366*f0865ec9SKyle Evans 	ctx->adata_len = adata_len;
367*f0865ec9SKyle Evans 	ctx->ctx_magic = SIG_SIGN_MAGIC;
368*f0865ec9SKyle Evans 
369*f0865ec9SKyle Evans 	/*
370*f0865ec9SKyle Evans 	 * NOTE: since sm has been previously initalized with a structure
371*f0865ec9SKyle Evans 	 * coming from a const source, we can safely call the callback here.
372*f0865ec9SKyle Evans 	 */
373*f0865ec9SKyle Evans 	ret = sm->sign_init(ctx);
374*f0865ec9SKyle Evans 
375*f0865ec9SKyle Evans  err:
376*f0865ec9SKyle Evans 	if (ret && (ctx != NULL)) {
377*f0865ec9SKyle Evans 		/* Clear the whole context to prevent future reuse */
378*f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_sign_context)));
379*f0865ec9SKyle Evans 	}
380*f0865ec9SKyle Evans 
381*f0865ec9SKyle Evans 	return ret;
382*f0865ec9SKyle Evans }
383*f0865ec9SKyle Evans 
384*f0865ec9SKyle Evans /*
385*f0865ec9SKyle Evans  * Same as previous but for public use; it forces our internal nn random
386*f0865ec9SKyle Evans  * function (nn_get_random_mod()). Returns 0 on success, -1 on error.
387*f0865ec9SKyle Evans  */
ec_sign_init(struct ec_sign_context * ctx,const ec_key_pair * key_pair,ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)388*f0865ec9SKyle Evans int ec_sign_init(struct ec_sign_context *ctx, const ec_key_pair *key_pair,
389*f0865ec9SKyle Evans 		 ec_alg_type sig_type, hash_alg_type hash_type,
390*f0865ec9SKyle Evans 		 const u8 *adata, u16 adata_len)
391*f0865ec9SKyle Evans {
392*f0865ec9SKyle Evans 	return _ec_sign_init(ctx, key_pair, NULL, sig_type, hash_type,
393*f0865ec9SKyle Evans 			     adata, adata_len);
394*f0865ec9SKyle Evans }
395*f0865ec9SKyle Evans 
396*f0865ec9SKyle Evans /*
397*f0865ec9SKyle Evans  * Signature update function. Returns 0 on success, -1 on error. On error,
398*f0865ec9SKyle Evans  * signature context is zeroized and is no more usable.
399*f0865ec9SKyle Evans  */
ec_sign_update(struct ec_sign_context * ctx,const u8 * chunk,u32 chunklen)400*f0865ec9SKyle Evans int ec_sign_update(struct ec_sign_context *ctx, const u8 *chunk, u32 chunklen)
401*f0865ec9SKyle Evans {
402*f0865ec9SKyle Evans 	int ret;
403*f0865ec9SKyle Evans 
404*f0865ec9SKyle Evans 	/* Sanity checks */
405*f0865ec9SKyle Evans 	ret = sig_sign_check_initialized(ctx); EG(ret, err);
406*f0865ec9SKyle Evans 	ret = sig_mapping_sanity_check(ctx->sig); EG(ret, err);
407*f0865ec9SKyle Evans 	ret = hash_mapping_sanity_check(ctx->h); EG(ret, err);
408*f0865ec9SKyle Evans 	ret = ec_sig_ctx_callbacks_sanity_check(ctx); EG(ret, err);
409*f0865ec9SKyle Evans 	ret = ctx->sig->sign_update(ctx, chunk, chunklen);
410*f0865ec9SKyle Evans 
411*f0865ec9SKyle Evans err:
412*f0865ec9SKyle Evans 	if (ret && (ctx != NULL)) {
413*f0865ec9SKyle Evans 		/* Clear the whole context to prevent future reuse */
414*f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_sign_context)));
415*f0865ec9SKyle Evans 	}
416*f0865ec9SKyle Evans 
417*f0865ec9SKyle Evans 	return ret;
418*f0865ec9SKyle Evans }
419*f0865ec9SKyle Evans 
420*f0865ec9SKyle Evans /*
421*f0865ec9SKyle Evans  * Signature finalization function. Returns 0 on success, -1 on error.
422*f0865ec9SKyle Evans  * Upon call, the signature context is cleared to prevent future use.
423*f0865ec9SKyle Evans  */
ec_sign_finalize(struct ec_sign_context * ctx,u8 * sig,u8 siglen)424*f0865ec9SKyle Evans int ec_sign_finalize(struct ec_sign_context *ctx, u8 *sig, u8 siglen)
425*f0865ec9SKyle Evans {
426*f0865ec9SKyle Evans 	int ret;
427*f0865ec9SKyle Evans 
428*f0865ec9SKyle Evans 	/* Sanity checks */
429*f0865ec9SKyle Evans 	ret = sig_sign_check_initialized(ctx); EG(ret, err);
430*f0865ec9SKyle Evans 	ret = sig_mapping_sanity_check(ctx->sig); EG(ret, err);
431*f0865ec9SKyle Evans 	ret = hash_mapping_sanity_check(ctx->h); EG(ret, err);
432*f0865ec9SKyle Evans 	ret = ec_sig_ctx_callbacks_sanity_check(ctx); EG(ret, err);
433*f0865ec9SKyle Evans 	ret = ctx->sig->sign_finalize(ctx, sig, siglen);
434*f0865ec9SKyle Evans 
435*f0865ec9SKyle Evans err:
436*f0865ec9SKyle Evans 	if (ctx != NULL) {
437*f0865ec9SKyle Evans 		/* Clear the whole context to prevent future reuse */
438*f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_sign_context)));
439*f0865ec9SKyle Evans 	}
440*f0865ec9SKyle Evans 
441*f0865ec9SKyle Evans 	return ret;
442*f0865ec9SKyle Evans }
443*f0865ec9SKyle Evans 
444*f0865ec9SKyle Evans /*
445*f0865ec9SKyle Evans  * Single call version of signature function (init, update and finalize). It
446*f0865ec9SKyle Evans  * returns 0 on success, -1 on error. This version allows passing a custom
447*f0865ec9SKyle Evans  * random function. This is useful for test vectors but should be done with
448*f0865ec9SKyle Evans  * care.
449*f0865ec9SKyle Evans  *
450*f0865ec9SKyle Evans  * The random function is expected to initialize a nn 'out' with a value taken
451*f0865ec9SKyle Evans  * uniformly at random in [1, q-1]. It returns 0 on success and -1 on error. See
452*f0865ec9SKyle Evans  * nn_get_random_mod() in nn_rand.c for a function that fits the dscription.
453*f0865ec9SKyle Evans  */
generic_ec_sign(u8 * sig,u8 siglen,const ec_key_pair * key_pair,const u8 * m,u32 mlen,int (* rand)(nn_t out,nn_src_t q),ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)454*f0865ec9SKyle Evans int generic_ec_sign(u8 *sig, u8 siglen, const ec_key_pair *key_pair,
455*f0865ec9SKyle Evans 		    const u8 *m, u32 mlen,
456*f0865ec9SKyle Evans 		    int (*rand) (nn_t out, nn_src_t q),
457*f0865ec9SKyle Evans 		    ec_alg_type sig_type, hash_alg_type hash_type,
458*f0865ec9SKyle Evans 		    const u8 *adata, u16 adata_len)
459*f0865ec9SKyle Evans {
460*f0865ec9SKyle Evans 	struct ec_sign_context ctx;
461*f0865ec9SKyle Evans 	int ret;
462*f0865ec9SKyle Evans 
463*f0865ec9SKyle Evans 	ret = _ec_sign_init(&ctx, key_pair, rand, sig_type,
464*f0865ec9SKyle Evans 			    hash_type, adata, adata_len); EG(ret, err);
465*f0865ec9SKyle Evans 	ret = ec_sign_update(&ctx, m, mlen); EG(ret, err);
466*f0865ec9SKyle Evans 	ret = ec_sign_finalize(&ctx, sig, siglen);
467*f0865ec9SKyle Evans 
468*f0865ec9SKyle Evans err:
469*f0865ec9SKyle Evans 	return ret;
470*f0865ec9SKyle Evans }
471*f0865ec9SKyle Evans 
472*f0865ec9SKyle Evans 
_ec_sign(u8 * sig,u8 siglen,const ec_key_pair * key_pair,const u8 * m,u32 mlen,int (* rand)(nn_t out,nn_src_t q),ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)473*f0865ec9SKyle Evans int _ec_sign(u8 *sig, u8 siglen, const ec_key_pair *key_pair,
474*f0865ec9SKyle Evans 	     const u8 *m, u32 mlen,
475*f0865ec9SKyle Evans 	     int (*rand) (nn_t out, nn_src_t q),
476*f0865ec9SKyle Evans 	     ec_alg_type sig_type, hash_alg_type hash_type,
477*f0865ec9SKyle Evans 	     const u8 *adata, u16 adata_len)
478*f0865ec9SKyle Evans {
479*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
480*f0865ec9SKyle Evans 	int ret;
481*f0865ec9SKyle Evans 
482*f0865ec9SKyle Evans 	ret = get_sig_by_type(sig_type, &sm); EG(ret, err);
483*f0865ec9SKyle Evans 	MUST_HAVE(((sm != NULL) && (sm->sign != NULL)), ret, err);
484*f0865ec9SKyle Evans 
485*f0865ec9SKyle Evans 	ret = sm->sign(sig, siglen, key_pair, m, mlen, rand,
486*f0865ec9SKyle Evans 		       sig_type, hash_type, adata, adata_len);
487*f0865ec9SKyle Evans 
488*f0865ec9SKyle Evans err:
489*f0865ec9SKyle Evans 	return ret;
490*f0865ec9SKyle Evans }
491*f0865ec9SKyle Evans 
492*f0865ec9SKyle Evans /*
493*f0865ec9SKyle Evans  * Same as previous but for public use; it forces our internal nn random
494*f0865ec9SKyle Evans  * function (nn_get_random_mod()) by pasing NULL for 'rand' argument
495*f0865ec9SKyle Evans  * _ec_sign(). Returns 0 on success, -1 on error.
496*f0865ec9SKyle Evans  */
ec_sign(u8 * sig,u8 siglen,const ec_key_pair * key_pair,const u8 * m,u32 mlen,ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)497*f0865ec9SKyle Evans int ec_sign(u8 *sig, u8 siglen, const ec_key_pair *key_pair,
498*f0865ec9SKyle Evans 	    const u8 *m, u32 mlen,
499*f0865ec9SKyle Evans 	    ec_alg_type sig_type, hash_alg_type hash_type,
500*f0865ec9SKyle Evans 	    const u8 *adata, u16 adata_len)
501*f0865ec9SKyle Evans {
502*f0865ec9SKyle Evans 	return _ec_sign(sig, siglen, key_pair, m, mlen,
503*f0865ec9SKyle Evans 			NULL, sig_type, hash_type, adata, adata_len);
504*f0865ec9SKyle Evans }
505*f0865ec9SKyle Evans 
506*f0865ec9SKyle Evans /*
507*f0865ec9SKyle Evans  * Generic signature verification initialization function. Returns 0 on success,
508*f0865ec9SKyle Evans  * -1 on error. On error, verification context is cleared to prevent further
509*f0865ec9SKyle Evans  * reuse.
510*f0865ec9SKyle Evans  */
ec_verify_init(struct ec_verify_context * ctx,const ec_pub_key * pub_key,const u8 * sig,u8 siglen,ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)511*f0865ec9SKyle Evans int ec_verify_init(struct ec_verify_context *ctx, const ec_pub_key *pub_key,
512*f0865ec9SKyle Evans 		   const u8 *sig, u8 siglen,
513*f0865ec9SKyle Evans 		   ec_alg_type sig_type, hash_alg_type hash_type,
514*f0865ec9SKyle Evans 		   const u8 *adata, u16 adata_len)
515*f0865ec9SKyle Evans {
516*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
517*f0865ec9SKyle Evans 	const hash_mapping *hm;
518*f0865ec9SKyle Evans 	u8 i;
519*f0865ec9SKyle Evans 	int ret;
520*f0865ec9SKyle Evans 
521*f0865ec9SKyle Evans 	MUST_HAVE((ctx != NULL), ret, err);
522*f0865ec9SKyle Evans 
523*f0865ec9SKyle Evans 	ret = pub_key_check_initialized_and_type(pub_key, sig_type); EG(ret, err);
524*f0865ec9SKyle Evans 
525*f0865ec9SKyle Evans 	/* We first need to get the specific hash structure */
526*f0865ec9SKyle Evans 	ret = -1;
527*f0865ec9SKyle Evans 	for (i = 0, hm = &hash_maps[i];
528*f0865ec9SKyle Evans 	     hm->type != UNKNOWN_HASH_ALG; hm = &hash_maps[++i]) {
529*f0865ec9SKyle Evans 		if (hm->type == hash_type) {
530*f0865ec9SKyle Evans 			ret = 0;
531*f0865ec9SKyle Evans 			break;
532*f0865ec9SKyle Evans 		}
533*f0865ec9SKyle Evans 	}
534*f0865ec9SKyle Evans 	if (ret) {
535*f0865ec9SKyle Evans 		goto err;
536*f0865ec9SKyle Evans 	}
537*f0865ec9SKyle Evans 
538*f0865ec9SKyle Evans 	/*
539*f0865ec9SKyle Evans 	 * Now, let's try and get the specific key algorithm which was
540*f0865ec9SKyle Evans 	 * requested
541*f0865ec9SKyle Evans 	 */
542*f0865ec9SKyle Evans 	ret = -1;
543*f0865ec9SKyle Evans 	for (i = 0, sm = &ec_sig_maps[i];
544*f0865ec9SKyle Evans 	     sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) {
545*f0865ec9SKyle Evans 		if ((sm->type == sig_type) && (sm->verify_init != NULL)) {
546*f0865ec9SKyle Evans 			ret = 0;
547*f0865ec9SKyle Evans 			break;
548*f0865ec9SKyle Evans 		}
549*f0865ec9SKyle Evans 	}
550*f0865ec9SKyle Evans 	if (ret) {
551*f0865ec9SKyle Evans 		goto err;
552*f0865ec9SKyle Evans 	}
553*f0865ec9SKyle Evans 
554*f0865ec9SKyle Evans 	/* Sanity checks on our mappings */
555*f0865ec9SKyle Evans 	ret = hash_mapping_sanity_check(hm); EG(ret, err);
556*f0865ec9SKyle Evans 	ret = sig_mapping_sanity_check(sm); EG(ret, err);
557*f0865ec9SKyle Evans 
558*f0865ec9SKyle Evans 	/* Initialize context for specific signature function */
559*f0865ec9SKyle Evans 	ret = local_memset(ctx, 0, sizeof(struct ec_verify_context)); EG(ret, err);
560*f0865ec9SKyle Evans 	ctx->pub_key = pub_key;
561*f0865ec9SKyle Evans 	ctx->h = hm;
562*f0865ec9SKyle Evans 	ctx->sig = sm;
563*f0865ec9SKyle Evans 	ctx->adata = adata;
564*f0865ec9SKyle Evans 	ctx->adata_len = adata_len;
565*f0865ec9SKyle Evans 	ctx->ctx_magic = SIG_VERIFY_MAGIC;
566*f0865ec9SKyle Evans 
567*f0865ec9SKyle Evans 	/*
568*f0865ec9SKyle Evans 	 * NOTE: since sm has been previously initalized with a structure
569*f0865ec9SKyle Evans 	 * coming from a const source, we can safely call the callback
570*f0865ec9SKyle Evans 	 * here.
571*f0865ec9SKyle Evans 	 */
572*f0865ec9SKyle Evans 	ret = sm->verify_init(ctx, sig, siglen);
573*f0865ec9SKyle Evans 
574*f0865ec9SKyle Evans  err:
575*f0865ec9SKyle Evans 
576*f0865ec9SKyle Evans 	if (ret && (ctx != NULL)) {
577*f0865ec9SKyle Evans 		/* Clear the whole context to prevent future reuse */
578*f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_verify_context)));
579*f0865ec9SKyle Evans 	}
580*f0865ec9SKyle Evans 
581*f0865ec9SKyle Evans 	return ret;
582*f0865ec9SKyle Evans }
583*f0865ec9SKyle Evans 
584*f0865ec9SKyle Evans /*
585*f0865ec9SKyle Evans  * Signature verification update function. Returns 0 on success, -1 on error.
586*f0865ec9SKyle Evans  * On error, verification context is cleared to prevent further reuse.
587*f0865ec9SKyle Evans  */
ec_verify_update(struct ec_verify_context * ctx,const u8 * chunk,u32 chunklen)588*f0865ec9SKyle Evans int ec_verify_update(struct ec_verify_context *ctx,
589*f0865ec9SKyle Evans 		     const u8 *chunk, u32 chunklen)
590*f0865ec9SKyle Evans {
591*f0865ec9SKyle Evans 	int ret;
592*f0865ec9SKyle Evans 
593*f0865ec9SKyle Evans 	ret = sig_verify_check_initialized(ctx); EG(ret, err);
594*f0865ec9SKyle Evans 	ret = sig_mapping_sanity_check(ctx->sig); EG(ret, err);
595*f0865ec9SKyle Evans 	ret = hash_mapping_sanity_check(ctx->h); EG(ret, err);
596*f0865ec9SKyle Evans 
597*f0865ec9SKyle Evans 	/* Since we call a callback, sanity check our contexts */
598*f0865ec9SKyle Evans 	ret = ec_verify_ctx_callbacks_sanity_check(ctx); EG(ret, err);
599*f0865ec9SKyle Evans 	ret = ctx->sig->verify_update(ctx, chunk, chunklen);
600*f0865ec9SKyle Evans 
601*f0865ec9SKyle Evans err:
602*f0865ec9SKyle Evans 	if (ret && (ctx != NULL)) {
603*f0865ec9SKyle Evans 		/* Clear the whole context to prevent future reuse */
604*f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_verify_context)));
605*f0865ec9SKyle Evans 	}
606*f0865ec9SKyle Evans 
607*f0865ec9SKyle Evans 	return ret;
608*f0865ec9SKyle Evans }
609*f0865ec9SKyle Evans 
610*f0865ec9SKyle Evans /*
611*f0865ec9SKyle Evans  * Signature verification finalize function. Returns 0 on success, -1 on error.
612*f0865ec9SKyle Evans  * On error, verification context is cleared to prevent further reuse.
613*f0865ec9SKyle Evans  */
ec_verify_finalize(struct ec_verify_context * ctx)614*f0865ec9SKyle Evans int ec_verify_finalize(struct ec_verify_context *ctx)
615*f0865ec9SKyle Evans {
616*f0865ec9SKyle Evans 	int ret;
617*f0865ec9SKyle Evans 
618*f0865ec9SKyle Evans 	ret = sig_verify_check_initialized(ctx); EG(ret, err);
619*f0865ec9SKyle Evans 	ret = sig_mapping_sanity_check(ctx->sig); EG(ret, err);
620*f0865ec9SKyle Evans 	ret = hash_mapping_sanity_check(ctx->h); EG(ret, err);
621*f0865ec9SKyle Evans 
622*f0865ec9SKyle Evans 	/* Since we call a callback, sanity check our contexts */
623*f0865ec9SKyle Evans 	ret = ec_verify_ctx_callbacks_sanity_check(ctx); EG(ret, err);
624*f0865ec9SKyle Evans 	ret = ctx->sig->verify_finalize(ctx);
625*f0865ec9SKyle Evans 
626*f0865ec9SKyle Evans err:
627*f0865ec9SKyle Evans 	if (ret && (ctx != NULL)) {
628*f0865ec9SKyle Evans 		/* Clear the whole context to prevent future reuse */
629*f0865ec9SKyle Evans 		IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_verify_context)));
630*f0865ec9SKyle Evans 	}
631*f0865ec9SKyle Evans 	return ret;
632*f0865ec9SKyle Evans }
633*f0865ec9SKyle Evans 
634*f0865ec9SKyle Evans /*
635*f0865ec9SKyle Evans  * Single call version of signature verification function (init, update and
636*f0865ec9SKyle Evans  * finalize). It returns 0 on success, -1 on error.
637*f0865ec9SKyle Evans  */
generic_ec_verify(const u8 * sig,u8 siglen,const ec_pub_key * pub_key,const u8 * m,u32 mlen,ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)638*f0865ec9SKyle Evans int generic_ec_verify(const u8 *sig, u8 siglen, const ec_pub_key *pub_key,
639*f0865ec9SKyle Evans 		      const u8 *m, u32 mlen,
640*f0865ec9SKyle Evans 		      ec_alg_type sig_type, hash_alg_type hash_type,
641*f0865ec9SKyle Evans 		      const u8 *adata, u16 adata_len)
642*f0865ec9SKyle Evans {
643*f0865ec9SKyle Evans 	struct ec_verify_context ctx;
644*f0865ec9SKyle Evans 	int ret;
645*f0865ec9SKyle Evans 
646*f0865ec9SKyle Evans 	ret = ec_verify_init(&ctx, pub_key, sig, siglen, sig_type,
647*f0865ec9SKyle Evans 			hash_type, adata, adata_len); EG(ret, err);
648*f0865ec9SKyle Evans 	ret = ec_verify_update(&ctx, m, mlen); EG(ret, err);
649*f0865ec9SKyle Evans 	ret = ec_verify_finalize(&ctx);
650*f0865ec9SKyle Evans 
651*f0865ec9SKyle Evans  err:
652*f0865ec9SKyle Evans 	return ret;
653*f0865ec9SKyle Evans }
654*f0865ec9SKyle Evans 
ec_verify(const u8 * sig,u8 siglen,const ec_pub_key * pub_key,const u8 * m,u32 mlen,ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)655*f0865ec9SKyle Evans int ec_verify(const u8 *sig, u8 siglen, const ec_pub_key *pub_key,
656*f0865ec9SKyle Evans 	      const u8 *m, u32 mlen,
657*f0865ec9SKyle Evans 	      ec_alg_type sig_type, hash_alg_type hash_type,
658*f0865ec9SKyle Evans 	      const u8 *adata, u16 adata_len)
659*f0865ec9SKyle Evans {
660*f0865ec9SKyle Evans 
661*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
662*f0865ec9SKyle Evans 	int ret;
663*f0865ec9SKyle Evans 
664*f0865ec9SKyle Evans 	ret = get_sig_by_type(sig_type, &sm); EG(ret, err);
665*f0865ec9SKyle Evans 
666*f0865ec9SKyle Evans 	MUST_HAVE((sm != NULL) && (sm->verify != NULL), ret, err);
667*f0865ec9SKyle Evans 
668*f0865ec9SKyle Evans 	ret = sm->verify(sig, siglen, pub_key, m, mlen, sig_type,
669*f0865ec9SKyle Evans 			 hash_type, adata, adata_len);
670*f0865ec9SKyle Evans 
671*f0865ec9SKyle Evans err:
672*f0865ec9SKyle Evans 	return ret;
673*f0865ec9SKyle Evans }
674*f0865ec9SKyle Evans 
ec_verify_batch(const u8 ** s,const u8 * s_len,const ec_pub_key ** pub_keys,const u8 ** m,const u32 * m_len,u32 num,ec_alg_type sig_type,hash_alg_type hash_type,const u8 ** adata,const u16 * adata_len,verify_batch_scratch_pad * scratch_pad_area,u32 * scratch_pad_area_len)675*f0865ec9SKyle Evans int ec_verify_batch(const u8 **s, const u8 *s_len, const ec_pub_key **pub_keys,
676*f0865ec9SKyle Evans               const u8 **m, const u32 *m_len, u32 num, ec_alg_type sig_type,
677*f0865ec9SKyle Evans               hash_alg_type hash_type, const u8 **adata, const u16 *adata_len,
678*f0865ec9SKyle Evans 	      verify_batch_scratch_pad *scratch_pad_area, u32 *scratch_pad_area_len)
679*f0865ec9SKyle Evans {
680*f0865ec9SKyle Evans 
681*f0865ec9SKyle Evans 	const ec_sig_mapping *sm;
682*f0865ec9SKyle Evans 	int ret;
683*f0865ec9SKyle Evans 
684*f0865ec9SKyle Evans 	ret = get_sig_by_type(sig_type, &sm); EG(ret, err);
685*f0865ec9SKyle Evans 
686*f0865ec9SKyle Evans 	MUST_HAVE((sm != NULL) && (sm->verify_batch != NULL), ret, err);
687*f0865ec9SKyle Evans 
688*f0865ec9SKyle Evans 	ret = sm->verify_batch(s, s_len, pub_keys, m, m_len, num, sig_type,
689*f0865ec9SKyle Evans 			 hash_type, adata, adata_len,
690*f0865ec9SKyle Evans 			 scratch_pad_area, scratch_pad_area_len);
691*f0865ec9SKyle Evans 
692*f0865ec9SKyle Evans err:
693*f0865ec9SKyle Evans 	return ret;
694*f0865ec9SKyle Evans }
695*f0865ec9SKyle Evans 
696*f0865ec9SKyle Evans /*
697*f0865ec9SKyle Evans  * Import a signature with structured data containing information about the EC
698*f0865ec9SKyle Evans  * algorithm type as well as the hash function used to produce the signature.
699*f0865ec9SKyle Evans  * The function returns 0 on success, -1 on error. out parameters (sig_type,
700*f0865ec9SKyle Evans  * hash_type, curve_name should only be considered on success.
701*f0865ec9SKyle Evans  */
ec_structured_sig_import_from_buf(u8 * sig,u32 siglen,const u8 * out_buf,u32 outlen,ec_alg_type * sig_type,hash_alg_type * hash_type,u8 curve_name[MAX_CURVE_NAME_LEN])702*f0865ec9SKyle Evans int ec_structured_sig_import_from_buf(u8 *sig, u32 siglen,
703*f0865ec9SKyle Evans 				      const u8 *out_buf, u32 outlen,
704*f0865ec9SKyle Evans 				      ec_alg_type * sig_type,
705*f0865ec9SKyle Evans 				      hash_alg_type * hash_type,
706*f0865ec9SKyle Evans 				      u8 curve_name[MAX_CURVE_NAME_LEN])
707*f0865ec9SKyle Evans {
708*f0865ec9SKyle Evans 	u32 metadata_len = (3 * sizeof(u8));
709*f0865ec9SKyle Evans 	int ret;
710*f0865ec9SKyle Evans 
711*f0865ec9SKyle Evans 	MUST_HAVE((out_buf != NULL) && (sig_type != NULL) &&
712*f0865ec9SKyle Evans 		  (hash_type != NULL) && (curve_name != NULL), ret, err);
713*f0865ec9SKyle Evans 	/* We only deal with signatures of length < 256 */
714*f0865ec9SKyle Evans 	MUST_HAVE((siglen <= EC_MAX_SIGLEN) && (sig != NULL), ret, err);
715*f0865ec9SKyle Evans 
716*f0865ec9SKyle Evans 	/* We first import the metadata consisting of:
717*f0865ec9SKyle Evans 	 *	- One byte = the EC algorithm type
718*f0865ec9SKyle Evans 	 *	- One byte = the hash algorithm type
719*f0865ec9SKyle Evans 	 *	- One byte = the curve type (FRP256V1, ...)
720*f0865ec9SKyle Evans 	 */
721*f0865ec9SKyle Evans 	MUST_HAVE((outlen <= (siglen + metadata_len)), ret, err);
722*f0865ec9SKyle Evans 
723*f0865ec9SKyle Evans 	*sig_type = (ec_alg_type)out_buf[0];
724*f0865ec9SKyle Evans 	*hash_type = (hash_alg_type)out_buf[1];
725*f0865ec9SKyle Evans 	ret = ec_get_curve_name_by_type((ec_curve_type) out_buf[2],
726*f0865ec9SKyle Evans 					curve_name, MAX_CURVE_NAME_LEN); EG(ret, err);
727*f0865ec9SKyle Evans 
728*f0865ec9SKyle Evans 	/* Copy the raw signature */
729*f0865ec9SKyle Evans 	ret = local_memcpy(sig, out_buf + metadata_len, siglen);
730*f0865ec9SKyle Evans 
731*f0865ec9SKyle Evans err:
732*f0865ec9SKyle Evans 	return ret;
733*f0865ec9SKyle Evans }
734*f0865ec9SKyle Evans 
735*f0865ec9SKyle Evans /*
736*f0865ec9SKyle Evans  * Export a signature with structured data containing information about the
737*f0865ec9SKyle Evans  * EC algorithm type as well as the hash function used to produce it. The
738*f0865ec9SKyle Evans  * function returns 0 on success, -1 on error.
739*f0865ec9SKyle Evans  */
ec_structured_sig_export_to_buf(const u8 * sig,u32 siglen,u8 * out_buf,u32 outlen,ec_alg_type sig_type,hash_alg_type hash_type,const u8 curve_name[MAX_CURVE_NAME_LEN])740*f0865ec9SKyle Evans int ec_structured_sig_export_to_buf(const u8 *sig, u32 siglen,
741*f0865ec9SKyle Evans 				    u8 *out_buf, u32 outlen,
742*f0865ec9SKyle Evans 				    ec_alg_type sig_type,
743*f0865ec9SKyle Evans 				    hash_alg_type hash_type,
744*f0865ec9SKyle Evans 				    const u8
745*f0865ec9SKyle Evans 				    curve_name[MAX_CURVE_NAME_LEN])
746*f0865ec9SKyle Evans {
747*f0865ec9SKyle Evans 	u32 metadata_len = (3 * sizeof(u8));
748*f0865ec9SKyle Evans 	u32 len;
749*f0865ec9SKyle Evans 	u8 curve_name_len;
750*f0865ec9SKyle Evans 	ec_curve_type curve_type;
751*f0865ec9SKyle Evans 	int ret;
752*f0865ec9SKyle Evans 
753*f0865ec9SKyle Evans 	MUST_HAVE((out_buf != NULL) && (curve_name != NULL), ret, err);
754*f0865ec9SKyle Evans 	/* We only deal with signatures of length < 256 */
755*f0865ec9SKyle Evans 	MUST_HAVE((siglen <= EC_MAX_SIGLEN) && (sig != NULL), ret, err);
756*f0865ec9SKyle Evans 
757*f0865ec9SKyle Evans 	/* We first export the metadata consisting of:
758*f0865ec9SKyle Evans 	 *	- One byte = the EC algorithm type
759*f0865ec9SKyle Evans 	 *	- One byte = the hash algorithm type
760*f0865ec9SKyle Evans 	 *	- One byte = the curve type (FRP256V1, ...)
761*f0865ec9SKyle Evans 	 *
762*f0865ec9SKyle Evans 	 */
763*f0865ec9SKyle Evans 	MUST_HAVE(outlen >= (siglen + metadata_len), ret, err);
764*f0865ec9SKyle Evans 
765*f0865ec9SKyle Evans 	out_buf[0] = (u8)sig_type;
766*f0865ec9SKyle Evans 	out_buf[1] = (u8)hash_type;
767*f0865ec9SKyle Evans 	ret = local_strlen((const char *)curve_name, &len); EG(ret, err);
768*f0865ec9SKyle Evans 	len += 1;
769*f0865ec9SKyle Evans 	MUST_HAVE((len < 256), ret, err);
770*f0865ec9SKyle Evans 	curve_name_len = (u8)len;
771*f0865ec9SKyle Evans 	ret = ec_get_curve_type_by_name(curve_name, curve_name_len, &curve_type); EG(ret, err);
772*f0865ec9SKyle Evans 	out_buf[2] = (u8)curve_type;
773*f0865ec9SKyle Evans 	MUST_HAVE((out_buf[2] != UNKNOWN_CURVE), ret, err);
774*f0865ec9SKyle Evans 
775*f0865ec9SKyle Evans 	/* Copy the raw signature */
776*f0865ec9SKyle Evans 	ret = local_memcpy(out_buf + metadata_len, sig, siglen);
777*f0865ec9SKyle Evans 
778*f0865ec9SKyle Evans err:
779*f0865ec9SKyle Evans 	return ret;
780*f0865ec9SKyle Evans }
781*f0865ec9SKyle Evans 
782*f0865ec9SKyle Evans 
783*f0865ec9SKyle Evans /* Signature finalization function */
unsupported_sign_init(struct ec_sign_context * ctx)784*f0865ec9SKyle Evans int unsupported_sign_init(struct ec_sign_context * ctx)
785*f0865ec9SKyle Evans {
786*f0865ec9SKyle Evans 	/* Quirk to avoid unused variables */
787*f0865ec9SKyle Evans 	FORCE_USED_VAR(ctx);
788*f0865ec9SKyle Evans 
789*f0865ec9SKyle Evans 	/* Return an error in any case here */
790*f0865ec9SKyle Evans 	return -1;
791*f0865ec9SKyle Evans }
792*f0865ec9SKyle Evans 
unsupported_sign_update(struct ec_sign_context * ctx,const u8 * chunk,u32 chunklen)793*f0865ec9SKyle Evans int unsupported_sign_update(struct ec_sign_context * ctx,
794*f0865ec9SKyle Evans 		    const u8 *chunk, u32 chunklen)
795*f0865ec9SKyle Evans {
796*f0865ec9SKyle Evans 	/* Quirk to avoid unused variables */
797*f0865ec9SKyle Evans 	FORCE_USED_VAR(ctx);
798*f0865ec9SKyle Evans 	FORCE_USED_VAR(chunk);
799*f0865ec9SKyle Evans 	FORCE_USED_VAR(chunklen);
800*f0865ec9SKyle Evans 
801*f0865ec9SKyle Evans 	/* Return an error in any case here */
802*f0865ec9SKyle Evans 	return -1;
803*f0865ec9SKyle Evans }
804*f0865ec9SKyle Evans 
unsupported_sign_finalize(struct ec_sign_context * ctx,u8 * sig,u8 siglen)805*f0865ec9SKyle Evans int unsupported_sign_finalize(struct ec_sign_context *ctx, u8 *sig, u8 siglen)
806*f0865ec9SKyle Evans {
807*f0865ec9SKyle Evans 	/* Quirk to avoid unused variables */
808*f0865ec9SKyle Evans 	FORCE_USED_VAR(ctx);
809*f0865ec9SKyle Evans 	FORCE_USED_VAR(sig);
810*f0865ec9SKyle Evans 	FORCE_USED_VAR(siglen);
811*f0865ec9SKyle Evans 
812*f0865ec9SKyle Evans 	/* Return an error in any case here */
813*f0865ec9SKyle Evans 	return -1;
814*f0865ec9SKyle Evans }
815*f0865ec9SKyle Evans 
unsupported_verify_init(struct ec_verify_context * ctx,const u8 * sig,u8 siglen)816*f0865ec9SKyle Evans int unsupported_verify_init(struct ec_verify_context * ctx,
817*f0865ec9SKyle Evans 		    const u8 *sig, u8 siglen)
818*f0865ec9SKyle Evans {
819*f0865ec9SKyle Evans 	/* Quirk to avoid unused variables */
820*f0865ec9SKyle Evans 	FORCE_USED_VAR(ctx);
821*f0865ec9SKyle Evans 	FORCE_USED_VAR(sig);
822*f0865ec9SKyle Evans 	FORCE_USED_VAR(siglen);
823*f0865ec9SKyle Evans 
824*f0865ec9SKyle Evans 	/* Return an error in any case here */
825*f0865ec9SKyle Evans 	return -1;
826*f0865ec9SKyle Evans }
827*f0865ec9SKyle Evans 
unsupported_verify_update(struct ec_verify_context * ctx,const u8 * chunk,u32 chunklen)828*f0865ec9SKyle Evans int unsupported_verify_update(struct ec_verify_context * ctx,
829*f0865ec9SKyle Evans 		      const u8 *chunk, u32 chunklen)
830*f0865ec9SKyle Evans {
831*f0865ec9SKyle Evans 	/* Quirk to avoid unused variables */
832*f0865ec9SKyle Evans 	FORCE_USED_VAR(ctx);
833*f0865ec9SKyle Evans 	FORCE_USED_VAR(chunk);
834*f0865ec9SKyle Evans 	FORCE_USED_VAR(chunklen);
835*f0865ec9SKyle Evans 
836*f0865ec9SKyle Evans 	/* Return an error in any case here */
837*f0865ec9SKyle Evans 	return -1;
838*f0865ec9SKyle Evans }
839*f0865ec9SKyle Evans 
unsupported_verify_finalize(struct ec_verify_context * ctx)840*f0865ec9SKyle Evans int unsupported_verify_finalize(struct ec_verify_context * ctx)
841*f0865ec9SKyle Evans {
842*f0865ec9SKyle Evans 	/* Quirk to avoid unused variables */
843*f0865ec9SKyle Evans 	FORCE_USED_VAR(ctx);
844*f0865ec9SKyle Evans 
845*f0865ec9SKyle Evans 	/* Return an error in any case here */
846*f0865ec9SKyle Evans 	return -1;
847*f0865ec9SKyle Evans }
848*f0865ec9SKyle Evans 
849*f0865ec9SKyle Evans /* Unsupported batch verification */
unsupported_verify_batch(const u8 ** s,const u8 * s_len,const ec_pub_key ** pub_keys,const u8 ** m,const u32 * m_len,u32 num,ec_alg_type sig_type,hash_alg_type hash_type,const u8 ** adata,const u16 * adata_len,verify_batch_scratch_pad * scratch_pad_area,u32 * scratch_pad_area_len)850*f0865ec9SKyle Evans int unsupported_verify_batch(const u8 **s, const u8 *s_len, const ec_pub_key **pub_keys,
851*f0865ec9SKyle Evans               const u8 **m, const u32 *m_len, u32 num, ec_alg_type sig_type,
852*f0865ec9SKyle Evans               hash_alg_type hash_type, const u8 **adata, const u16 *adata_len,
853*f0865ec9SKyle Evans 	      verify_batch_scratch_pad *scratch_pad_area, u32 *scratch_pad_area_len)
854*f0865ec9SKyle Evans {
855*f0865ec9SKyle Evans 	/* Quirk to avoid unused variables */
856*f0865ec9SKyle Evans 	FORCE_USED_VAR(s);
857*f0865ec9SKyle Evans 	FORCE_USED_VAR(pub_keys);
858*f0865ec9SKyle Evans 	FORCE_USED_VAR(m);
859*f0865ec9SKyle Evans 	FORCE_USED_VAR(num);
860*f0865ec9SKyle Evans 	FORCE_USED_VAR(sig_type);
861*f0865ec9SKyle Evans 	FORCE_USED_VAR(hash_type);
862*f0865ec9SKyle Evans 	FORCE_USED_VAR(adata);
863*f0865ec9SKyle Evans 	FORCE_USED_VAR(s_len);
864*f0865ec9SKyle Evans 	FORCE_USED_VAR(m_len);
865*f0865ec9SKyle Evans 	FORCE_USED_VAR(adata_len);
866*f0865ec9SKyle Evans 	FORCE_USED_VAR(scratch_pad_area);
867*f0865ec9SKyle Evans 	FORCE_USED_VAR(scratch_pad_area_len);
868*f0865ec9SKyle Evans 
869*f0865ec9SKyle Evans 	/* Return an error in any case here */
870*f0865ec9SKyle Evans 	return -1;
871*f0865ec9SKyle Evans }
872*f0865ec9SKyle Evans 
873*f0865ec9SKyle Evans /* This function returns 1 in 'check' if the init/update/finalize mode
874*f0865ec9SKyle Evans  * is supported by the signature algorithm, 0 otherwise.
875*f0865ec9SKyle Evans  *
876*f0865ec9SKyle Evans  * Return value is 0 on success, -1 on error. 'check' is only meaningful on
877*f0865ec9SKyle Evans  * success.
878*f0865ec9SKyle Evans  */
is_sign_streaming_mode_supported(ec_alg_type sig_type,int * check)879*f0865ec9SKyle Evans int is_sign_streaming_mode_supported(ec_alg_type sig_type, int *check)
880*f0865ec9SKyle Evans {
881*f0865ec9SKyle Evans 	int ret;
882*f0865ec9SKyle Evans 	const ec_sig_mapping *sig;
883*f0865ec9SKyle Evans 
884*f0865ec9SKyle Evans 	MUST_HAVE((check != NULL), ret, err);
885*f0865ec9SKyle Evans 
886*f0865ec9SKyle Evans 	ret = get_sig_by_type(sig_type, &sig); EG(ret, err);
887*f0865ec9SKyle Evans 	MUST_HAVE((sig != NULL), ret, err);
888*f0865ec9SKyle Evans 
889*f0865ec9SKyle Evans 	if ((sig->sign_init == unsupported_sign_init) ||
890*f0865ec9SKyle Evans 	    (sig->sign_update == unsupported_sign_update) ||
891*f0865ec9SKyle Evans 	    (sig->sign_finalize == unsupported_sign_finalize)) {
892*f0865ec9SKyle Evans 		(*check) = 0;
893*f0865ec9SKyle Evans 	}
894*f0865ec9SKyle Evans 	else{
895*f0865ec9SKyle Evans 		(*check) = 1;
896*f0865ec9SKyle Evans 	}
897*f0865ec9SKyle Evans 
898*f0865ec9SKyle Evans err:
899*f0865ec9SKyle Evans 	return ret;
900*f0865ec9SKyle Evans }
901*f0865ec9SKyle Evans 
902*f0865ec9SKyle Evans /* This function returns 1 in 'check' if the init/update/finalize mode
903*f0865ec9SKyle Evans  * is supported by the verification algorithm, 0 otherwise.
904*f0865ec9SKyle Evans  *
905*f0865ec9SKyle Evans  * Return value is 0 on success, -1 on error. 'check' is only meaningful on
906*f0865ec9SKyle Evans  * success.
907*f0865ec9SKyle Evans  */
is_verify_streaming_mode_supported(ec_alg_type sig_type,int * check)908*f0865ec9SKyle Evans int is_verify_streaming_mode_supported(ec_alg_type sig_type, int *check)
909*f0865ec9SKyle Evans {
910*f0865ec9SKyle Evans 	int ret;
911*f0865ec9SKyle Evans 	const ec_sig_mapping *sig;
912*f0865ec9SKyle Evans 
913*f0865ec9SKyle Evans 	MUST_HAVE((check != NULL), ret, err);
914*f0865ec9SKyle Evans 
915*f0865ec9SKyle Evans 	ret = get_sig_by_type(sig_type, &sig); EG(ret, err);
916*f0865ec9SKyle Evans 	MUST_HAVE((sig != NULL), ret, err);
917*f0865ec9SKyle Evans 
918*f0865ec9SKyle Evans 	if ((sig->verify_init == unsupported_verify_init) ||
919*f0865ec9SKyle Evans 	    (sig->verify_update == unsupported_verify_update) ||
920*f0865ec9SKyle Evans 	    (sig->verify_finalize == unsupported_verify_finalize)) {
921*f0865ec9SKyle Evans 		(*check) = 0;
922*f0865ec9SKyle Evans 	}
923*f0865ec9SKyle Evans 	else{
924*f0865ec9SKyle Evans 		(*check) = 1;
925*f0865ec9SKyle Evans 	}
926*f0865ec9SKyle Evans 
927*f0865ec9SKyle Evans err:
928*f0865ec9SKyle Evans 	return ret;
929*f0865ec9SKyle Evans }
930*f0865ec9SKyle Evans 
931*f0865ec9SKyle Evans /* This function returns 1 in 'check' if the batch verification mode
932*f0865ec9SKyle Evans  * is supported by the verification algorithm, 0 otherwise.
933*f0865ec9SKyle Evans  *
934*f0865ec9SKyle Evans  * Return value is 0 on success, -1 on error. 'check' is only meaningful on
935*f0865ec9SKyle Evans  * success.
936*f0865ec9SKyle Evans  */
is_verify_batch_mode_supported(ec_alg_type sig_type,int * check)937*f0865ec9SKyle Evans int is_verify_batch_mode_supported(ec_alg_type sig_type, int *check)
938*f0865ec9SKyle Evans {
939*f0865ec9SKyle Evans 	int ret;
940*f0865ec9SKyle Evans 	const ec_sig_mapping *sig;
941*f0865ec9SKyle Evans 
942*f0865ec9SKyle Evans 	MUST_HAVE((check != NULL), ret, err);
943*f0865ec9SKyle Evans 
944*f0865ec9SKyle Evans 	ret = get_sig_by_type(sig_type, &sig); EG(ret, err);
945*f0865ec9SKyle Evans 	MUST_HAVE((sig != NULL), ret, err);
946*f0865ec9SKyle Evans 
947*f0865ec9SKyle Evans 	if (sig->verify_batch == unsupported_verify_batch) {
948*f0865ec9SKyle Evans 		(*check) = 0;
949*f0865ec9SKyle Evans 	}
950*f0865ec9SKyle Evans 	else{
951*f0865ec9SKyle Evans 		(*check) = 1;
952*f0865ec9SKyle Evans 	}
953*f0865ec9SKyle Evans 
954*f0865ec9SKyle Evans err:
955*f0865ec9SKyle Evans 	return ret;
956*f0865ec9SKyle Evans }
957*f0865ec9SKyle Evans 
958*f0865ec9SKyle Evans /* Tells if the signature scheme is deterministic or not,
959*f0865ec9SKyle Evans  * e.g. if random nonces are used to produce signatures.
960*f0865ec9SKyle Evans  *
961*f0865ec9SKyle Evans  * 'check' is set to 1 if deterministic, 0 otherwise.
962*f0865ec9SKyle Evans  *
963*f0865ec9SKyle Evans  * Return value is 0 on success, -1 on error. 'check' is only meaningful on
964*f0865ec9SKyle Evans  * success.
965*f0865ec9SKyle Evans 
966*f0865ec9SKyle Evans  */
is_sign_deterministic(ec_alg_type sig_type,int * check)967*f0865ec9SKyle Evans int is_sign_deterministic(ec_alg_type sig_type, int *check)
968*f0865ec9SKyle Evans {
969*f0865ec9SKyle Evans 	int ret;
970*f0865ec9SKyle Evans 	const ec_sig_mapping *sig;
971*f0865ec9SKyle Evans 
972*f0865ec9SKyle Evans 	MUST_HAVE((check != NULL), ret, err);
973*f0865ec9SKyle Evans 
974*f0865ec9SKyle Evans 	ret = get_sig_by_type(sig_type, &sig); EG(ret, err);
975*f0865ec9SKyle Evans 	MUST_HAVE((sig != NULL), ret, err);
976*f0865ec9SKyle Evans 
977*f0865ec9SKyle Evans 	switch(sig_type) {
978*f0865ec9SKyle Evans #if defined(WITH_SIG_EDDSA25519)
979*f0865ec9SKyle Evans 	case EDDSA25519:
980*f0865ec9SKyle Evans 	case EDDSA25519CTX:
981*f0865ec9SKyle Evans 	case EDDSA25519PH:
982*f0865ec9SKyle Evans 		(*check) = 1;
983*f0865ec9SKyle Evans 		break;
984*f0865ec9SKyle Evans #endif
985*f0865ec9SKyle Evans #if defined(WITH_SIG_EDDSA448)
986*f0865ec9SKyle Evans 	case EDDSA448:
987*f0865ec9SKyle Evans 	case EDDSA448PH:
988*f0865ec9SKyle Evans 		(*check) = 1;
989*f0865ec9SKyle Evans 		break;
990*f0865ec9SKyle Evans #endif
991*f0865ec9SKyle Evans #if defined(WITH_SIG_DECDSA)
992*f0865ec9SKyle Evans 	case DECDSA:
993*f0865ec9SKyle Evans 		(*check) = 1;
994*f0865ec9SKyle Evans 		break;
995*f0865ec9SKyle Evans #endif
996*f0865ec9SKyle Evans 	default:
997*f0865ec9SKyle Evans 		(*check) = 0;
998*f0865ec9SKyle Evans 		break;
999*f0865ec9SKyle Evans 	}
1000*f0865ec9SKyle Evans 
1001*f0865ec9SKyle Evans err:
1002*f0865ec9SKyle Evans 	return ret;
1003*f0865ec9SKyle Evans }
1004*f0865ec9SKyle Evans 
1005*f0865ec9SKyle Evans 
1006*f0865ec9SKyle Evans /*
1007*f0865ec9SKyle Evans  * Bubble sort the table of numbers and the table of projective points
1008*f0865ec9SKyle Evans  * accordingly in ascending order. We only work on index numbers in the table
1009*f0865ec9SKyle Evans  * to avoid useless copies.
1010*f0865ec9SKyle Evans  */
_bubble_sort(verify_batch_scratch_pad * elements,u32 num)1011*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _bubble_sort(verify_batch_scratch_pad *elements, u32 num)
1012*f0865ec9SKyle Evans {
1013*f0865ec9SKyle Evans         u32 i, j;
1014*f0865ec9SKyle Evans         int ret, swapped;
1015*f0865ec9SKyle Evans 
1016*f0865ec9SKyle Evans         MUST_HAVE((elements != NULL), ret, err);
1017*f0865ec9SKyle Evans         MUST_HAVE((num >= 1), ret, err);
1018*f0865ec9SKyle Evans         for(i = 0; i < (num - 1); i++){
1019*f0865ec9SKyle Evans 		swapped = 0;
1020*f0865ec9SKyle Evans                 for(j = 0; j < (num - i - 1); j++){
1021*f0865ec9SKyle Evans                         int check;
1022*f0865ec9SKyle Evans 			u32 indexj, indexj_next;
1023*f0865ec9SKyle Evans 			indexj      = elements[j].index;
1024*f0865ec9SKyle Evans 			indexj_next = elements[j + 1].index;
1025*f0865ec9SKyle Evans                         ret = nn_cmp(&elements[indexj].number, &elements[indexj_next].number, &check); EG(ret, err);
1026*f0865ec9SKyle Evans                         if(check < 0){
1027*f0865ec9SKyle Evans                                 /* Swap the two elements */
1028*f0865ec9SKyle Evans                                 elements[j].index   = indexj_next;
1029*f0865ec9SKyle Evans                                 elements[j + 1].index = indexj;
1030*f0865ec9SKyle Evans 				swapped = 1;
1031*f0865ec9SKyle Evans                         }
1032*f0865ec9SKyle Evans                 }
1033*f0865ec9SKyle Evans 		/* If no swap occured in the inner loop, get out */
1034*f0865ec9SKyle Evans 		if(!swapped){
1035*f0865ec9SKyle Evans 			break;
1036*f0865ec9SKyle Evans 		}
1037*f0865ec9SKyle Evans         }
1038*f0865ec9SKyle Evans 
1039*f0865ec9SKyle Evans         ret = 0;
1040*f0865ec9SKyle Evans err:
1041*f0865ec9SKyle Evans         return ret;
1042*f0865ec9SKyle Evans }
1043*f0865ec9SKyle Evans 
1044*f0865ec9SKyle Evans /*
1045*f0865ec9SKyle Evans  * Bos-Coster algorithm, presented e.g. in https://ed25519.cr.yp.to/ed25519-20110705.pdf
1046*f0865ec9SKyle Evans  *
1047*f0865ec9SKyle Evans  * The Bos-Coster algorithm allows to optimize a sum of multi-scalar multiplications using
1048*f0865ec9SKyle Evans  * addition chains. This is used for example in batch signature verification of schemes
1049*f0865ec9SKyle Evans  * that support it.
1050*f0865ec9SKyle Evans  *
1051*f0865ec9SKyle Evans  */
ec_verify_bos_coster(verify_batch_scratch_pad * elements,u32 num,bitcnt_t bits)1052*f0865ec9SKyle Evans int ec_verify_bos_coster(verify_batch_scratch_pad *elements, u32 num, bitcnt_t bits)
1053*f0865ec9SKyle Evans {
1054*f0865ec9SKyle Evans 	int ret, check;
1055*f0865ec9SKyle Evans 	u32 i, index0, index1, max_bos_coster_iterations;
1056*f0865ec9SKyle Evans 
1057*f0865ec9SKyle Evans 	MUST_HAVE((elements != NULL), ret, err);
1058*f0865ec9SKyle Evans 	MUST_HAVE((num > 1), ret, err);
1059*f0865ec9SKyle Evans 
1060*f0865ec9SKyle Evans 	/* We fix our maximum attempts here.
1061*f0865ec9SKyle Evans 	 *
1062*f0865ec9SKyle Evans 	 * NOTE: this avoids "denial of service" when
1063*f0865ec9SKyle Evans 	 * providing scalars with too big discrepancies, as
1064*f0865ec9SKyle Evans 	 * the Bos-Coster algorithm supposes uniformly randomized
1065*f0865ec9SKyle Evans 	 * numbers ...
1066*f0865ec9SKyle Evans 	 * If we are provided with scalars with too big differences,
1067*f0865ec9SKyle Evans 	 * we end up looping for a very long time. In this case, we
1068*f0865ec9SKyle Evans 	 * rather quit with a specific error.
1069*f0865ec9SKyle Evans 	 *
1070*f0865ec9SKyle Evans 	 * The limit hereafter is fixed using the mean asymptotic complexity
1071*f0865ec9SKyle Evans 	 * of the algorithm in the nominal case (multiplied by the bit size
1072*f0865ec9SKyle Evans 	 * of num to be lax).
1073*f0865ec9SKyle Evans 	 */
1074*f0865ec9SKyle Evans 	MUST_HAVE((num * bits) >= num, ret, err);
1075*f0865ec9SKyle Evans 	MUST_HAVE((num * bits) >= bits, ret, err);
1076*f0865ec9SKyle Evans 	max_bos_coster_iterations = (num * bits);
1077*f0865ec9SKyle Evans 
1078*f0865ec9SKyle Evans         /********************************************/
1079*f0865ec9SKyle Evans         /****** Bos-Coster algorithm ****************/
1080*f0865ec9SKyle Evans         for(i = 0; i < num; i++){
1081*f0865ec9SKyle Evans                 elements[i].index = i;
1082*f0865ec9SKyle Evans         }
1083*f0865ec9SKyle Evans 	i = 0;
1084*f0865ec9SKyle Evans         do {
1085*f0865ec9SKyle Evans 		/* Sort the elements in descending order */
1086*f0865ec9SKyle Evans 		ret = _bubble_sort(elements, num); EG(ret, err);
1087*f0865ec9SKyle Evans                 /* Perform the addition */
1088*f0865ec9SKyle Evans 		index0 = elements[0].index;
1089*f0865ec9SKyle Evans 		index1 = elements[1].index;
1090*f0865ec9SKyle Evans 		ret = prj_pt_add(&elements[index1].point, &elements[index0].point,
1091*f0865ec9SKyle Evans 				 &elements[index1].point); EG(ret, err);
1092*f0865ec9SKyle Evans                 /* Check the two first integers */
1093*f0865ec9SKyle Evans 		ret = nn_cmp(&elements[index0].number, &elements[index1].number, &check);
1094*f0865ec9SKyle Evans                 /* Subtract the two first numbers */
1095*f0865ec9SKyle Evans                 ret = nn_sub(&elements[index0].number, &elements[index0].number,
1096*f0865ec9SKyle Evans                              &elements[index1].number); EG(ret, err);
1097*f0865ec9SKyle Evans 		i++;
1098*f0865ec9SKyle Evans 		if(i > max_bos_coster_iterations){
1099*f0865ec9SKyle Evans 			/* Give up with specific error code */
1100*f0865ec9SKyle Evans 			ret = -2;
1101*f0865ec9SKyle Evans 			goto err;
1102*f0865ec9SKyle Evans 		}
1103*f0865ec9SKyle Evans 	} while(check > 0);
1104*f0865ec9SKyle Evans 
1105*f0865ec9SKyle Evans 	index0 = elements[0].index;
1106*f0865ec9SKyle Evans 	/* Proceed with the last scalar multiplication */
1107*f0865ec9SKyle Evans 	ret = _prj_pt_unprotected_mult(&elements[index0].point, &elements[index0].number, &elements[index0].point);
1108*f0865ec9SKyle Evans 
1109*f0865ec9SKyle Evans 	/* The result is in point [0] of elements */
1110*f0865ec9SKyle Evans err:
1111*f0865ec9SKyle Evans 	return ret;
1112*f0865ec9SKyle Evans }
1113