xref: /freebsd/crypto/libecc/src/sig/ecsdsa_common.c (revision 0e8011faf58b743cc652e3b2ad0f7671227610df)
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/lib_ecc_config.h>
17 #if (defined(WITH_SIG_ECSDSA) || defined(WITH_SIG_ECOSDSA))
18 
19 #include <libecc/nn/nn_rand.h>
20 #include <libecc/nn/nn_mul_public.h>
21 #include <libecc/nn/nn_logical.h>
22 
23 #include <libecc/sig/ecsdsa_common.h>
24 #include <libecc/sig/sig_algs_internal.h>
25 #include <libecc/sig/ec_key.h>
26 #ifdef VERBOSE_INNER_VALUES
27 #define EC_SIG_ALG "EC[O]SDSA"
28 #endif
29 #include <libecc/utils/dbg_sig.h>
30 
31 /*
32  * Generic *internal* helper for EC-{,O}SDSA public key initialization
33  * functions. The function returns 0 on success, -1 on error.
34  */
35 int __ecsdsa_init_pub_key(ec_pub_key *out_pub, const ec_priv_key *in_priv,
36 			   ec_alg_type key_type)
37 {
38 	prj_pt_src_t G;
39 	int ret;
40 
41 	MUST_HAVE((out_pub != NULL), ret, err);
42 
43 	/* Zero init public key to be generated */
44 	ret = local_memset(out_pub, 0, sizeof(ec_pub_key)); EG(ret, err);
45 
46 	ret = priv_key_check_initialized_and_type(in_priv, key_type); EG(ret, err);
47 
48 	/* Y = xG */
49 	G = &(in_priv->params->ec_gen);
50 	/* Use blinding when computing point scalar multiplication */
51 	ret = prj_pt_mul_blind(&(out_pub->y), &(in_priv->x), G); EG(ret, err);
52 
53 	out_pub->key_type = key_type;
54 	out_pub->params = in_priv->params;
55 	out_pub->magic = PUB_KEY_MAGIC;
56 
57 err:
58 	return ret;
59 }
60 
61 /*
62  * Generic *internal* helper for EC{,O}SDSA signature length functions.
63  * It provides signature length when exported to a buffer based on hash
64  * algorithm digest and block size, generator point order bit length, and
65  * uderlying prime field order bit length. The function returns 0 on success,
66  * -1 on error. On success, signature length is provided via 'siglen' out
67  * parameter. The function returns 0 on success, -1 on error. On success,
68  * 'siglen' out parameter provides the length of signature fonction. It is
69  * not meaningful on error.
70  */
71 int __ecsdsa_siglen(u16 p_bit_len, u16 q_bit_len, u8 hsize, u8 blocksize,
72 		    u8 *siglen)
73 {
74 	int ret;
75 
76 	MUST_HAVE((siglen != NULL), ret, err);
77 	MUST_HAVE(((p_bit_len <= CURVES_MAX_P_BIT_LEN) &&
78 		   (q_bit_len <= CURVES_MAX_Q_BIT_LEN) &&
79 		   (hsize <= MAX_DIGEST_SIZE) && (blocksize <= MAX_BLOCK_SIZE)),
80 		   ret, err);
81 
82 	(*siglen) = (u8)ECSDSA_SIGLEN(hsize, q_bit_len);
83 	ret = 0;
84 
85 err:
86 	return ret;
87 }
88 
89 /*
90  * Generic *internal* EC-{,O}SDSA signature functions. There purpose is to
91  * allow passing specific hash functions and the random ephemeral
92  * key k, so that compliance tests against test vector be made
93  * without ugly hack in the code itself.
94  *
95  * The 'optimized' parameter tells the function if the r value of
96  * the signature is computed using only the x ccordinate of the
97  * the user's public key (normal version uses both coordinates).
98  *
99  * Normal:     r = h(Wx || Wy || m)
100  * Optimized : r = h(Wx || m)
101  *
102  *| IUF - ECSDSA/ECOSDSA signature
103  *|
104  *| I	1. Get a random value k in ]0, q[
105  *| I	2. Compute W = kG = (Wx, Wy)
106  *| IUF 3. Compute r = H(Wx [|| Wy] || m)
107  *|	   - In the normal version (ECSDSA), r = H(Wx || Wy || m).
108  *|	   - In the optimized version (ECOSDSA), r = H(Wx || m).
109  *|   F 4. Compute e = OS2I(r) mod q
110  *|   F 5. if e == 0, restart at step 1.
111  *|   F 6. Compute s = (k + ex) mod q.
112  *|   F 7. if s == 0, restart at step 1.
113  *|   F 8. Return (r, s)
114  *
115  * In the project, the normal mode is named ECSDSA, the optimized
116  * one is ECOSDSA.
117  *
118  * Implementation note:
119  *
120  * In ISO-14888-3, the option is provided to the developer to check
121  * whether r = 0 and restart the process in that case. Even if
122  * unlikely to trigger, that check makes a lot of sense because the
123  * verifier expects a non-zero value for r. In the  specification, r
124  * is a string (r =  H(Wx [|| Wy] || m)). But r is used in practice
125  * - both on the signer and the verifier - after conversion to an
126  * integer and reduction mod q. The value resulting from that step
127  * is named e (e = OS2I(r) mod q). The check for the case when r = 0
128  * should be replaced by a check for e = 0. This is more conservative
129  * and what is described above and done below in the implementation.
130  */
131 
132 #define ECSDSA_SIGN_MAGIC ((word_t)(0x743c03ae409d15c4ULL))
133 #define ECSDSA_SIGN_CHECK_INITIALIZED(A, ret, err) \
134 	MUST_HAVE((((void *)(A)) != NULL) && \
135 		  ((A)->magic == ECSDSA_SIGN_MAGIC), ret, err)
136 
137 /*
138  * Generic *internal* helper for EC-{,O}SDSA signature initialization functions.
139  * The function returns 0 on success, -1 on error.
140  */
141 int __ecsdsa_sign_init(struct ec_sign_context *ctx,
142 		       ec_alg_type key_type, int optimized)
143 {
144 	u8 Wx[BYTECEIL(CURVES_MAX_P_BIT_LEN)];
145 	u8 Wy[BYTECEIL(CURVES_MAX_P_BIT_LEN)];
146 	const ec_priv_key *priv_key;
147 	prj_pt_src_t G;
148 	bitcnt_t p_bit_len;
149 	u8 p_len;
150 	prj_pt kG;
151 	nn_src_t q;
152 	int ret;
153 	nn k;
154 	kG.magic = k.magic = WORD(0);
155 
156 	/* First, verify context has been initialized */
157 	ret = sig_sign_check_initialized(ctx); EG(ret, err);
158 
159 	/* Zero init points */
160 	ret = local_memset(&kG, 0, sizeof(prj_pt)); EG(ret, err);
161 
162 	/* Additional sanity checks on input params from context */
163 	ret = key_pair_check_initialized_and_type(ctx->key_pair, key_type); EG(ret, err);
164 	MUST_HAVE((ctx->h != NULL) && (ctx->h->digest_size <= MAX_DIGEST_SIZE) &&
165 		  (ctx->h->block_size <= MAX_BLOCK_SIZE), ret, err);
166 
167 	/* Make things more readable */
168 	priv_key = &(ctx->key_pair->priv_key);
169 	G = &(priv_key->params->ec_gen);
170 	q = &(priv_key->params->ec_gen_order);
171 	p_bit_len = priv_key->params->ec_fp.p_bitlen;
172 	p_len = (u8)BYTECEIL(p_bit_len);
173 
174 	dbg_nn_print("p", &(priv_key->params->ec_fp.p));
175 	dbg_nn_print("q", q);
176 	dbg_priv_key_print("x", priv_key);
177 	dbg_ec_point_print("G", G);
178 	dbg_pub_key_print("Y", &(ctx->key_pair->pub_key));
179 
180 	/* 1. Get a random value k in ]0, q[ */
181 #ifdef NO_KNOWN_VECTORS
182 	/* NOTE: when we do not need self tests for known vectors,
183 	 * we can be strict about random function handler!
184 	 * This allows us to avoid the corruption of such a pointer.
185 	 */
186 	/* Sanity check on the handler before calling it */
187 	MUST_HAVE((ctx->rand == nn_get_random_mod), ret, err);
188 #endif
189 	MUST_HAVE((ctx->rand != NULL), ret, err);
190 	ret = ctx->rand(&k, q); EG(ret, err);
191 	dbg_nn_print("k", &k);
192 
193 	/* 2. Compute W = kG = (Wx, Wy). */
194 #ifdef USE_SIG_BLINDING
195 	ret = prj_pt_mul_blind(&kG, &k, G); EG(ret, err);
196 #else
197 	ret = prj_pt_mul(&kG, &k, G); EG(ret, err);
198 #endif
199 	ret = prj_pt_unique(&kG, &kG); EG(ret, err);
200 	dbg_nn_print("W_x", &(kG.X.fp_val));
201 	dbg_nn_print("W_y", &(kG.Y.fp_val));
202 
203 	/*
204 	 * 3. Compute r = H(Wx [|| Wy] || m)
205 	 *
206 	 *    - In the normal version (ECSDSA), r = h(Wx || Wy || m).
207 	 *    - In the optimized version (ECOSDSA), r = h(Wx || m).
208 	 */
209 	/* Since we call a callback, sanity check our mapping */
210 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
211 	ret = ctx->h->hfunc_init(&(ctx->sign_data.ecsdsa.h_ctx)); EG(ret, err);
212 	ret = fp_export_to_buf(Wx, p_len, &(kG.X)); EG(ret, err);
213 	ret = ctx->h->hfunc_update(&(ctx->sign_data.ecsdsa.h_ctx), Wx, p_len); EG(ret, err);
214 	if (!optimized) {
215 		ret = fp_export_to_buf(Wy, p_len, &(kG.Y)); EG(ret, err);
216 		ret = ctx->h->hfunc_update(&(ctx->sign_data.ecsdsa.h_ctx), Wy,
217 					   p_len); EG(ret, err);
218 	}
219 	ret = local_memset(Wx, 0, p_len); EG(ret, err);
220 	ret = local_memset(Wy, 0, p_len); EG(ret, err);
221 
222 	/* Initialize the remaining of sign context. */
223 	ret = nn_copy(&(ctx->sign_data.ecsdsa.k), &k); EG(ret, err);
224 	ctx->sign_data.ecsdsa.magic = ECSDSA_SIGN_MAGIC;
225 
226  err:
227 	prj_pt_uninit(&kG);
228 	nn_uninit(&k);
229 
230 	PTR_NULLIFY(priv_key);
231 	PTR_NULLIFY(G);
232 	PTR_NULLIFY(q);
233 	VAR_ZEROIFY(p_len);
234 	VAR_ZEROIFY(p_bit_len);
235 
236 	return ret;
237 }
238 
239 /*
240  * Generic *internal* helper for EC-{,O}SDSA signature update functions.
241  * The function returns 0 on success, -1 on error.
242  */
243 int __ecsdsa_sign_update(struct ec_sign_context *ctx,
244 			 const u8 *chunk, u32 chunklen)
245 {
246 	int ret;
247 
248 	/*
249 	 * First, verify context has been initialized and private
250 	 * part too. This guarantees the context is an ECSDSA
251 	 * signature one and we do not update() or finalize()
252 	 * before init().
253 	 */
254 	ret = sig_sign_check_initialized(ctx); EG(ret, err);
255 	ECSDSA_SIGN_CHECK_INITIALIZED(&(ctx->sign_data.ecsdsa), ret, err);
256 
257 	/* 3. Compute r = H(Wx [|| Wy] || m) */
258 	/* Since we call a callback, sanity check our mapping */
259 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
260 	ret = ctx->h->hfunc_update(&(ctx->sign_data.ecsdsa.h_ctx), chunk, chunklen); EG(ret, err);
261 
262 err:
263 	return ret;
264 }
265 
266 /*
267  * Generic *internal* helper for EC-{,O}SDSA signature finalization functions.
268  * The function returns 0 on success, -1 on error.
269  */
270 int __ecsdsa_sign_finalize(struct ec_sign_context *ctx, u8 *sig, u8 siglen)
271 {
272 	nn_src_t q, x;
273 	nn s, e, ex;
274 	u8 r[MAX_DIGEST_SIZE];
275 	const ec_priv_key *priv_key;
276 	bitcnt_t q_bit_len;
277 	u8 r_len, s_len;
278 	u8 hsize;
279 	int ret;
280 	int iszero;
281 #ifdef USE_SIG_BLINDING
282 	/* b is the blinding mask */
283 	nn b, binv;
284 	b.magic = binv.magic = WORD(0);
285 #endif /* USE_SIG_BLINDING */
286 
287 	s.magic = e.magic = ex.magic = WORD(0);
288 
289 	/*
290 	 * First, verify context has been initialized and private
291 	 * part too. This guarantees the context is an ECSDSA
292 	 * signature one and we do not finalize() before init().
293 	 */
294 	ret = sig_sign_check_initialized(ctx); EG(ret, err);
295 	ECSDSA_SIGN_CHECK_INITIALIZED(&(ctx->sign_data.ecsdsa), ret, err);
296 	MUST_HAVE((sig != NULL), ret, err);
297 
298 	/* Make things more readable */
299 	priv_key = &(ctx->key_pair->priv_key);
300 	q = &(priv_key->params->ec_gen_order);
301 	x = &(priv_key->x);
302 	q_bit_len = priv_key->params->ec_gen_order_bitlen;
303 	hsize = ctx->h->digest_size;
304 	r_len = (u8)ECSDSA_R_LEN(hsize);
305 	s_len = (u8)ECSDSA_S_LEN(q_bit_len);
306 
307 	MUST_HAVE((siglen == ECSDSA_SIGLEN(hsize, q_bit_len)), ret, err);
308 
309 #ifdef USE_SIG_BLINDING
310 	ret = nn_get_random_mod(&b, q); EG(ret, err);
311 	dbg_nn_print("b", &b);
312 #endif /* USE_SIG_BLINDING */
313 
314 	/* 3. Compute r = H(Wx [|| Wy] || m) */
315 	ret = local_memset(r, 0, hsize); EG(ret, err);
316 	/* Since we call a callback, sanity check our mapping */
317 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
318 	ret = ctx->h->hfunc_finalize(&(ctx->sign_data.ecsdsa.h_ctx), r); EG(ret, err);
319 
320 	dbg_buf_print("r", r, r_len);
321 
322 	/* 4. Compute e = OS2I(r) mod q */
323 	ret = nn_init_from_buf(&e, r, r_len); EG(ret, err);
324 	ret = nn_mod(&e, &e, q); EG(ret, err);
325 	dbg_nn_print("e", &e);
326 
327 	/*
328 	 * 5. if e == 0, restart at step 1.
329 	 *
330 	 * As we cannot restart at that point (step 1. is in init()),
331 	 * we just stop and return an error.
332 	 */
333 	MUST_HAVE(!nn_iszero(&e, &iszero) && !iszero, ret, err);
334 
335 #ifdef USE_SIG_BLINDING
336 	/* Blind e with b */
337 	ret = nn_mod_mul(&e, &e, &b, q); EG(ret, err);
338 #endif /* USE_SIG_BLINDING */
339 
340 	/* 6. Compute s = (k + ex) mod q. */
341 	ret = nn_mod_mul(&ex, x, &e, q); EG(ret, err);
342 #ifdef USE_SIG_BLINDING
343 	/* Blind k with b */
344 	ret = nn_mod_mul(&s, &(ctx->sign_data.ecsdsa.k), &b, q); EG(ret, err);
345 	ret = nn_mod_add(&s, &s, &ex, q); EG(ret, err);
346 #else
347 	ret = nn_mod_add(&s, &(ctx->sign_data.ecsdsa.k), &ex, q); EG(ret, err);
348 #endif /* USE_SIG_BLINDING */
349 
350 #ifdef USE_SIG_BLINDING
351 	/* Unblind s */
352         /* NOTE: we use Fermat's little theorem inversion for
353          * constant time here. This is possible since q is prime.
354          */
355 	ret = nn_modinv_fermat(&binv, &b, q); EG(ret, err);
356 	ret = nn_mod_mul(&s, &s, &binv, q); EG(ret, err);
357 #endif /* USE_SIG_BLINDING */
358 	dbg_nn_print("s", &s);
359 
360 	/*
361 	 * 7. if s == 0, restart at step 1.
362 	 *
363 	 * As we cannot restart at that point (step 1. is in init()),
364 	 * we just stop and return an error.
365 	 */
366 	MUST_HAVE((!nn_iszero(&s, &iszero)) && (!iszero), ret, err);
367 
368 	/* 8. Return (r, s) */
369 	ret = local_memcpy(sig, r, r_len); EG(ret, err);
370 	ret = local_memset(r, 0, r_len); EG(ret, err);
371 	ret = nn_export_to_buf(sig + r_len, s_len, &s);
372 
373  err:
374 	nn_uninit(&s);
375 	nn_uninit(&e);
376 	nn_uninit(&ex);
377 #ifdef USE_SIG_BLINDING
378 	nn_uninit(&b);
379 	nn_uninit(&binv);
380 #endif /* USE_SIG_BLINDING */
381 
382 	/*
383 	 * We can now clear data part of the context. This will clear
384 	 * magic and avoid further reuse of the whole context.
385 	 */
386 	if(ctx != NULL){
387 		IGNORE_RET_VAL(local_memset(&(ctx->sign_data.ecsdsa), 0, sizeof(ecsdsa_sign_data)));
388 	}
389 
390 	/* Clean what remains on the stack */
391 	PTR_NULLIFY(q);
392 	PTR_NULLIFY(x);
393 	PTR_NULLIFY(priv_key);
394 	VAR_ZEROIFY(q_bit_len);
395 	VAR_ZEROIFY(r_len);
396 	VAR_ZEROIFY(s_len);
397 	VAR_ZEROIFY(hsize);
398 
399 	return ret;
400 }
401 
402 /* local helper for context sanity checks. Returns 0 on success, -1 on error. */
403 #define ECSDSA_VERIFY_MAGIC ((word_t)(0x8eac1ff89995bb0aULL))
404 #define ECSDSA_VERIFY_CHECK_INITIALIZED(A, ret, err) \
405 	MUST_HAVE((((const void *)(A)) != NULL) && \
406 		  ((A)->magic == ECSDSA_VERIFY_MAGIC), ret, err)
407 
408 /*
409  *| IUF - ECSDSA/ECOSDSA verification
410  *|
411  *| I	1. if s is not in ]0,q[, reject the signature.
412  *| I	2. Compute e = -r mod q
413  *| I	3. If e == 0, reject the signature.
414  *| I	4. Compute W' = sG + eY
415  *| IUF 5. Compute r' = H(W'x [|| W'y] || m)
416  *|	   - In the normal version (ECSDSA), r' = H(W'x || W'y || m).
417  *|	   - In the optimized version (ECOSDSA), r' = H(W'x || m).
418  *|   F 6. Accept the signature if and only if r and r' are the same
419  */
420 
421 /*
422  * Generic *internal* helper for EC-{,O}SDSA verification initialization functions.
423  * The function returns 0 on success, -1 on error.
424  */
425 int __ecsdsa_verify_init(struct ec_verify_context *ctx,
426 			 const u8 *sig, u8 siglen,
427 			 ec_alg_type key_type, int optimized)
428 {
429 	prj_pt_src_t G, Y;
430 	const ec_pub_key *pub_key;
431 	nn_src_t q;
432 	nn rmodq, e, r, s;
433 	prj_pt sG, eY;
434 	prj_pt_t Wprime;
435 	u8 Wprimex[BYTECEIL(CURVES_MAX_P_BIT_LEN)];
436 	u8 Wprimey[BYTECEIL(CURVES_MAX_P_BIT_LEN)];
437 	u8 p_len, r_len, s_len;
438 	bitcnt_t q_bit_len;
439 	u8 hsize;
440 	int ret, iszero, cmp;
441 
442 	rmodq.magic = e.magic = r.magic = s.magic = WORD(0);
443 	sG.magic = eY.magic = WORD(0);
444 
445 	/* NOTE: we reuse sG for Wprime to optimize local variables */
446 	Wprime = &sG;
447 
448 	/* First, verify context has been initialized */
449 	ret = sig_verify_check_initialized(ctx); EG(ret, err);
450 
451 	/* Zero init points */
452 	ret = local_memset(&sG, 0, sizeof(prj_pt)); EG(ret, err);
453 	ret = local_memset(&eY, 0, sizeof(prj_pt)); EG(ret, err);
454 
455 	/* Do some sanity checks on input params */
456 	ret = pub_key_check_initialized_and_type(ctx->pub_key, key_type); EG(ret, err);
457 	MUST_HAVE((ctx->h != NULL) && (ctx->h->digest_size <= MAX_DIGEST_SIZE) &&
458 		  (ctx->h->block_size <= MAX_BLOCK_SIZE), ret, err);
459 	MUST_HAVE((sig != NULL), ret, err);
460 
461 	/* Make things more readable */
462 	pub_key = ctx->pub_key;
463 	G = &(pub_key->params->ec_gen);
464 	Y = &(pub_key->y);
465 	q = &(pub_key->params->ec_gen_order);
466 	p_len = (u8)BYTECEIL(pub_key->params->ec_fp.p_bitlen);
467 	q_bit_len = pub_key->params->ec_gen_order_bitlen;
468 	hsize = ctx->h->digest_size;
469 	r_len = (u8)ECSDSA_R_LEN(hsize);
470 	s_len = (u8)ECSDSA_S_LEN(q_bit_len);
471 
472 	MUST_HAVE((siglen == ECSDSA_SIGLEN(hsize, q_bit_len)), ret, err);
473 
474 	/* 1. if s is not in ]0,q[, reject the signature. */
475 	ret = nn_init_from_buf(&s, sig + r_len, s_len); EG(ret, err);
476 	ret = nn_iszero(&s, &iszero); EG(ret, err);
477 	ret = nn_cmp(&s, q, &cmp); EG(ret, err);
478 	MUST_HAVE((!iszero) && (cmp < 0), ret, err);
479 
480 	/*
481 	 * 2. Compute e = -r mod q
482 	 *
483 	 * To avoid dealing w/ negative numbers, we simply compute
484 	 * e = -r mod q = q - (r mod q) (except when r is 0).
485 	 */
486 	ret = nn_init_from_buf(&r, sig, r_len); EG(ret, err);
487 	ret = nn_mod(&rmodq, &r, q); EG(ret, err);
488 	ret = nn_mod_neg(&e, &rmodq, q); EG(ret, err);
489 
490 	/* 3. If e == 0, reject the signature. */
491 	ret = nn_iszero(&e, &iszero); EG(ret, err);
492 	MUST_HAVE((!iszero), ret, err);
493 
494 	/* 4. Compute W' = sG + eY */
495 	ret = prj_pt_mul(&sG, &s, G); EG(ret, err);
496 	ret = prj_pt_mul(&eY, &e, Y); EG(ret, err);
497 	ret = prj_pt_add(Wprime, &sG, &eY); EG(ret, err);
498 	ret = prj_pt_unique(Wprime, Wprime); EG(ret, err);
499 
500 	/*
501 	 * 5. Compute r' = H(W'x [|| W'y] || m)
502 	 *
503 	 *    - In the normal version (ECSDSA), r = h(W'x || W'y || m).
504 	 *    - In the optimized version (ECOSDSA), r = h(W'x || m).
505 	 */
506 	/* Since we call a callback, sanity check our mapping */
507 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
508 	ret = ctx->h->hfunc_init(&(ctx->verify_data.ecsdsa.h_ctx)); EG(ret, err);
509 	ret = fp_export_to_buf(Wprimex, p_len, &(Wprime->X)); EG(ret, err);
510 	/* Since we call a callback, sanity check our mapping */
511 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
512 	ret = ctx->h->hfunc_update(&(ctx->verify_data.ecsdsa.h_ctx), Wprimex, p_len); EG(ret, err);
513 	if (!optimized) {
514 		ret = fp_export_to_buf(Wprimey, p_len, &(Wprime->Y)); EG(ret, err);
515 		/* Since we call a callback, sanity check our mapping */
516 		ret =  hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
517 		ret = ctx->h->hfunc_update(&(ctx->verify_data.ecsdsa.h_ctx),
518 					   Wprimey, p_len); EG(ret, err);
519 	}
520 	ret = local_memset(Wprimex, 0, p_len); EG(ret, err);
521 	ret = local_memset(Wprimey, 0, p_len); EG(ret, err);
522 
523 	/* Initialize the remaining of verify context. */
524 	ret = local_memcpy(ctx->verify_data.ecsdsa.r, sig, r_len); EG(ret, err);
525 	ret = nn_copy(&(ctx->verify_data.ecsdsa.s), &s); EG(ret, err);
526 
527 	ctx->verify_data.ecsdsa.magic = ECSDSA_VERIFY_MAGIC;
528 
529  err:
530 	nn_uninit(&rmodq);
531 	nn_uninit(&e);
532 	nn_uninit(&r);
533 	nn_uninit(&s);
534 	prj_pt_uninit(&sG);
535 	prj_pt_uninit(&eY);
536 
537 	/* Clean what remains on the stack */
538 	PTR_NULLIFY(Wprime);
539 	PTR_NULLIFY(G);
540 	PTR_NULLIFY(Y);
541 	PTR_NULLIFY(pub_key);
542 	PTR_NULLIFY(q);
543 	VAR_ZEROIFY(p_len);
544 	VAR_ZEROIFY(r_len);
545 	VAR_ZEROIFY(s_len);
546 	VAR_ZEROIFY(q_bit_len);
547 	VAR_ZEROIFY(hsize);
548 
549 	return ret;
550 }
551 
552 /*
553  * Generic *internal* helper for EC-{,O}SDSA verification update functions.
554  * The function returns 0 on success, -1 on error.
555  */
556 int __ecsdsa_verify_update(struct ec_verify_context *ctx,
557 			   const u8 *chunk, u32 chunklen)
558 {
559 	int ret;
560 
561 	/*
562 	 * First, verify context has been initialized and public
563 	 * part too. This guarantees the context is an ECSDSA
564 	 * verification one and we do not update() or finalize()
565 	 * before init().
566 	 */
567 	ret = sig_verify_check_initialized(ctx); EG(ret, err);
568 	ECSDSA_VERIFY_CHECK_INITIALIZED(&(ctx->verify_data.ecsdsa), ret, err);
569 
570 	/* 5. Compute r' = H(W'x [|| W'y] || m) */
571 	/* Since we call a callback, sanity check our mapping */
572 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
573 	ret = ctx->h->hfunc_update(&(ctx->verify_data.ecsdsa.h_ctx), chunk,
574 				chunklen);
575 
576 err:
577 	return ret;
578 }
579 
580 /*
581  * Generic *internal* helper for EC-{,O}SDSA verification finalization
582  * functions. The function returns 0 on success, -1 on error.
583  */
584 int __ecsdsa_verify_finalize(struct ec_verify_context *ctx)
585 {
586 	u8 r_prime[MAX_DIGEST_SIZE];
587 	u32 r_len;
588 	int ret, check;
589 
590 	/*
591 	 * First, verify context has been initialized and public
592 	 * part too. This guarantees the context is an ECSDSA
593 	 * verification one and we do not finalize() before init().
594 	 */
595 	ret = sig_verify_check_initialized(ctx); EG(ret, err);
596 	ECSDSA_VERIFY_CHECK_INITIALIZED(&(ctx->verify_data.ecsdsa), ret, err);
597 
598 	r_len = ECSDSA_R_LEN(ctx->h->digest_size);
599 
600 	/* 5. Compute r' = H(W'x [|| W'y] || m) */
601 	/* Since we call a callback, sanity check our mapping */
602 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
603 	ret = ctx->h->hfunc_finalize(&(ctx->verify_data.ecsdsa.h_ctx), r_prime); EG(ret, err);
604 
605 	/* 6. Accept the signature if and only if r and r' are the same */
606 	ret = are_equal(ctx->verify_data.ecsdsa.r, r_prime, r_len, &check); EG(ret, err);
607 	ret = check ? 0 : -1;
608 
609 err:
610 	IGNORE_RET_VAL(local_memset(r_prime, 0, sizeof(r_prime)));
611 	/*
612 	 * We can now clear data part of the context. This will clear
613 	 * magic and avoid further reuse of the whole context.
614 	 */
615 	if(ctx != NULL){
616 		IGNORE_RET_VAL(local_memset(&(ctx->verify_data.ecsdsa), 0,
617 			     sizeof(ecsdsa_verify_data)));
618 	}
619 
620 	/* Clean what remains on the stack */
621 	VAR_ZEROIFY(r_len);
622 
623 	return ret;
624 }
625 
626 #else /* (defined(WITH_SIG_ECSDSA) || defined(WITH_SIG_ECOSDSA)) */
627 
628 /*
629  * Dummy definition to avoid the empty translation unit ISO C warning
630  */
631 typedef int dummy;
632 #endif /* (defined(WITH_SIG_ECSDSA) || defined(WITH_SIG_ECOSDSA)) */
633