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