/ external / libecc / src / curves / ec_params.c
ec_params.c
  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   */
 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  }