xref: /freebsd/crypto/libecc/src/sig/sm2.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
1 /*
2  *  Copyright (C) 2021 - 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  *
8  *  This software is licensed under a dual BSD and GPL v2 license.
9  *  See LICENSE file at the root folder of the project.
10  */
11 
12 #include <libecc/lib_ecc_config.h>
13 #ifdef WITH_SIG_SM2
14 
15 #include <libecc/nn/nn_rand.h>
16 #include <libecc/nn/nn_mul_public.h>
17 #include <libecc/nn/nn_logical.h>
18 
19 #include <libecc/sig/sig_algs_internal.h>
20 #include <libecc/sig/ec_key.h>
21 #include <libecc/utils/utils.h>
22 #ifdef VERBOSE_INNER_VALUES
23 #define EC_SIG_ALG "SM2"
24 #endif
25 #include <libecc/utils/dbg_sig.h>
26 
27 /*
28  * NOTE: SM2 has an oddity in private key generation when compared to
29  * other EC*DSA style signature algorithms described in ISO14888-3:
30  * the private key x MUST be in ]0, q-1[ instead of ]0, q[ (this is actually
31  * explained by the fact that (1 + x) must be inversible modulo q during the
32  * signature process).
33  *
34  * Hence the following specific key generation function.
35  *
36  */
sm2_gen_priv_key(ec_priv_key * priv_key)37 int sm2_gen_priv_key(ec_priv_key *priv_key)
38 {
39 	int ret;
40 	nn tmp;
41 	tmp.magic = WORD(0);
42 
43 	ret = priv_key_check_initialized_and_type(priv_key, SM2); EG(ret, err);
44 
45 	/* Get a random value in ]0,q-1[ where q is the group generator order */
46 	ret = nn_init(&tmp, 0); EG(ret, err);
47 	ret = nn_dec(&tmp,  &(priv_key->params->ec_gen_order)); EG(ret, err);
48 	ret = nn_get_random_mod(&(priv_key->x), &tmp);
49 
50 err:
51 	nn_uninit(&tmp);
52 
53 	return ret;
54 }
55 
sm2_init_pub_key(ec_pub_key * out_pub,const ec_priv_key * in_priv)56 int sm2_init_pub_key(ec_pub_key *out_pub, const ec_priv_key *in_priv)
57 {
58 	prj_pt_src_t G;
59 	int ret, cmp;
60 	nn tmp;
61 	tmp.magic = WORD(0);
62 
63 	MUST_HAVE((out_pub != NULL), ret, err);
64 
65 	ret = priv_key_check_initialized_and_type(in_priv, SM2); EG(ret, err);
66 
67 	/*
68 	 * We verify that the private key is valid, i.e. in
69 	 * ]0, q-1[. This excluded q-1 is an oddity but is what the
70 	 * ISO14888-3:2018 has.
71 	 */
72 	ret = nn_init(&tmp, 0); EG(ret, err);
73 	ret = nn_dec(&tmp, &in_priv->params->ec_gen_order); EG(ret, err);
74 	/* If x >= (q - 1), this is an error */
75 	MUST_HAVE((!nn_cmp(&(in_priv->x), &tmp, &cmp)) && (cmp < 0), ret, err);
76 
77 	/* Y = xG */
78 	G = &(in_priv->params->ec_gen);
79 
80 	/* Zero init public key to be generated */
81 	ret = local_memset(out_pub, 0, sizeof(ec_pub_key)); EG(ret, err);
82 
83 	/* Use blinding with scalar_b when computing point scalar multiplication */
84 	ret = prj_pt_mul_blind(&(out_pub->y), &(in_priv->x), G); EG(ret, err);
85 
86 	out_pub->key_type = SM2;
87 	out_pub->params = in_priv->params;
88 	out_pub->magic = PUB_KEY_MAGIC;
89 
90 err:
91 	nn_uninit(&tmp);
92 
93 	return ret;
94 }
95 
sm2_siglen(u16 p_bit_len,u16 q_bit_len,u8 hsize,u8 blocksize,u8 * siglen)96 int sm2_siglen(u16 p_bit_len, u16 q_bit_len, u8 hsize, u8 blocksize, u8 *siglen)
97 {
98 	int ret;
99 
100 	MUST_HAVE((siglen != NULL), ret, err);
101 	MUST_HAVE((p_bit_len <= CURVES_MAX_P_BIT_LEN) &&
102 		  (q_bit_len <= CURVES_MAX_Q_BIT_LEN) &&
103 		  (hsize <= MAX_DIGEST_SIZE) && (blocksize <= MAX_BLOCK_SIZE), ret, err);
104 
105 	(*siglen) = (u8)SM2_SIGLEN(q_bit_len);
106 	ret = 0;
107 
108 err:
109 	return ret;
110 }
111 
112 /*
113  * Helper to compute Z from user ID, curve parameters, public key and hash
114  * function as defined in section 6.12.4.3 of ISO14888-3:2018. The function
115  * returns 0 on success, -1 on error. On success, the number of bytes
116  * written to Z is provided using Zlen. On input, Zlen provides the size of
117  * Z buffer, which must be large enough for selected hash function (Z has
118  * the digest size of the hash function). 'id' buffer of size 'id_len' must
119  * be smaller than SM2_MAX_ID_LEN (see sm2.h).
120  *
121  * Z = h(ENTL || ID || FE2BS(p, a) || FE2BS(p, b) || FE2BS(p, Gx) ||
122  *       FE2BS(p, Gy) || FE2BS(p, Yx) || FE2BS(p, Yy)).
123  *
124  * with:
125  *
126  *  - GF(p), Finite field of cardinality p.
127  *  - Curve Weierstrass Equation y^2 = x^3 + a * x + b.
128  *  - ID string containing an identifier of the signer
129  *  - G = (Gx, Gy) an element of order q in E.
130  *  - entlen is the bit-length of ID and ENTL the two bytes string transformed
131  *    from the integer entlen, i.e. ENTL = I2BS(12, entlen).
132  *
133  */
134 #define Z_INPUT_MAX_LEN (2 + SM2_MAX_ID_LEN + (6 * BYTECEIL(CURVES_MAX_P_BIT_LEN)))
135 
sm2_compute_Z(u8 * Z,u16 * Zlen,const u8 * id,u16 id_len,const ec_pub_key * pub_key,hash_alg_type hash_type)136 ATTRIBUTE_WARN_UNUSED_RET static int sm2_compute_Z(u8 *Z, u16 *Zlen, const u8 *id, u16 id_len,
137 		  const ec_pub_key *pub_key, hash_alg_type hash_type)
138 {
139 	u16 hsize, entlen, p_len;
140 	u8 buf[2 * BYTECEIL(CURVES_MAX_P_BIT_LEN)];
141 	const hash_mapping *hm;
142 	prj_pt_src_t G, Y;
143 	hash_context hctx;
144 	bitcnt_t p_bit_len;
145 	fp_src_t a, b;
146 	int ret;
147 
148 	MUST_HAVE((Z != NULL) && (Zlen != NULL), ret, err);
149 	MUST_HAVE((id != NULL) && (pub_key != NULL), ret, err);
150 	/* Maximum size is Entlen on 16 bits in *bits*, i.e. 8192 bytes */
151 	MUST_HAVE((id_len <= SM2_MAX_ID_LEN), ret, err);
152 	ret = pub_key_check_initialized_and_type(pub_key, SM2); EG(ret, err);
153 
154 	ret = get_hash_by_type(hash_type, &hm); EG(ret, err);
155 	MUST_HAVE((hm != NULL), ret, err);
156 
157 	/* Zlen must be large enough to receive digest */
158 	hsize = hm->digest_size;
159 	MUST_HAVE((*Zlen) >= hsize, ret, err);
160 
161 	/* Make things more readable */
162 	G = &(pub_key->params->ec_gen);
163 	Y = &(pub_key->y);
164 	p_bit_len = pub_key->params->ec_fp.p_bitlen;
165 	p_len = (u8)BYTECEIL(p_bit_len);
166 	entlen = (u16)(id_len * 8);
167 	a = &(pub_key->params->ec_curve.a);
168 	b = &(pub_key->params->ec_curve.b);
169 
170 	/* Since we call a callback, sanity check our mapping */
171 	ret = hash_mapping_callbacks_sanity_check(hm); EG(ret, err);
172 	ret = hm->hfunc_init(&hctx); EG(ret, err);
173 
174 	/* ENTL */
175 	buf[0] = (u8)((entlen >> 8) & 0xff);
176 	buf[1] = (u8)(entlen & 0xff);
177 	ret = hm->hfunc_update(&hctx, buf, 2); EG(ret, err);
178 
179 	/* ID */
180 	ret = hm->hfunc_update(&hctx, id, id_len); EG(ret, err);
181 
182 	/* FE2BS(p, a) */
183 	ret = fp_export_to_buf(buf, p_len, a); EG(ret, err);
184 	ret = hm->hfunc_update(&hctx, buf, p_len); EG(ret, err);
185 
186 	/* FE2BS(p, b) */
187 	ret = fp_export_to_buf(buf, p_len, b); EG(ret, err);
188 	ret = hm->hfunc_update(&hctx, buf, p_len); EG(ret, err);
189 
190 	/* FE2BS(p, Gx) || FE2BS(p, Gy) */
191 	ret = prj_pt_export_to_aff_buf(G, buf, (u32)(2 * p_len)); EG(ret, err);
192 	ret = hm->hfunc_update(&hctx, buf, (u32)(2 * p_len)); EG(ret, err);
193 
194 	/* FE2BS(p, Yx) || FE2BS(p, Yy) */
195 	ret = prj_pt_export_to_aff_buf(Y, buf, (u32)(2 * p_len)); EG(ret, err);
196 	ret = hm->hfunc_update(&hctx, buf, (u32)(2 * p_len)); EG(ret, err);
197 
198 	/* Let's now finalize hash computation */
199 	ret = hm->hfunc_finalize(&hctx, Z); EG(ret, err);
200 	dbg_buf_print("Z", Z, hsize);
201 
202 	ret = local_memset(buf, 0, sizeof(buf)); EG(ret, err);
203 	ret = local_memset(&hctx, 0, sizeof(hctx)); EG(ret, err);
204 
205 	(*Zlen) = hsize;
206 
207 err:
208 	if (ret && (Zlen != NULL)){
209 		(*Zlen) = 0;
210 	}
211 	return ret;
212 }
213 
214 
215 /*
216  * Generic *internal* SM2 signature functions (init, update and finalize).
217  * Their purpose is to allow passing a specific hash function (along with
218  * its output size) and the random ephemeral key k, so that compliance
219  * tests against test vectors can be made without ugly hack in the code
220  * itself.
221  *
222  * Global SM2 signature process is as follows (I,U,F provides information
223  * in which function(s) (init(), update() or finalize()) a specific step
224  * is performed):
225  *
226  *| IUF  - SM2 signature
227  *|
228  *|  UF  1. set M1 = Z || M   (See (*) below)
229  *|   F  2. Compute H = h(M1)
230  *|   F  3. Get a random value k in ]0,q[
231  *|   F  4. Compute W = (W_x,W_y) = kG
232  *|   F  5. Compute r = (OS2I(H) + Wx) mod q
233  *|   F  6. If r is 0, restart the process at step 3.
234  *|   F  7. If r + k is q, restart the process at step 3.
235  *|   F  8. Compute s = ((1 + x)^(-1) * (k - rx)) mod q
236  *|   F  9. If s is 0, restart the process at step 3.
237  *|   F  10. Export r and s
238  *
239  * (*) It is user responsibility to pass the ID string in the optional ancillary
240  *     data of the API.
241  */
242 
243 #define SM2_SIGN_MAGIC ((word_t)(0x324300884035dae8ULL))
244 #define SM2_SIGN_CHECK_INITIALIZED(A, ret, err) \
245 	MUST_HAVE((((void *)(A)) != NULL) && ((A)->magic == SM2_SIGN_MAGIC), ret, err)
246 
_sm2_sign_init(struct ec_sign_context * ctx)247 int _sm2_sign_init(struct ec_sign_context *ctx)
248 {
249 	int ret;
250 	u8 Z[Z_INPUT_MAX_LEN];
251 	u16 Zlen;
252 
253 	/* First, verify context has been initialized */
254 	ret = sig_sign_check_initialized(ctx); EG(ret, err);
255 
256 	/* Additional sanity checks on input params from context */
257 	ret = key_pair_check_initialized_and_type(ctx->key_pair, SM2); EG(ret, err);
258 	MUST_HAVE((ctx->h != NULL) && (ctx->h->digest_size <= MAX_DIGEST_SIZE) &&
259 		  (ctx->h->block_size <= MAX_BLOCK_SIZE), ret, err);
260 
261 	/*
262 	 * Initialize hash context stored in our private part of context
263 	 * and record data init has been done
264 	 */
265 	/* Since we call a callback, sanity check our mapping */
266 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
267 	ret = ctx->h->hfunc_init(&(ctx->sign_data.sm2.h_ctx)); EG(ret, err);
268 
269 	/* Compute Z from the ID */
270 	ret = local_memset(Z, 0, sizeof(Z)); EG(ret, err);
271 	Zlen = sizeof(Z);
272 	ret = sm2_compute_Z(Z, &Zlen, ctx->adata, ctx->adata_len,
273 			    &(ctx->key_pair->pub_key), ctx->h->type); EG(ret, err);
274 
275 	/* Update the hash function with Z */
276 	/* Since we call a callback, sanity check our mapping */
277 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
278 	ret = ctx->h->hfunc_update(&(ctx->sign_data.sm2.h_ctx), Z, Zlen); EG(ret, err);
279 
280 	ctx->sign_data.sm2.magic = SM2_SIGN_MAGIC;
281 
282 err:
283 	VAR_ZEROIFY(Zlen);
284 
285 	return ret;
286 }
287 
_sm2_sign_update(struct ec_sign_context * ctx,const u8 * chunk,u32 chunklen)288 int _sm2_sign_update(struct ec_sign_context *ctx,
289 		       const u8 *chunk, u32 chunklen)
290 {
291 	int ret;
292 
293 	/*
294 	 * First, verify context has been initialized and private part too.
295 	 * This guarantees the context is an SM2 signature one and we do not
296 	 * update() or finalize() before init().
297 	 */
298 	ret = sig_sign_check_initialized(ctx); EG(ret, err);
299 	SM2_SIGN_CHECK_INITIALIZED(&(ctx->sign_data.sm2), ret, err);
300 
301 	/* 1. Compute h = H(m) */
302 	/* Since we call a callback, sanity check our mapping */
303 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
304 	ret = ctx->h->hfunc_update(&(ctx->sign_data.sm2.h_ctx), chunk, chunklen);
305 
306 err:
307 	return ret;
308 }
309 
_sm2_sign_finalize(struct ec_sign_context * ctx,u8 * sig,u8 siglen)310 int _sm2_sign_finalize(struct ec_sign_context *ctx, u8 *sig, u8 siglen)
311 {
312 	const ec_priv_key *priv_key;
313 	u8 hash[MAX_DIGEST_SIZE];
314 	bitcnt_t q_bit_len;
315 	u8 hsize, q_len;
316 	prj_pt_src_t G;
317 	nn_src_t q, x;
318 	prj_pt kG;
319 	int ret, iszero, cmp;
320 	nn k, r, s, tmp, tmp2, tmp3;
321 #ifdef USE_SIG_BLINDING
322 	nn b;        /* blinding mask */
323 	b.magic = WORD(0);
324 #endif
325 
326 	kG.magic = WORD(0);
327 	k.magic = r.magic = s.magic = tmp.magic = tmp2.magic = tmp3.magic = WORD(0);
328 
329 	/*
330 	 * First, verify context has been initialized and private part too.
331 	 * This guarantees the context is an SM2 signature one and we do not
332 	 * update() or finalize() before init().
333 	 */
334 	ret = sig_sign_check_initialized(ctx); EG(ret, err);
335 	SM2_SIGN_CHECK_INITIALIZED(&(ctx->sign_data.sm2), ret, err);
336 	MUST_HAVE((sig != NULL), ret, err);
337 
338 	/* Zero init out point */
339 	ret = local_memset(&kG, 0, sizeof(prj_pt)); EG(ret, err);
340 
341 	/* Make things more readable */
342 	priv_key = &(ctx->key_pair->priv_key);
343 	q = &(priv_key->params->ec_gen_order);
344 	q_bit_len = priv_key->params->ec_gen_order_bitlen;
345 	G = &(priv_key->params->ec_gen);
346 	q_len = (u8)BYTECEIL(q_bit_len);
347 	x = &(priv_key->x);
348 	hsize = ctx->h->digest_size;
349 
350 	dbg_nn_print("p", &(priv_key->params->ec_fp.p));
351 	dbg_nn_print("q", &(priv_key->params->ec_gen_order));
352 	dbg_priv_key_print("x", priv_key);
353 	dbg_ec_point_print("G", &(priv_key->params->ec_gen));
354 	dbg_pub_key_print("Y", &(ctx->key_pair->pub_key));
355 
356 	/* Check given signature buffer length has the expected size */
357 	MUST_HAVE((siglen == SM2_SIGLEN(q_bit_len)), ret, err);
358 
359 	ret = local_memset(hash, 0, hsize); EG(ret, err);
360 	/* Since we call a callback, sanity check our mapping */
361 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
362 
363 	/* 2. Compute H = h(M1) */
364 	ret = ctx->h->hfunc_finalize(&(ctx->sign_data.sm2.h_ctx), hash); EG(ret, err);
365 	dbg_buf_print("h", hash, hsize);
366 
367  restart:
368 
369 	/* 3. Get a random value k in ]0,q[ */
370 #ifdef NO_KNOWN_VECTORS
371 	/* NOTE: when we do not need self tests for known vectors,
372 	 * we can be strict about random function handler!
373 	 * This allows us to avoid the corruption of such a pointer.
374 	 */
375 	/* Sanity check on the handler before calling it */
376 	MUST_HAVE(ctx->rand == nn_get_random_mod, ret, err);
377 #endif
378 	ret = ctx->rand(&k, q); EG(ret, err);
379 	dbg_nn_print("k", &k);
380 
381 	/* 4. Compute W = (W_x,W_y) = kG */
382 #ifdef USE_SIG_BLINDING
383 	ret = prj_pt_mul_blind(&kG, &k, G); EG(ret, err);
384 #else
385 	ret = prj_pt_mul(&kG, &k, G); EG(ret, err);
386 #endif /* USE_SIG_BLINDING */
387 	ret = prj_pt_unique(&kG, &kG); EG(ret, err);
388 
389 	dbg_nn_print("W_x", &(kG.X.fp_val));
390 	dbg_nn_print("W_y", &(kG.Y.fp_val));
391 
392 	/* 5. Compute r = (OS2I(H) + Wx) mod q */
393 	ret = nn_init_from_buf(&tmp, hash, hsize); EG(ret, err);
394 	ret = local_memset(hash, 0, hsize); EG(ret, err);
395 	dbg_nn_print("OS2I(H)", &tmp);
396 	ret = nn_add(&tmp2, &tmp, &(kG.X.fp_val)); EG(ret, err);
397 	ret = nn_mod(&r, &tmp2, q); EG(ret, err);
398 	dbg_nn_print("r", &r);
399 
400 	/* 6. If r is 0, restart the process at step 3. */
401 	ret = nn_iszero(&r, &iszero); EG(ret, err);
402 	if (iszero) {
403 		goto restart;
404 	}
405 
406 	/* 7. If r + k is q, restart the process at step 3. */
407 	ret = nn_add(&tmp, &r, q); EG(ret, err);
408 	ret = nn_cmp(&tmp, q, &cmp); EG(ret, err);
409 	if (cmp == 0) {
410 		goto restart;
411 	}
412 
413 	/* 8. Compute s = ((1 + x)^(-1) * (k - rx)) mod q */
414 #ifdef USE_SIG_BLINDING
415 	/*
416 	 * With blinding enabled, the computation above is performed in the
417 	 * following way s = ((b*(1 + x))^(-1) * (kb - (br)x)) mod q
418 	 */
419 	ret = nn_get_random_mod(&b, q); EG(ret, err);
420 	dbg_nn_print("b", &b);
421 	ret = nn_inc(&tmp2, x); EG(ret, err);
422 	ret = nn_mod_mul(&tmp2, &tmp2, &b, q); EG(ret, err);
423         /* NOTE: we use Fermat's little theorem inversion for
424          * constant time here. This is possible since q is prime.
425          */
426 	ret = nn_modinv_fermat(&tmp, &tmp2, q); EG(ret, err); /* tmp = (b*(1 + x))^(-1) */
427 	dbg_nn_print("(b*(1 + x))^(-1)", &tmp);
428 	ret = nn_mod_mul(&tmp3, &r, &b, q); EG(ret, err); /* rb */
429 	ret = nn_mod_mul(&k, &k, &b, q); EG(ret, err); /* kb */
430 	ret = nn_mod_mul(&tmp3, &tmp3, x, q); EG(ret, err); /* (rb)x mod q */
431 	ret = nn_mod_sub(&tmp2, &k, &tmp3, q); EG(ret, err); /* tmp2 = (kb - (rb)x) mod q */
432 	ret = nn_mod_mul(&s, &tmp, &tmp2, q); EG(ret, err);
433 	dbg_nn_print("s", &s);
434 #else
435 	ret = nn_inc(&tmp2, x); EG(ret, err);
436         /* NOTE: we use Fermat's little theorem inversion for
437          * constant time here. This is possible since q is prime.
438          */
439 	ret = nn_modinv_fermat(&tmp, &tmp2, q); EG(ret, err); /* tmp = (1 + x)^(-1) */
440 	dbg_nn_print("(1 + x)^(-1)", &tmp);
441 	ret = nn_mod_mul(&tmp3, &r, x, q); EG(ret, err); /* rx mod q */
442 	ret = nn_mod_sub(&tmp2, &k, &tmp3, q); EG(ret, err); /* tmp2 = (k - rx) mod q */
443 	ret = nn_mod_mul(&s, &tmp, &tmp2, q); EG(ret, err);
444 	dbg_nn_print("s", &s);
445 #endif
446 
447 	/* 9. If s is 0, restart the process at step 3. */
448 	ret = nn_iszero(&s, &iszero); EG(ret, err);
449 	if (iszero) {
450 		goto restart;
451 	}
452 
453 	/* 10. Export r and s */
454 	ret = nn_export_to_buf(sig, q_len, &r); EG(ret, err);
455 	ret = nn_export_to_buf(sig + q_len, q_len, &s);
456 
457 err:
458 	prj_pt_uninit(&kG);
459 	nn_uninit(&k);
460 	nn_uninit(&r);
461 	nn_uninit(&s);
462 	nn_uninit(&tmp);
463 	nn_uninit(&tmp2);
464 	nn_uninit(&tmp3);
465 #ifdef USE_SIG_BLINDING
466 	nn_uninit(&b);
467 #endif
468 	/*
469 	 * We can now clear data part of the context. This will clear
470 	 * magic and avoid further reuse of the whole context.
471 	 */
472 	IGNORE_RET_VAL(local_memset(&(ctx->sign_data.sm2), 0, sizeof(sm2_sign_data)));
473 
474 	/* Clean what remains on the stack */
475 	PTR_NULLIFY(priv_key);
476 	PTR_NULLIFY(G);
477 	PTR_NULLIFY(q);
478 	PTR_NULLIFY(x);
479 	VAR_ZEROIFY(q_len);
480 	VAR_ZEROIFY(q_bit_len);
481 	VAR_ZEROIFY(hsize);
482 
483 	return ret;
484 }
485 
486 
487 /*
488  * Generic *internal* SM2 verification functions (init, update and finalize).
489  * Their purpose is to allow passing a specific hash function (along with
490  * its output size) and the random ephemeral key k, so that compliance
491  * tests against test vectors can be made without ugly hack in the code
492  * itself.
493  *
494  * Global SM2 verification process is as follows (I,U,F provides information
495  * in which function(s) (init(), update() or finalize()) a specific step is
496  * performed):
497  *
498  *| IUF  - SM2 verification
499  *|
500  *| I   1. Reject the signature if r or s is 0 or >= q.
501  *|  UF 2. Compute h = H(M1) w/ M1 = Z || M   (See (*) below)
502  *|   F 3. Compute t = r + s mod q
503  *|   F 4. Reject signature if t is 0
504  *|   F 5. Compute e = OS2I(h) mod q
505  *|   F 6. Compute W' = sG + tY
506  *|   F 7. If W' is the point at infinity, reject the signature.
507  *|   F 8. Compute r' = (e + W'_x) mod q
508  *|   F 9. Accept the signature if and only if r equals r'
509  *
510  * (*) It is user responsibility to pass the ID string in the optional ancillary
511  *     data of the API.
512  */
513 
514 #define SM2_VERIFY_MAGIC ((word_t)(0x9177c61e777f9f22ULL))
515 #define SM2_VERIFY_CHECK_INITIALIZED(A, ret, err) \
516 	MUST_HAVE((((void *)(A)) != NULL) && ((A)->magic == SM2_VERIFY_MAGIC), ret, err)
517 
_sm2_verify_init(struct ec_verify_context * ctx,const u8 * sig,u8 siglen)518 int _sm2_verify_init(struct ec_verify_context *ctx,
519 		       const u8 *sig, u8 siglen)
520 {
521 	bitcnt_t q_bit_len;
522 	u8 q_len;
523 	nn_src_t q;
524 	nn *r = NULL, *s = NULL;
525 	int ret, iszero1, iszero2, cmp1, cmp2;
526 	u8 Z[Z_INPUT_MAX_LEN];
527 	u16 Zlen;
528 
529 	/* First, verify context has been initialized */
530 	ret = sig_verify_check_initialized(ctx); EG(ret, err);
531 
532 	/* Do some sanity checks on input params */
533 	ret = pub_key_check_initialized_and_type(ctx->pub_key, SM2); EG(ret, err);
534 	MUST_HAVE((ctx->h != NULL) && (ctx->h->digest_size <= MAX_DIGEST_SIZE) &&
535 		  (ctx->h->block_size <= MAX_BLOCK_SIZE), ret, err);
536 	MUST_HAVE((sig != NULL), ret, err);
537 
538 	/* Make things more readable */
539 	q = &(ctx->pub_key->params->ec_gen_order);
540 	q_bit_len = ctx->pub_key->params->ec_gen_order_bitlen;
541 	q_len = (u8)BYTECEIL(q_bit_len);
542 	r = &(ctx->verify_data.sm2.r);
543 	s = &(ctx->verify_data.sm2.s);
544 
545 	/* Check given signature length is the expected one */
546 	MUST_HAVE((siglen == SM2_SIGLEN(q_bit_len)), ret, err);
547 
548 	/* Import r and s values from signature buffer */
549 	ret = nn_init_from_buf(r, sig, q_len); EG(ret, err);
550 	ret = nn_init_from_buf(s, sig + q_len, q_len); EG(ret, err);
551 	dbg_nn_print("r", r);
552 	dbg_nn_print("s", s);
553 
554 	/* 1. Reject the signature if r or s is 0 or >= q. */
555 	ret = nn_iszero(r, &iszero1); EG(ret, err);
556 	ret = nn_iszero(s, &iszero2); EG(ret, err);
557 	ret = nn_cmp(r, q, &cmp1); EG(ret, err);
558 	ret = nn_cmp(s, q, &cmp2); EG(ret, err);
559 	MUST_HAVE((!iszero1) && (cmp1 < 0) && (!iszero2) && (cmp2 < 0), ret, err);
560 
561 	/* Initialize the remaining of verify context. */
562 	/* Since we call a callback, sanity check our mapping */
563 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
564 	ret = ctx->h->hfunc_init(&(ctx->verify_data.sm2.h_ctx)); EG(ret, err);
565 
566 	/* Compute Z from the ID */
567 	ret = local_memset(Z, 0, sizeof(Z)); EG(ret, err);
568 	Zlen = sizeof(Z);
569 	ret = sm2_compute_Z(Z, &Zlen, ctx->adata, ctx->adata_len, ctx->pub_key, ctx->h->type); EG(ret, err);
570 
571 	/* Update the hash function with Z */
572 	ret = ctx->h->hfunc_update(&(ctx->verify_data.sm2.h_ctx), Z, Zlen); EG(ret, err);
573 
574 	ctx->verify_data.sm2.magic = SM2_VERIFY_MAGIC;
575 
576  err:
577 	VAR_ZEROIFY(q_len);
578 	VAR_ZEROIFY(q_bit_len);
579 	VAR_ZEROIFY(Zlen);
580 	PTR_NULLIFY(q);
581 	PTR_NULLIFY(r);
582 	PTR_NULLIFY(s);
583 
584 	return ret;
585 }
586 
587 
_sm2_verify_update(struct ec_verify_context * ctx,const u8 * chunk,u32 chunklen)588 int _sm2_verify_update(struct ec_verify_context *ctx,
589 			 const u8 *chunk, u32 chunklen)
590 {
591 	int ret;
592 
593 	/*
594 	 * First, verify context has been initialized and public part too. This
595 	 * guarantees the context is a SM2 verification one and we do not
596 	 * update() or finalize() before init().
597 	 */
598 	ret = sig_verify_check_initialized(ctx); EG(ret, err);
599 	SM2_VERIFY_CHECK_INITIALIZED(&(ctx->verify_data.sm2), ret, err);
600 
601 	/* 2. Compute h = H(M1) w/ M1 = Z || M */
602 	/* Since we call a callback, sanity check our mapping */
603 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
604 	ret = ctx->h->hfunc_update(&(ctx->verify_data.sm2.h_ctx), chunk, chunklen);
605 
606 err:
607 	return ret;
608 }
609 
_sm2_verify_finalize(struct ec_verify_context * ctx)610 int _sm2_verify_finalize(struct ec_verify_context *ctx)
611 {
612 	prj_pt sG, tY;
613 	prj_pt_t W_prime;
614 	nn e, tmp, r_prime;
615 	prj_pt_src_t G, Y;
616 	u8 hash[MAX_DIGEST_SIZE];
617 	nn_src_t q;
618 	nn *s, *r;
619 	nn t;
620 	u8 hsize;
621 	int ret, iszero, cmp;
622 
623 	e.magic = tmp.magic = r_prime.magic = t.magic = WORD(0);
624 	sG.magic = tY.magic = WORD(0);
625 
626 	/* NOTE: we reuse sG for W_prime to optimize local variables */
627 	W_prime = &sG;
628 
629 	/*
630 	 * First, verify context has been initialized and public
631 	 * part too. This guarantees the context is an SM2
632 	 * verification one and we do not finalize() before init().
633 	 */
634 	ret = sig_verify_check_initialized(ctx); EG(ret, err);
635 	SM2_VERIFY_CHECK_INITIALIZED(&(ctx->verify_data.sm2), ret, err);
636 
637 	/* Zero init points */
638 	ret = local_memset(&sG, 0, sizeof(prj_pt)); EG(ret, err);
639 	ret = local_memset(&tY, 0, sizeof(prj_pt)); EG(ret, err);
640 
641 	/* Make things more readable */
642 	G = &(ctx->pub_key->params->ec_gen);
643 	Y = &(ctx->pub_key->y);
644 	q = &(ctx->pub_key->params->ec_gen_order);
645 	hsize = ctx->h->digest_size;
646 	r = &(ctx->verify_data.sm2.r);
647 	s = &(ctx->verify_data.sm2.s);
648 
649 	/* 2. Compute h = H(M1) w/ M1 = Z || M */
650 	/* Since we call a callback, sanity check our mapping */
651 	ret = hash_mapping_callbacks_sanity_check(ctx->h); EG(ret, err);
652 	ret = ctx->h->hfunc_finalize(&(ctx->verify_data.sm2.h_ctx), hash); EG(ret, err);
653 	dbg_buf_print("h = H(m)", hash, hsize);
654 
655 	/* 3. Compute t = r + s mod q */
656 	ret = nn_mod_add(&t, r, s, q); EG(ret, err);
657 
658 	/* 4. Reject signature if t is 0 */
659 	ret = nn_iszero(&t, &iszero); EG(ret, err);
660 	MUST_HAVE((!iszero), ret, err);
661 
662 	/* 5. Compute e = OS2I(h) mod q */
663 	ret = nn_init_from_buf(&tmp, hash, hsize); EG(ret, err);
664 	ret = local_memset(hash, 0, hsize); EG(ret, err);
665 	dbg_nn_print("h imported as nn", &tmp);
666 	ret = nn_mod(&e, &tmp, q); EG(ret, err);
667 	dbg_nn_print("e", &e);
668 
669 	/* 6. Compute W' = sG + tY */
670 	ret = prj_pt_mul(&sG, s, G); EG(ret, err);
671 	ret = prj_pt_mul(&tY, &t, Y); EG(ret, err);
672 	ret = prj_pt_add(W_prime, &sG, &tY); EG(ret, err);
673 
674 	/* 7. If W' is the point at infinity, reject the signature. */
675 	ret = prj_pt_iszero(W_prime, &iszero); EG(ret, err);
676 	MUST_HAVE((!iszero), ret, err);
677 
678 	/* 8. Compute r' = (e + W'_x) mod q */
679 	ret = prj_pt_unique(W_prime, W_prime); EG(ret, err);
680 	dbg_nn_print("W'_x", &(W_prime->X.fp_val));
681 	dbg_nn_print("W'_y", &(W_prime->Y.fp_val));
682 
683 	/* First, reduce W'_x mod q */
684 	ret = nn_mod(&r_prime, &(W_prime->X.fp_val), q); EG(ret, err);
685 	/* Then compute r' = (e + W'_x) mod q */
686 	ret = nn_mod_add(&r_prime, &e, &r_prime, q); EG(ret, err);
687 
688 	/* 9. Accept the signature if and only if r equals r' */
689 	ret = nn_cmp(&r_prime, r, &cmp); EG(ret, err);
690 	ret = (cmp != 0) ? -1 : 0;
691 
692  err:
693 	nn_uninit(&e);
694 	nn_uninit(&tmp);
695 	nn_uninit(&r_prime);
696 	nn_uninit(&t);
697 	prj_pt_uninit(&sG);
698 	prj_pt_uninit(&tY);
699 
700 	/*
701 	 * We can now clear data part of the context. This will clear
702 	 * magic and avoid further reuse of the whole context.
703 	 */
704 	IGNORE_RET_VAL(local_memset(&(ctx->verify_data.sm2), 0, sizeof(sm2_verify_data)));
705 
706 	/* Clean what remains on the stack */
707 	PTR_NULLIFY(W_prime);
708 	PTR_NULLIFY(G);
709 	PTR_NULLIFY(Y);
710 	PTR_NULLIFY(q);
711 	PTR_NULLIFY(s);
712 	PTR_NULLIFY(r);
713 	VAR_ZEROIFY(hsize);
714 
715 	return ret;
716 }
717 
718 #else /* WITH_SIG_SM2 */
719 
720 /*
721  * Dummy definition to avoid the empty translation unit ISO C warning
722  */
723 typedef int dummy;
724 #endif /* WITH_SIG_SM2 */
725