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