OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
ecp_mont.c
Go to the documentation of this file.
1 /* crypto/ec/ecp_mont.c */
2 /*
3  * Originally written by Bodo Moeller for the OpenSSL project.
4  */
5 /* ====================================================================
6  * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  * software must display the following acknowledgment:
22  * "This product includes software developed by the OpenSSL Project
23  * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  * endorse or promote products derived from this software without
27  * prior written permission. For written permission, please contact
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  * nor may "OpenSSL" appear in their names without prior written
32  * permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  * acknowledgment:
36  * "This product includes software developed by the OpenSSL Project
37  * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * ([email protected]). This product includes software written by Tim
55  * Hudson ([email protected]).
56  *
57  */
58 /* ====================================================================
59  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60  * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61  * and contributed to the OpenSSL project.
62  */
63 
64 #include <openssl/err.h>
65 
66 #ifdef OPENSSL_FIPS
67 #include <openssl/fips.h>
68 #endif
69 
70 #include "ec_lcl.h"
71 
72 
74  {
75 #ifdef OPENSSL_FIPS
76  return fips_ec_gfp_mont_method();
77 #else
78  static const EC_METHOD ret = {
98  0,0,0,
107  0 /* mul */,
108  0 /* precompute_mult */,
109  0 /* have_precompute_mult */,
112  0 /* field_div */,
116 
117 
118  return &ret;
119 #endif
120  }
121 
122 
124  {
125  int ok;
126 
127  ok = ec_GFp_simple_group_init(group);
128  group->field_data1 = NULL;
129  group->field_data2 = NULL;
130  return ok;
131  }
132 
133 
135  {
136  if (group->field_data1 != NULL)
137  {
139  group->field_data1 = NULL;
140  }
141  if (group->field_data2 != NULL)
142  {
143  BN_free(group->field_data2);
144  group->field_data2 = NULL;
145  }
147  }
148 
149 
151  {
152  if (group->field_data1 != NULL)
153  {
155  group->field_data1 = NULL;
156  }
157  if (group->field_data2 != NULL)
158  {
159  BN_clear_free(group->field_data2);
160  group->field_data2 = NULL;
161  }
163  }
164 
165 
167  {
168  if (dest->field_data1 != NULL)
169  {
171  dest->field_data1 = NULL;
172  }
173  if (dest->field_data2 != NULL)
174  {
175  BN_clear_free(dest->field_data2);
176  dest->field_data2 = NULL;
177  }
178 
179  if (!ec_GFp_simple_group_copy(dest, src)) return 0;
180 
181  if (src->field_data1 != NULL)
182  {
183  dest->field_data1 = BN_MONT_CTX_new();
184  if (dest->field_data1 == NULL) return 0;
185  if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
186  }
187  if (src->field_data2 != NULL)
188  {
189  dest->field_data2 = BN_dup(src->field_data2);
190  if (dest->field_data2 == NULL) goto err;
191  }
192 
193  return 1;
194 
195  err:
196  if (dest->field_data1 != NULL)
197  {
199  dest->field_data1 = NULL;
200  }
201  return 0;
202  }
203 
204 
205 int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
206  {
207  BN_CTX *new_ctx = NULL;
208  BN_MONT_CTX *mont = NULL;
209  BIGNUM *one = NULL;
210  int ret = 0;
211 
212  if (group->field_data1 != NULL)
213  {
215  group->field_data1 = NULL;
216  }
217  if (group->field_data2 != NULL)
218  {
219  BN_free(group->field_data2);
220  group->field_data2 = NULL;
221  }
222 
223  if (ctx == NULL)
224  {
225  ctx = new_ctx = BN_CTX_new();
226  if (ctx == NULL)
227  return 0;
228  }
229 
230  mont = BN_MONT_CTX_new();
231  if (mont == NULL) goto err;
232  if (!BN_MONT_CTX_set(mont, p, ctx))
233  {
235  goto err;
236  }
237  one = BN_new();
238  if (one == NULL) goto err;
239  if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
240 
241  group->field_data1 = mont;
242  mont = NULL;
243  group->field_data2 = one;
244  one = NULL;
245 
246  ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
247 
248  if (!ret)
249  {
251  group->field_data1 = NULL;
252  BN_free(group->field_data2);
253  group->field_data2 = NULL;
254  }
255 
256  err:
257  if (new_ctx != NULL)
258  BN_CTX_free(new_ctx);
259  if (mont != NULL)
260  BN_MONT_CTX_free(mont);
261  return ret;
262  }
263 
264 
265 int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
266  {
267  if (group->field_data1 == NULL)
268  {
270  return 0;
271  }
272 
273  return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
274  }
275 
276 
277 int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
278  {
279  if (group->field_data1 == NULL)
280  {
282  return 0;
283  }
284 
285  return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
286  }
287 
288 
289 int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
290  {
291  if (group->field_data1 == NULL)
292  {
294  return 0;
295  }
296 
297  return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
298  }
299 
300 
301 int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
302  {
303  if (group->field_data1 == NULL)
304  {
306  return 0;
307  }
308 
309  return BN_from_montgomery(r, a, group->field_data1, ctx);
310  }
311 
312 
314  {
315  if (group->field_data2 == NULL)
316  {
318  return 0;
319  }
320 
321  if (!BN_copy(r, group->field_data2)) return 0;
322  return 1;
323  }