xref: /freebsd/crypto/libecc/src/sig/ec_key.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/ec_key.h>
17 #include <libecc/sig/sig_algs.h>
18 #include <libecc/curves/curves.h>
19 
20 /*
21  * Check if given private key 'A' has been initialized. Returns 0 on success,
22  * -1 on error
23  */
priv_key_check_initialized(const ec_priv_key * A)24 int priv_key_check_initialized(const ec_priv_key *A)
25 {
26 	int ret = 0;
27 
28 	MUST_HAVE(((A != NULL) && (A->magic == PRIV_KEY_MAGIC) && (A->params != NULL)), ret, err);
29 
30 err:
31 	return ret;
32 }
33 
34 /*
35  * Same as previous but also verifies that the signature algorithm type does
36  * match the one passed using 'alg_type'. Returns 0 on success, -1 on error.
37  */
priv_key_check_initialized_and_type(const ec_priv_key * A,ec_alg_type alg_type)38 int priv_key_check_initialized_and_type(const ec_priv_key *A,
39 					 ec_alg_type alg_type)
40 {
41 	int ret = 0;
42 
43 	MUST_HAVE(((A != NULL) && (A->magic == PRIV_KEY_MAGIC) &&
44 			(A->params != NULL) && (A->key_type == alg_type)), ret, err);
45 
46 err:
47 	return ret;
48 }
49 
50 /*
51  * Import a private key from a buffer with known EC parameters and algorithm
52  * Note that no sanity check is performed  by the function to verify key
53  * is valid for params. Also note that no deep copy of pointed params is
54  * performed. The function returns 0 on success, -1 on error.
55  */
ec_priv_key_import_from_buf(ec_priv_key * priv_key,const ec_params * params,const u8 * priv_key_buf,u8 priv_key_buf_len,ec_alg_type ec_key_alg)56 int ec_priv_key_import_from_buf(ec_priv_key *priv_key,
57 				const ec_params *params,
58 				const u8 *priv_key_buf, u8 priv_key_buf_len,
59 				ec_alg_type ec_key_alg)
60 {
61 	int ret;
62 
63 	MUST_HAVE((priv_key != NULL), ret, err);
64 
65 	ret = nn_init_from_buf(&(priv_key->x), priv_key_buf, priv_key_buf_len); EG(ret, err);
66 
67 	/* Set key type and pointer to EC params */
68 	priv_key->key_type = ec_key_alg;
69 	priv_key->params = (const ec_params *)params;
70 	priv_key->magic = PRIV_KEY_MAGIC;
71 
72 err:
73 	return ret;
74 }
75 
76 /*
77  * Export a private key 'priv_key' to a buffer 'priv_key_buf' of length
78  * 'priv_key_buf_len'. The function returns 0 on sucess, -1 on error.
79  */
ec_priv_key_export_to_buf(const ec_priv_key * priv_key,u8 * priv_key_buf,u8 priv_key_buf_len)80 int ec_priv_key_export_to_buf(const ec_priv_key *priv_key, u8 *priv_key_buf,
81 			      u8 priv_key_buf_len)
82 {
83 	int ret;
84 	bitcnt_t blen;
85 
86 	ret = priv_key_check_initialized(priv_key); EG(ret, err);
87 
88 	/*
89 	 * Check that there is enough room to export our private key without
90 	 * losing information.
91 	 */
92 	ret = nn_bitlen(&(priv_key->x), &blen); EG(ret, err);
93 	MUST_HAVE(((8 * (u32)priv_key_buf_len) >= (u32)blen), ret, err);
94 
95 	/* Export our private key */
96 	ret = nn_export_to_buf(priv_key_buf, priv_key_buf_len, &(priv_key->x));
97 
98 err:
99 	return ret;
100 }
101 
102 /*
103  * Check if given public key 'A' has been initialized. Returns 0 on success,
104  * -1 on error
105  */
pub_key_check_initialized(const ec_pub_key * A)106 int pub_key_check_initialized(const ec_pub_key *A)
107 {
108 	int ret = 0;
109 
110 	MUST_HAVE(((A != NULL) && (A->magic == PUB_KEY_MAGIC) && (A->params != NULL)), ret, err);
111 
112 err:
113 	return ret;
114 }
115 
116 /*
117  * Same as previous but also verifies that the signature algorithm type does
118  * match the one passed using 'alg_type'. Returns 0 on success, -1 on error.
119  */
pub_key_check_initialized_and_type(const ec_pub_key * A,ec_alg_type alg_type)120 int pub_key_check_initialized_and_type(const ec_pub_key *A,
121 					ec_alg_type alg_type)
122 {
123 	int ret = 0;
124 
125 	MUST_HAVE(((A != NULL) && (A->magic == PUB_KEY_MAGIC) &&
126 			(A->params != NULL) && (A->key_type == alg_type)), ret, err);
127 
128 err:
129 	return ret;
130 }
131 
132 /*
133  * Import a public key from a buffer with known EC parameters and algorithm
134  * Note that no sanity check is performed by the function to verify key
135  * is valid for params. Also note that no deep copy of pointed params is
136  * performed. The buffer contains projective point coordinates. The function
137  * returns 0 on success, -1 on error.
138  */
ec_pub_key_import_from_buf(ec_pub_key * pub_key,const ec_params * params,const u8 * pub_key_buf,u8 pub_key_buf_len,ec_alg_type ec_key_alg)139 int ec_pub_key_import_from_buf(ec_pub_key *pub_key, const ec_params *params,
140 			       const u8 *pub_key_buf, u8 pub_key_buf_len,
141 			       ec_alg_type ec_key_alg)
142 {
143 	int ret, isone, check;
144 
145 	MUST_HAVE(((pub_key != NULL) && (pub_key_buf != NULL) && (params != NULL)), ret, err);
146 
147 	/* Import the projective point */
148 	ret = prj_pt_import_from_buf(&(pub_key->y),
149 				     pub_key_buf, pub_key_buf_len,
150 				     (ec_shortw_crv_src_t)&(params->ec_curve)); EG(ret, err);
151 
152 	/* If the cofactor of the curve is not 1, we check that
153 	 * our public key is indeed in the sub-group generated by
154 	 * our generator.
155 	 * NOTE: this is indeed a 'costly' operation, but it is necessary
156 	 * when we do not trust the public key that is provided, which can
157 	 * be the case in some protocols.
158 	 */
159 	ret = nn_isone(&(params->ec_gen_cofactor), &isone); EG(ret, err);
160 	if (!isone) {
161 		ret = check_prj_pt_order(&(pub_key->y), &(params->ec_gen_order), PUBLIC_PT, &check); EG(ret, err);
162 		MUST_HAVE(check, ret, err);
163 	}
164 
165 	/* Set key type and pointer to EC params */
166 	pub_key->key_type = ec_key_alg;
167 	pub_key->params = (const ec_params *)params;
168 	pub_key->magic = PUB_KEY_MAGIC;
169 
170 err:
171 	return ret;
172 }
173 
174 /*
175  * Import a public key from a buffer with known EC parameters and algorithm
176  * Note that no sanity check is performed  by the function to verify key
177  * is valid for params. Also note that no deep copy of pointed params is
178  * performed. The buffer contains affine point coordinates. The function
179  * returns 0 on success, -1 on error.
180  */
ec_pub_key_import_from_aff_buf(ec_pub_key * pub_key,const ec_params * params,const u8 * pub_key_buf,u8 pub_key_buf_len,ec_alg_type ec_key_alg)181 int ec_pub_key_import_from_aff_buf(ec_pub_key *pub_key, const ec_params *params,
182 			       const u8 *pub_key_buf, u8 pub_key_buf_len,
183 			       ec_alg_type ec_key_alg)
184 {
185 	int ret, isone, check;
186 
187 	MUST_HAVE(((pub_key != NULL) && (pub_key_buf != NULL) && (params != NULL)), ret, err);
188 
189 	/* Import the projective point */
190 	ret = prj_pt_import_from_aff_buf(&(pub_key->y),
191 				     pub_key_buf, pub_key_buf_len,
192 				     (ec_shortw_crv_src_t)&(params->ec_curve)); EG(ret, err);
193 
194 	/* If the cofactor of the curve is not 1, we check that
195 	 * our public key is indeed in the sub-group generated by
196 	 * our generator.
197 	 * NOTE: this is indeed a 'costly' operation, but it is necessary
198 	 * when we do not trust the public key that is provided, which can
199 	 * be the case in some protocols.
200 	 */
201 	ret = nn_isone(&(params->ec_gen_cofactor), &isone); EG(ret, err);
202 	if (!isone){
203 		ret = check_prj_pt_order(&(pub_key->y), &(params->ec_gen_order), PUBLIC_PT, &check); EG(ret, err);
204 		MUST_HAVE(check, ret, err);
205 	}
206 
207 	/* Set key type and pointer to EC params */
208 	pub_key->key_type = ec_key_alg;
209 	pub_key->params = (const ec_params *)params;
210 	pub_key->magic = PUB_KEY_MAGIC;
211 
212 err:
213 	return ret;
214 }
215 
216 /*
217  * Export a public key to a projective point buffer. The function returns 0 on
218  * success, -1 on error.
219  */
ec_pub_key_export_to_buf(const ec_pub_key * pub_key,u8 * pub_key_buf,u8 pub_key_buf_len)220 int ec_pub_key_export_to_buf(const ec_pub_key *pub_key, u8 *pub_key_buf,
221 			     u8 pub_key_buf_len)
222 {
223 	int ret;
224 
225 	ret = pub_key_check_initialized(pub_key); EG(ret, err);
226 	ret = prj_pt_export_to_buf(&(pub_key->y), pub_key_buf, pub_key_buf_len);
227 
228 err:
229 	return ret;
230 }
231 
232 /*
233  * Export a public key to an affine point buffer. The function returns 0 on
234  * success, -1 on error.
235  */
ec_pub_key_export_to_aff_buf(const ec_pub_key * pub_key,u8 * pub_key_buf,u8 pub_key_buf_len)236 int ec_pub_key_export_to_aff_buf(const ec_pub_key *pub_key, u8 *pub_key_buf,
237 			     u8 pub_key_buf_len)
238 {
239 	int ret;
240 
241 	ret = pub_key_check_initialized(pub_key); EG(ret, err);
242 	ret = prj_pt_export_to_aff_buf(&(pub_key->y), pub_key_buf,
243 				       pub_key_buf_len);
244 
245 err:
246 	return ret;
247 }
248 
249 /*
250  * Check if given key pair 'A' has been initialized. Returns 0 on success,
251  * -1 on error
252  */
key_pair_check_initialized(const ec_key_pair * A)253 int key_pair_check_initialized(const ec_key_pair *A)
254 {
255 	int ret;
256 
257 	MUST_HAVE((A != NULL), ret, err);
258 
259 	ret = priv_key_check_initialized(&A->priv_key); EG(ret, err);
260 	ret = pub_key_check_initialized(&A->pub_key);
261 
262 err:
263 	return ret;
264 }
265 
266 /*
267  * Same as previous but also verifies that the signature algorithm type does
268  * match the one passed using 'alg_type'. Returns 0 on success, -1 on error.
269  */
key_pair_check_initialized_and_type(const ec_key_pair * A,ec_alg_type alg_type)270 int key_pair_check_initialized_and_type(const ec_key_pair *A,
271 					 ec_alg_type alg_type)
272 {
273 	int ret;
274 
275 	MUST_HAVE((A != NULL), ret, err);
276 
277 	ret = priv_key_check_initialized_and_type(&A->priv_key, alg_type); EG(ret, err);
278 	ret = pub_key_check_initialized_and_type(&A->pub_key, alg_type);
279 
280 err:
281 	return ret;
282 }
283 
284 /*
285  * Import a key pair from a buffer representing the private key. The associated
286  * public key is computed from the private key. The function returns 0 on
287  * success, -1 on error.
288  */
ec_key_pair_import_from_priv_key_buf(ec_key_pair * kp,const ec_params * params,const u8 * priv_key,u8 priv_key_len,ec_alg_type ec_key_alg)289 int ec_key_pair_import_from_priv_key_buf(ec_key_pair *kp,
290 					 const ec_params *params,
291 					 const u8 *priv_key, u8 priv_key_len,
292 					 ec_alg_type ec_key_alg)
293 {
294 	int ret;
295 
296 	MUST_HAVE((kp != NULL), ret, err);
297 
298 	/* Import private key */
299 	ret = ec_priv_key_import_from_buf(&(kp->priv_key), params, priv_key,
300 					  priv_key_len, ec_key_alg);  EG(ret, err);
301 	/* Generate associated public key. */
302 	ret = init_pubkey_from_privkey(&(kp->pub_key), &(kp->priv_key));
303 
304 err:
305 	return ret;
306 }
307 
308 /*
309  * Import a structured private key to buffer. The structure allows some sanity
310  * checks. The function returns 0 on success, -1 on error.
311  */
ec_structured_priv_key_import_from_buf(ec_priv_key * priv_key,const ec_params * params,const u8 * priv_key_buf,u8 priv_key_buf_len,ec_alg_type ec_key_alg)312 int ec_structured_priv_key_import_from_buf(ec_priv_key *priv_key,
313 					   const ec_params *params,
314 					   const u8 *priv_key_buf,
315 					   u8 priv_key_buf_len,
316 					   ec_alg_type ec_key_alg)
317 {
318 	u8 metadata_len = (3 * sizeof(u8));
319 	u8 crv_name_len;
320 	u32 len;
321 	int ret;
322 
323 	/* We first pull the metadata, consisting of:
324 	 *   - One byte = the key type (public or private)
325 	 *   - One byte = the algorithm type (ECDSA, ECKCDSA, ...)
326 	 *   - One byte = the curve type (FRP256V1, ...)
327 	 */
328 	MUST_HAVE((priv_key != NULL) && (priv_key_buf != NULL) && (priv_key_buf_len > metadata_len), ret, err);
329 	MUST_HAVE((params != NULL) && (params->curve_name != NULL), ret, err);
330 
331 	/* Pull and check the key type */
332 	MUST_HAVE((EC_PRIVKEY == priv_key_buf[0]), ret, err);
333 
334 	/* Pull and check the algorithm type */
335 	MUST_HAVE((ec_key_alg == priv_key_buf[1]), ret, err);
336 
337 	/* Pull and check the curve type */
338 	ret = local_strlen((const char *)params->curve_name, &len); EG(ret, err);
339 	len += 1;
340 	MUST_HAVE((len < 256), ret, err);
341 	crv_name_len = (u8)len;
342 
343 	ret = ec_check_curve_type_and_name((ec_curve_type) (priv_key_buf[2]),
344 					params->curve_name, crv_name_len); EG(ret, err);
345 	ret = ec_priv_key_import_from_buf(priv_key, params,
346 					  priv_key_buf + metadata_len,
347 					  (u8)(priv_key_buf_len - metadata_len),
348 					  ec_key_alg);
349 
350  err:
351 	return ret;
352 }
353 
354 /*
355  * Export a structured private key to buffer. The structure allows some sanity
356  * checks. The function returns 0 on success, -1 on error.
357  */
ec_structured_priv_key_export_to_buf(const ec_priv_key * priv_key,u8 * priv_key_buf,u8 priv_key_buf_len)358 int ec_structured_priv_key_export_to_buf(const ec_priv_key *priv_key,
359 					 u8 *priv_key_buf, u8 priv_key_buf_len)
360 {
361 
362 	u8 metadata_len = (3 * sizeof(u8));
363 	const u8 *curve_name;
364 	u8 curve_name_len;
365 	u32 len;
366 	ec_curve_type curve_type;
367 	int ret;
368 
369 	ret = priv_key_check_initialized(priv_key); EG(ret, err);
370 
371 	MUST_HAVE((priv_key_buf != NULL) && (priv_key_buf_len > metadata_len) && (priv_key->params->curve_name != NULL), ret, err);
372 
373 	/*
374 	 * We first put the metadata, consisting on:
375 	 *   - One byte = the key type (public or private)
376 	 *   - One byte = the algorithm type (ECDSA, ECKCDSA, ...)
377 	 *   - One byte = the curve type (FRP256V1, ...)
378 	 */
379 
380 	/* Push the key type */
381 	priv_key_buf[0] = (u8)EC_PRIVKEY;
382 
383 	/* Push the algorithm type */
384 	priv_key_buf[1] = (u8)priv_key->key_type;
385 
386 	/* Push the curve type */
387 	curve_name = priv_key->params->curve_name;
388 
389 	ret = local_strlen((const char *)curve_name, &len); EG(ret, err);
390 	len += 1;
391 	MUST_HAVE((len < 256), ret, err);
392 	curve_name_len = (u8)len;
393 
394 	ret = ec_get_curve_type_by_name(curve_name, curve_name_len, &curve_type); EG(ret, err);
395 	priv_key_buf[2] = (u8)curve_type;
396 
397 	/* Push the raw private key buffer */
398 	ret = ec_priv_key_export_to_buf(priv_key, priv_key_buf + metadata_len,
399 					(u8)(priv_key_buf_len - metadata_len));
400 
401 err:
402 	return ret;
403 }
404 
405 /*
406  * Import a structured pub key from buffer. The structure allows some sanity
407  * checks. The function returns 0 on success, -1 on error.
408  */
ec_structured_pub_key_import_from_buf(ec_pub_key * pub_key,const ec_params * params,const u8 * pub_key_buf,u8 pub_key_buf_len,ec_alg_type ec_key_alg)409 int ec_structured_pub_key_import_from_buf(ec_pub_key *pub_key,
410 					  const ec_params *params,
411 					  const u8 *pub_key_buf,
412 					  u8 pub_key_buf_len,
413 					  ec_alg_type ec_key_alg)
414 {
415 	u8 metadata_len = (3 * sizeof(u8));
416 	u8 crv_name_len;
417 	u32 len;
418 	int ret;
419 
420 	MUST_HAVE((pub_key_buf != NULL) && (pub_key_buf_len > metadata_len), ret, err);
421 	MUST_HAVE((params != NULL) && (params->curve_name != NULL), ret, err);
422 
423 	/*
424 	 * We first pull the metadata, consisting of:
425 	 *   - One byte = the key type (public or private)
426 	 *   - One byte = the algorithm type (ECDSA, ECKCDSA, ...)
427 	 *   - One byte = the curve type (FRP256V1, ...)
428 	 */
429 
430 	/* Pull and check the key type */
431 	MUST_HAVE((EC_PUBKEY == pub_key_buf[0]), ret, err);
432 
433 	/* Pull and check the algorithm type */
434 	MUST_HAVE((ec_key_alg == pub_key_buf[1]), ret, err);
435 
436 	/* Pull and check the curve type */
437 	ret = local_strlen((const char *)params->curve_name, &len); EG(ret, err);
438 	len += 1;
439 	MUST_HAVE((len < 256), ret, err);
440 	crv_name_len = (u8)len;
441 
442 	ret = ec_check_curve_type_and_name((ec_curve_type) (pub_key_buf[2]),
443 					   params->curve_name, crv_name_len); EG(ret, err);
444 	ret = ec_pub_key_import_from_buf(pub_key, params,
445 					 pub_key_buf + metadata_len,
446 					 (u8)(pub_key_buf_len - metadata_len),
447 					 ec_key_alg);
448 
449 err:
450 	return ret;
451 }
452 
453 /*
454  * Export a structured pubate key to buffer. The structure allows some sanity
455  * checks. The function returns 0 on success, -1 on error.
456  */
ec_structured_pub_key_export_to_buf(const ec_pub_key * pub_key,u8 * pub_key_buf,u8 pub_key_buf_len)457 int ec_structured_pub_key_export_to_buf(const ec_pub_key *pub_key,
458 					u8 *pub_key_buf, u8 pub_key_buf_len)
459 {
460 	u8 metadata_len = (3 * sizeof(u8));
461 	const u8 *curve_name;
462 	u8 curve_name_len;
463 	u32 len;
464 	ec_curve_type curve_type;
465 	int ret;
466 
467 	ret = pub_key_check_initialized(pub_key); EG(ret, err);
468 
469 	MUST_HAVE((pub_key_buf != NULL) && (pub_key_buf_len > metadata_len), ret, err);
470 	MUST_HAVE((pub_key->params->curve_name != NULL), ret, err);
471 
472 	/*
473 	 * We first put the metadata, consisting of:
474 	 *   - One byte = the key type (public or private)
475 	 *   - One byte = the algorithm type (ECDSA, ECKCDSA, ...)
476 	 *   - One byte = the curve type (FRP256V1, ...)
477 	 */
478 
479 	/* Push the key type */
480 	pub_key_buf[0] = (u8)EC_PUBKEY;
481 
482 	/* Push the algorithm type */
483 	pub_key_buf[1] = (u8)pub_key->key_type;
484 
485 	/* Push the curve type */
486 	curve_name = pub_key->params->curve_name;
487 
488 	ret = local_strlen((const char *)curve_name, &len); EG(ret, err);
489 	len += 1;
490 	MUST_HAVE((len < 256), ret, err);
491 	curve_name_len = (u8)len;
492 
493 	ret = ec_get_curve_type_by_name(curve_name, curve_name_len, &curve_type); EG(ret, err);
494 	pub_key_buf[2] = (u8)curve_type;
495 
496 	/* Push the raw pub key buffer */
497 	ret = ec_pub_key_export_to_buf(pub_key, pub_key_buf + metadata_len,
498 				       (u8)(pub_key_buf_len - metadata_len));
499 
500 err:
501 	return ret;
502 }
503 
504 /*
505  * Import a key pair from a structured private key buffer. The structure allows
506  * some sanity checks. The function returns 0 on success, -1 on error.
507  */
ec_structured_key_pair_import_from_priv_key_buf(ec_key_pair * kp,const ec_params * params,const u8 * priv_key_buf,u8 priv_key_buf_len,ec_alg_type ec_key_alg)508 int ec_structured_key_pair_import_from_priv_key_buf(ec_key_pair *kp,
509 						    const ec_params *params,
510 						    const u8 *priv_key_buf,
511 						    u8 priv_key_buf_len,
512 						    ec_alg_type ec_key_alg)
513 {
514 	u8 metadata_len = (3 * sizeof(u8));
515 	u8 crv_name_len;
516 	u32 len;
517 	int ret;
518 
519 	MUST_HAVE((kp != NULL) && (priv_key_buf != NULL) && (priv_key_buf_len > metadata_len), ret, err);
520 	MUST_HAVE((params != NULL) && (params->curve_name != NULL), ret, err);
521 
522 	/* We first pull the metadata, consisting on:
523 	 *   - One byte = the key type (public or private)
524 	 *   - One byte = the algorithm type (ECDSA, ECKCDSA, ...)
525 	 *   - One byte = the curve type (FRP256V1, ...)
526 	 */
527 
528 	/* Pull and check the key type */
529 	MUST_HAVE((EC_PRIVKEY == priv_key_buf[0]), ret, err);
530 
531 	/* Pull and check the algorithm type */
532 	MUST_HAVE((ec_key_alg == priv_key_buf[1]), ret, err);
533 
534 	/* Pull and check the curve type */
535 	ret = local_strlen((const char *)params->curve_name, &len); EG(ret, err);
536 	len += 1;
537 	MUST_HAVE((len < 256), ret, err);
538 	crv_name_len = (u8)len;
539 
540 	ret = ec_check_curve_type_and_name((ec_curve_type) (priv_key_buf[2]),
541 					params->curve_name, crv_name_len); EG(ret, err);
542 	ret = ec_key_pair_import_from_priv_key_buf(kp, params,
543 						   priv_key_buf + metadata_len,
544 						   (u8)(priv_key_buf_len - metadata_len),
545 						   ec_key_alg);
546 
547  err:
548 	return ret;
549 }
550 
551 /*
552  * Import a key pair from a two structured key buffer (private and public one)
553  * The function does not verify the coherency between private and public parts.
554  * The function returns 0 on success, -1 on error.
555  *
556  * NOTE: please use this API with care as it does not check the consistency
557  * between the private and public keys! On one side, this "saves" a costly
558  * scalar multiplication when there is confidence in the source of the buffers,
559  * but on the other side the user of the API MUST check the source (integrity)
560  * of the private/public key pair. If unsure, it is advised to use the
561  * ec_structured_key_pair_import_from_priv_key_buf API that safely derives the
562  * public key from the private key.
563  *
564  */
ec_structured_key_pair_import_from_buf(ec_key_pair * kp,const ec_params * params,const u8 * priv_key_buf,u8 priv_key_buf_len,const u8 * pub_key_buf,u8 pub_key_buf_len,ec_alg_type ec_key_alg)565 int ec_structured_key_pair_import_from_buf(ec_key_pair *kp,
566 					   const ec_params *params,
567 					   const u8 *priv_key_buf,
568 					   u8 priv_key_buf_len,
569 					   const u8 *pub_key_buf,
570 					   u8 pub_key_buf_len,
571 					   ec_alg_type ec_key_alg)
572 {
573 	int ret;
574 
575 	MUST_HAVE((kp != NULL), ret, err);
576 
577 	ret = ec_structured_pub_key_import_from_buf(&kp->pub_key, params,
578 						    pub_key_buf,
579 						    pub_key_buf_len,
580 						    ec_key_alg); EG(ret, err);
581 	ret = ec_structured_priv_key_import_from_buf(&kp->priv_key, params,
582 						     priv_key_buf,
583 						     priv_key_buf_len,
584 						     ec_key_alg);
585 
586 err:
587 	return ret;
588 }
589 
590 /*
591  * Generate a public/private key pair for given signature algorithm, using
592  * given EC params. The function returns 0 on success, -1 on error.
593  */
ec_key_pair_gen(ec_key_pair * kp,const ec_params * params,ec_alg_type ec_key_alg)594 int ec_key_pair_gen(ec_key_pair *kp, const ec_params *params,
595 		    ec_alg_type ec_key_alg)
596 {
597 	int ret;
598 
599 	MUST_HAVE((kp != NULL) && (params != NULL), ret, err);
600 
601 	/* Get a random value in ]0,q[ */
602 	ret = nn_get_random_mod(&(kp->priv_key.x), &(params->ec_gen_order)); EG(ret, err);
603 
604 	/* Set key type and pointer to EC params for private key */
605 	kp->priv_key.key_type = ec_key_alg;
606 	kp->priv_key.params = (const ec_params *)params;
607 	kp->priv_key.magic = PRIV_KEY_MAGIC;
608 
609 	/* Call our private key generation function */
610 	ret = gen_priv_key(&(kp->priv_key)); EG(ret, err);
611 
612 	/* Generate associated public key. */
613 	ret = init_pubkey_from_privkey(&(kp->pub_key), &(kp->priv_key));
614 
615  err:
616 	if (ret && (kp != NULL)) {
617 		IGNORE_RET_VAL(local_memset(kp, 0, sizeof(ec_key_pair)));
618 	}
619 	return ret;
620 }
621