xref: /freebsd/crypto/libecc/src/curves/ec_params.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/curves/ec_params.h>
17 #include <libecc/curves/curves.h>
18 
19 /*
20  * Initialize (already allocated) curve parameters structure pointed by
21  * ec_params using value provided in remaining parameters. The function
22  * returns 0 on success, -1 on error.
23  */
import_params(ec_params * out_params,const ec_str_params * in_str_params)24 int import_params(ec_params *out_params, const ec_str_params *in_str_params)
25 {
26 	nn tmp_p, tmp_p_bitlen, tmp_r, tmp_r_square, tmp_mpinv, tmp_p_shift;
27 	nn tmp_p_normalized, tmp_p_reciprocal, tmp_curve_order, tmp_order;
28 	nn tmp_order_bitlen, tmp_cofactor;
29 	fp tmp_a, tmp_b, tmp_gx, tmp_gy, tmp_gz;
30 	ec_curve_type curve_type;
31 	int ret;
32 	tmp_p.magic = tmp_r.magic = tmp_r_square.magic = tmp_mpinv.magic = WORD(0);
33 	tmp_p_shift.magic = tmp_p_normalized.magic = tmp_p_reciprocal.magic = WORD(0);
34 	tmp_a.magic = tmp_b.magic = tmp_curve_order.magic = tmp_gx.magic = WORD(0);
35 	tmp_gy.magic = tmp_gz.magic = tmp_order.magic = tmp_cofactor.magic = WORD(0);
36 	tmp_order_bitlen.magic = tmp_p_bitlen.magic = WORD(0);
37 
38 	MUST_HAVE(((out_params != NULL) && (in_str_params != NULL)), ret, err);
39 
40 	ret = local_memset(out_params, 0, sizeof(ec_params)); EG(ret, err);
41 
42 	/*
43 	 * We first need to import p, the prime defining Fp and associated
44 	 * Montgomery parameters (r, r^2 and mpinv)
45 	 */
46 	ret = nn_init_from_buf(&tmp_p, PARAM_BUF_PTR(in_str_params->p),
47 			PARAM_BUF_LEN(in_str_params->p)); EG(ret, err);
48 
49 	ret = nn_init_from_buf(&tmp_p_bitlen,
50 			PARAM_BUF_PTR(in_str_params->p_bitlen),
51 			PARAM_BUF_LEN(in_str_params->p_bitlen)); EG(ret, err);
52 
53 	ret = nn_init_from_buf(&tmp_r, PARAM_BUF_PTR(in_str_params->r),
54 			PARAM_BUF_LEN(in_str_params->r)); EG(ret, err);
55 
56 	ret = nn_init_from_buf(&tmp_r_square,
57 			PARAM_BUF_PTR(in_str_params->r_square),
58 			PARAM_BUF_LEN(in_str_params->r_square)); EG(ret, err);
59 
60 	ret = nn_init_from_buf(&tmp_mpinv,
61 			PARAM_BUF_PTR(in_str_params->mpinv),
62 			PARAM_BUF_LEN(in_str_params->mpinv)); EG(ret, err);
63 
64 	ret = nn_init_from_buf(&tmp_p_shift,
65 			PARAM_BUF_PTR(in_str_params->p_shift),
66 			PARAM_BUF_LEN(in_str_params->p_shift)); EG(ret, err);
67 
68 	ret = nn_init_from_buf(&tmp_p_normalized,
69 			PARAM_BUF_PTR(in_str_params->p_normalized),
70 			PARAM_BUF_LEN(in_str_params->p_normalized)); EG(ret, err);
71 
72 	ret = nn_init_from_buf(&tmp_p_reciprocal,
73 			 PARAM_BUF_PTR(in_str_params->p_reciprocal),
74 			 PARAM_BUF_LEN(in_str_params->p_reciprocal)); EG(ret, err);
75 
76 	/* From p, we can create global Fp context */
77 	ret = fp_ctx_init(&(out_params->ec_fp), &tmp_p,
78 		    (bitcnt_t)(tmp_p_bitlen.val[0]),
79 		    &tmp_r, &tmp_r_square,
80 		    tmp_mpinv.val[0], (bitcnt_t)tmp_p_shift.val[0],
81 		    &tmp_p_normalized, tmp_p_reciprocal.val[0]); EG(ret, err);
82 
83 	/*
84 	 * Having Fp context, we can import a and b, the coefficient of
85 	 * of Weierstrass equation.
86 	 */
87 	ret = fp_init_from_buf(&tmp_a, &(out_params->ec_fp),
88 			 PARAM_BUF_PTR(in_str_params->a),
89 			 PARAM_BUF_LEN(in_str_params->a)); EG(ret, err);
90 	ret = fp_init_from_buf(&tmp_b, &(out_params->ec_fp),
91 			 PARAM_BUF_PTR(in_str_params->b),
92 			 PARAM_BUF_LEN(in_str_params->b)); EG(ret, err);
93 
94 	/*
95 	 * Now we can store the number of points in the group generated
96 	 * by g and the associated cofactor (i.e. npoints / order).
97 	 */
98 	ret = nn_init_from_buf(&tmp_order,
99 			 PARAM_BUF_PTR(in_str_params->gen_order),
100 			 PARAM_BUF_LEN(in_str_params->gen_order)); EG(ret, err);
101 	ret = nn_init(&(out_params->ec_gen_order), (u16)(tmp_order.wlen * WORD_BYTES)); EG(ret, err);
102 	ret = nn_copy(&(out_params->ec_gen_order), &tmp_order); EG(ret, err);
103 
104 	ret = nn_init_from_buf(&tmp_order_bitlen,
105 			 PARAM_BUF_PTR(in_str_params->gen_order_bitlen),
106 			 PARAM_BUF_LEN(in_str_params->gen_order_bitlen)); EG(ret, err);
107 	out_params->ec_gen_order_bitlen = (bitcnt_t)(tmp_order_bitlen.val[0]);
108 
109 	ret = nn_init_from_buf(&tmp_cofactor,
110 			 PARAM_BUF_PTR(in_str_params->cofactor),
111 			 PARAM_BUF_LEN(in_str_params->cofactor)); EG(ret, err);
112 	ret = nn_init(&(out_params->ec_gen_cofactor),
113 		(u16)(tmp_cofactor.wlen * WORD_BYTES)); EG(ret, err);
114 	ret = nn_copy(&(out_params->ec_gen_cofactor), &tmp_cofactor); EG(ret, err);
115 
116 	/* Now we can store the number of points on the curve (curve order) */
117 	ret = nn_init_from_buf(&tmp_curve_order,
118 			 PARAM_BUF_PTR(in_str_params->curve_order),
119 			 PARAM_BUF_LEN(in_str_params->curve_order)); EG(ret, err);
120 
121 	/* Now, we can create curve context from a and b. */
122 	ret = ec_shortw_crv_init(&(out_params->ec_curve), &tmp_a, &tmp_b, &tmp_curve_order); EG(ret, err);
123 
124 	/* Let's now import G from its affine coordinates (gx,gy) */
125 	ret = fp_init_from_buf(&tmp_gx, &(out_params->ec_fp),
126 			 PARAM_BUF_PTR(in_str_params->gx),
127 			 PARAM_BUF_LEN(in_str_params->gx)); EG(ret, err);
128 	ret = fp_init_from_buf(&tmp_gy, &(out_params->ec_fp),
129 			 PARAM_BUF_PTR(in_str_params->gy),
130 			 PARAM_BUF_LEN(in_str_params->gy)); EG(ret, err);
131 	ret = fp_init_from_buf(&tmp_gz, &(out_params->ec_fp),
132 			 PARAM_BUF_PTR(in_str_params->gz),
133 			 PARAM_BUF_LEN(in_str_params->gz)); EG(ret, err);
134 	ret = prj_pt_init_from_coords(&(out_params->ec_gen),
135 				&(out_params->ec_curve),
136 				&tmp_gx, &tmp_gy, &tmp_gz); EG(ret, err);
137 
138 #if !defined(USE_SMALL_STACK)
139 	/* Let's get the optional alpha transfert coefficients */
140 	ret = fp_init_from_buf(&(out_params->ec_alpha_montgomery), &(out_params->ec_fp),
141 			 PARAM_BUF_PTR(in_str_params->alpha_montgomery),
142 			 PARAM_BUF_LEN(in_str_params->alpha_montgomery)); EG(ret, err);
143 	ret = fp_init_from_buf(&(out_params->ec_gamma_montgomery), &(out_params->ec_fp),
144 			 PARAM_BUF_PTR(in_str_params->gamma_montgomery),
145 			 PARAM_BUF_LEN(in_str_params->gamma_montgomery)); EG(ret, err);
146 
147 	ret = fp_init_from_buf(&(out_params->ec_alpha_edwards), &(out_params->ec_fp),
148 			 PARAM_BUF_PTR(in_str_params->alpha_edwards),
149 			 PARAM_BUF_LEN(in_str_params->alpha_edwards)); EG(ret, err);
150 #endif
151 
152 	/* Import a local copy of curve OID */
153 	MUST_HAVE(in_str_params->oid->buflen < MAX_CURVE_OID_LEN, ret, err);
154 	ret = local_memset(out_params->curve_oid, 0, MAX_CURVE_OID_LEN); EG(ret, err);
155 	ret = local_strncpy((char *)(out_params->curve_oid),
156 		      (const char *)(in_str_params->oid->buf),
157 		      in_str_params->oid->buflen); EG(ret, err);
158 
159 	/* Import a local copy of curve name */
160 	MUST_HAVE(in_str_params->name->buflen < MAX_CURVE_NAME_LEN, ret, err);
161 	ret = local_memset(out_params->curve_name, 0, MAX_CURVE_NAME_LEN); EG(ret, err);
162 	ret = local_strncpy((char *)(out_params->curve_name),
163 		      (const char *)(in_str_params->name->buf),
164 		      in_str_params->name->buflen); EG(ret, err);
165 
166 	/* Get the curve type */
167 	ret = ec_get_curve_type_by_name(in_str_params->name->buf,
168 					in_str_params->name->buflen,
169 					&curve_type); EG(ret, err);
170 	MUST_HAVE(curve_type != UNKNOWN_CURVE, ret, err);
171 	out_params->curve_type = curve_type;
172 
173 err:
174 	/* Uninit temporary parameters */
175 	nn_uninit(&tmp_p_bitlen);
176 	nn_uninit(&tmp_order_bitlen);
177 	nn_uninit(&tmp_p);
178 	nn_uninit(&tmp_r);
179 	nn_uninit(&tmp_r_square);
180 	nn_uninit(&tmp_mpinv);
181 	nn_uninit(&tmp_p_shift);
182 	nn_uninit(&tmp_p_normalized);
183 	nn_uninit(&tmp_p_reciprocal);
184 	fp_uninit(&tmp_a);
185 	fp_uninit(&tmp_b);
186 	nn_uninit(&tmp_curve_order);
187 	fp_uninit(&tmp_gx);
188 	fp_uninit(&tmp_gy);
189 	fp_uninit(&tmp_gz);
190 	nn_uninit(&tmp_order);
191 	nn_uninit(&tmp_cofactor);
192 
193 	return ret;
194 }
195