summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec/ecp_oct.c
diff options
context:
space:
mode:
authortedu <>2014-05-06 03:56:27 +0000
committertedu <>2014-05-06 03:56:27 +0000
commit2518b24aa4315d557b967bff48dfc9efed909569 (patch)
treece2ee4fdddbbe61dd0ccb045a1604a3d92a86a00 /src/lib/libcrypto/ec/ecp_oct.c
parent0539604f5771dae2c3ecffa8122b5651ff283719 (diff)
downloadopenbsd-2518b24aa4315d557b967bff48dfc9efed909569.tar.gz
openbsd-2518b24aa4315d557b967bff48dfc9efed909569.tar.bz2
openbsd-2518b24aa4315d557b967bff48dfc9efed909569.zip
knf approximation
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/ec/ecp_oct.c373
1 files changed, 169 insertions, 204 deletions
diff --git a/src/lib/libcrypto/ec/ecp_oct.c b/src/lib/libcrypto/ec/ecp_oct.c
index a06abbc8cd..c7719c7413 100644
--- a/src/lib/libcrypto/ec/ecp_oct.c
+++ b/src/lib/libcrypto/ec/ecp_oct.c
@@ -1,6 +1,6 @@
1/* crypto/ec/ecp_oct.c */ 1/* crypto/ec/ecp_oct.c */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project. 3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project. 4 * Includes code written by Bodo Moeller for the OpenSSL project.
5*/ 5*/
6/* ==================================================================== 6/* ====================================================================
@@ -11,7 +11,7 @@
11 * are met: 11 * are met:
12 * 12 *
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 15 *
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in 17 * notice, this list of conditions and the following disclaimer in
@@ -66,23 +66,22 @@
66 66
67#include "ec_lcl.h" 67#include "ec_lcl.h"
68 68
69int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 69int
70 const BIGNUM *x_, int y_bit, BN_CTX *ctx) 70ec_GFp_simple_set_compressed_coordinates(const EC_GROUP * group, EC_POINT * point,
71 { 71 const BIGNUM * x_, int y_bit, BN_CTX * ctx)
72{
72 BN_CTX *new_ctx = NULL; 73 BN_CTX *new_ctx = NULL;
73 BIGNUM *tmp1, *tmp2, *x, *y; 74 BIGNUM *tmp1, *tmp2, *x, *y;
74 int ret = 0; 75 int ret = 0;
75 76
76 /* clear error queue*/ 77 /* clear error queue */
77 ERR_clear_error(); 78 ERR_clear_error();
78 79
79 if (ctx == NULL) 80 if (ctx == NULL) {
80 {
81 ctx = new_ctx = BN_CTX_new(); 81 ctx = new_ctx = BN_CTX_new();
82 if (ctx == NULL) 82 if (ctx == NULL)
83 return 0; 83 return 0;
84 } 84 }
85
86 y_bit = (y_bit != 0); 85 y_bit = (y_bit != 0);
87 86
88 BN_CTX_start(ctx); 87 BN_CTX_start(ctx);
@@ -90,114 +89,117 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *po
90 tmp2 = BN_CTX_get(ctx); 89 tmp2 = BN_CTX_get(ctx);
91 x = BN_CTX_get(ctx); 90 x = BN_CTX_get(ctx);
92 y = BN_CTX_get(ctx); 91 y = BN_CTX_get(ctx);
93 if (y == NULL) goto err; 92 if (y == NULL)
93 goto err;
94 94
95 /* Recover y. We have a Weierstrass equation 95 /*
96 * y^2 = x^3 + a*x + b, 96 * Recover y. We have a Weierstrass equation y^2 = x^3 + a*x + b, so
97 * so y is one of the square roots of x^3 + a*x + b. 97 * y is one of the square roots of x^3 + a*x + b.
98 */ 98 */
99 99
100 /* tmp1 := x^3 */ 100 /* tmp1 := x^3 */
101 if (!BN_nnmod(x, x_, &group->field,ctx)) goto err; 101 if (!BN_nnmod(x, x_, &group->field, ctx))
102 if (group->meth->field_decode == 0) 102 goto err;
103 { 103 if (group->meth->field_decode == 0) {
104 /* field_{sqr,mul} work on standard representation */ 104 /* field_{sqr,mul} work on standard representation */
105 if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err; 105 if (!group->meth->field_sqr(group, tmp2, x_, ctx))
106 if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err; 106 goto err;
107 } 107 if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
108 else 108 goto err;
109 { 109 } else {
110 if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err; 110 if (!BN_mod_sqr(tmp2, x_, &group->field, ctx))
111 if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err; 111 goto err;
112 } 112 if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx))
113 113 goto err;
114 }
115
114 /* tmp1 := tmp1 + a*x */ 116 /* tmp1 := tmp1 + a*x */
115 if (group->a_is_minus3) 117 if (group->a_is_minus3) {
116 { 118 if (!BN_mod_lshift1_quick(tmp2, x, &group->field))
117 if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err; 119 goto err;
118 if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err; 120 if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field))
119 if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err; 121 goto err;
120 } 122 if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field))
121 else 123 goto err;
122 { 124 } else {
123 if (group->meth->field_decode) 125 if (group->meth->field_decode) {
124 { 126 if (!group->meth->field_decode(group, tmp2, &group->a, ctx))
125 if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err; 127 goto err;
126 if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err; 128 if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx))
127 } 129 goto err;
128 else 130 } else {
129 {
130 /* field_mul works on standard representation */ 131 /* field_mul works on standard representation */
131 if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err; 132 if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx))
132 } 133 goto err;
133
134 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err;
135 } 134 }
136 135
136 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
137 goto err;
138 }
139
137 /* tmp1 := tmp1 + b */ 140 /* tmp1 := tmp1 + b */
138 if (group->meth->field_decode) 141 if (group->meth->field_decode) {
139 { 142 if (!group->meth->field_decode(group, tmp2, &group->b, ctx))
140 if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err; 143 goto err;
141 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err; 144 if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
142 } 145 goto err;
143 else 146 } else {
144 { 147 if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field))
145 if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err; 148 goto err;
146 } 149 }
147 150
148 if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) 151 if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
149 {
150 unsigned long err = ERR_peek_last_error(); 152 unsigned long err = ERR_peek_last_error();
151 153
152 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) 154 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
153 {
154 ERR_clear_error(); 155 ERR_clear_error();
155 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); 156 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
156 } 157 } else
157 else
158 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB); 158 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
159 goto err; 159 goto err;
160 } 160 }
161 161 if (y_bit != BN_is_odd(y)) {
162 if (y_bit != BN_is_odd(y)) 162 if (BN_is_zero(y)) {
163 {
164 if (BN_is_zero(y))
165 {
166 int kron; 163 int kron;
167 164
168 kron = BN_kronecker(x, &group->field, ctx); 165 kron = BN_kronecker(x, &group->field, ctx);
169 if (kron == -2) goto err; 166 if (kron == -2)
167 goto err;
170 168
171 if (kron == 1) 169 if (kron == 1)
172 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT); 170 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT);
173 else 171 else
174 /* BN_mod_sqrt() should have cought this error (not a square) */ 172 /*
173 * BN_mod_sqrt() should have cought this
174 * error (not a square)
175 */
175 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); 176 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
176 goto err; 177 goto err;
177 }
178 if (!BN_usub(y, &group->field, y)) goto err;
179 } 178 }
180 if (y_bit != BN_is_odd(y)) 179 if (!BN_usub(y, &group->field, y))
181 { 180 goto err;
181 }
182 if (y_bit != BN_is_odd(y)) {
182 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR); 183 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR);
183 goto err; 184 goto err;
184 } 185 }
185 186 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
186 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; 187 goto err;
187 188
188 ret = 1; 189 ret = 1;
189 190
190 err: 191err:
191 BN_CTX_end(ctx); 192 BN_CTX_end(ctx);
192 if (new_ctx != NULL) 193 if (new_ctx != NULL)
193 BN_CTX_free(new_ctx); 194 BN_CTX_free(new_ctx);
194 return ret; 195 return ret;
195 } 196}
196 197
197 198
198size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, 199size_t
199 unsigned char *buf, size_t len, BN_CTX *ctx) 200ec_GFp_simple_point2oct(const EC_GROUP * group, const EC_POINT * point, point_conversion_form_t form,
200 { 201 unsigned char *buf, size_t len, BN_CTX * ctx)
202{
201 size_t ret; 203 size_t ret;
202 BN_CTX *new_ctx = NULL; 204 BN_CTX *new_ctx = NULL;
203 int used_ctx = 0; 205 int used_ctx = 0;
@@ -205,125 +207,106 @@ size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, poi
205 size_t field_len, i, skip; 207 size_t field_len, i, skip;
206 208
207 if ((form != POINT_CONVERSION_COMPRESSED) 209 if ((form != POINT_CONVERSION_COMPRESSED)
208 && (form != POINT_CONVERSION_UNCOMPRESSED) 210 && (form != POINT_CONVERSION_UNCOMPRESSED)
209 && (form != POINT_CONVERSION_HYBRID)) 211 && (form != POINT_CONVERSION_HYBRID)) {
210 {
211 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); 212 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
212 goto err; 213 goto err;
213 } 214 }
214 215 if (EC_POINT_is_at_infinity(group, point)) {
215 if (EC_POINT_is_at_infinity(group, point))
216 {
217 /* encodes to a single 0 octet */ 216 /* encodes to a single 0 octet */
218 if (buf != NULL) 217 if (buf != NULL) {
219 { 218 if (len < 1) {
220 if (len < 1)
221 {
222 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); 219 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
223 return 0; 220 return 0;
224 }
225 buf[0] = 0;
226 } 221 }
227 return 1; 222 buf[0] = 0;
228 } 223 }
229 224 return 1;
230 225 }
231 /* ret := required output buffer length */ 226 /* ret := required output buffer length */
232 field_len = BN_num_bytes(&group->field); 227 field_len = BN_num_bytes(&group->field);
233 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len; 228 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
234 229
235 /* if 'buf' is NULL, just return required length */ 230 /* if 'buf' is NULL, just return required length */
236 if (buf != NULL) 231 if (buf != NULL) {
237 { 232 if (len < ret) {
238 if (len < ret)
239 {
240 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); 233 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
241 goto err; 234 goto err;
242 } 235 }
243 236 if (ctx == NULL) {
244 if (ctx == NULL)
245 {
246 ctx = new_ctx = BN_CTX_new(); 237 ctx = new_ctx = BN_CTX_new();
247 if (ctx == NULL) 238 if (ctx == NULL)
248 return 0; 239 return 0;
249 } 240 }
250
251 BN_CTX_start(ctx); 241 BN_CTX_start(ctx);
252 used_ctx = 1; 242 used_ctx = 1;
253 x = BN_CTX_get(ctx); 243 x = BN_CTX_get(ctx);
254 y = BN_CTX_get(ctx); 244 y = BN_CTX_get(ctx);
255 if (y == NULL) goto err; 245 if (y == NULL)
246 goto err;
256 247
257 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; 248 if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
249 goto err;
258 250
259 if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) 251 if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
260 buf[0] = form + 1; 252 buf[0] = form + 1;
261 else 253 else
262 buf[0] = form; 254 buf[0] = form;
263 255
264 i = 1; 256 i = 1;
265 257
266 skip = field_len - BN_num_bytes(x); 258 skip = field_len - BN_num_bytes(x);
267 if (skip > field_len) 259 if (skip > field_len) {
268 {
269 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); 260 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
270 goto err; 261 goto err;
271 } 262 }
272 while (skip > 0) 263 while (skip > 0) {
273 {
274 buf[i++] = 0; 264 buf[i++] = 0;
275 skip--; 265 skip--;
276 } 266 }
277 skip = BN_bn2bin(x, buf + i); 267 skip = BN_bn2bin(x, buf + i);
278 i += skip; 268 i += skip;
279 if (i != 1 + field_len) 269 if (i != 1 + field_len) {
280 {
281 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); 270 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
282 goto err; 271 goto err;
283 } 272 }
284 273 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID) {
285 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
286 {
287 skip = field_len - BN_num_bytes(y); 274 skip = field_len - BN_num_bytes(y);
288 if (skip > field_len) 275 if (skip > field_len) {
289 {
290 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); 276 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
291 goto err; 277 goto err;
292 } 278 }
293 while (skip > 0) 279 while (skip > 0) {
294 {
295 buf[i++] = 0; 280 buf[i++] = 0;
296 skip--; 281 skip--;
297 } 282 }
298 skip = BN_bn2bin(y, buf + i); 283 skip = BN_bn2bin(y, buf + i);
299 i += skip; 284 i += skip;
300 } 285 }
301 286 if (i != ret) {
302 if (i != ret)
303 {
304 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); 287 ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
305 goto err; 288 goto err;
306 }
307 } 289 }
308 290 }
309 if (used_ctx) 291 if (used_ctx)
310 BN_CTX_end(ctx); 292 BN_CTX_end(ctx);
311 if (new_ctx != NULL) 293 if (new_ctx != NULL)
312 BN_CTX_free(new_ctx); 294 BN_CTX_free(new_ctx);
313 return ret; 295 return ret;
314 296
315 err: 297err:
316 if (used_ctx) 298 if (used_ctx)
317 BN_CTX_end(ctx); 299 BN_CTX_end(ctx);
318 if (new_ctx != NULL) 300 if (new_ctx != NULL)
319 BN_CTX_free(new_ctx); 301 BN_CTX_free(new_ctx);
320 return 0; 302 return 0;
321 } 303}
322 304
323 305
324int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, 306int
325 const unsigned char *buf, size_t len, BN_CTX *ctx) 307ec_GFp_simple_oct2point(const EC_GROUP * group, EC_POINT * point,
326 { 308 const unsigned char *buf, size_t len, BN_CTX * ctx)
309{
327 point_conversion_form_t form; 310 point_conversion_form_t form;
328 int y_bit; 311 int y_bit;
329 BN_CTX *new_ctx = NULL; 312 BN_CTX *new_ctx = NULL;
@@ -331,102 +314,84 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
331 size_t field_len, enc_len; 314 size_t field_len, enc_len;
332 int ret = 0; 315 int ret = 0;
333 316
334 if (len == 0) 317 if (len == 0) {
335 {
336 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); 318 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
337 return 0; 319 return 0;
338 } 320 }
339 form = buf[0]; 321 form = buf[0];
340 y_bit = form & 1; 322 y_bit = form & 1;
341 form = form & ~1U; 323 form = form & ~1U;
342 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) 324 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
343 && (form != POINT_CONVERSION_UNCOMPRESSED) 325 && (form != POINT_CONVERSION_UNCOMPRESSED)
344 && (form != POINT_CONVERSION_HYBRID)) 326 && (form != POINT_CONVERSION_HYBRID)) {
345 {
346 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 327 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
347 return 0; 328 return 0;
348 } 329 }
349 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) 330 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
350 {
351 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 331 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
352 return 0; 332 return 0;
353 } 333 }
354 334 if (form == 0) {
355 if (form == 0) 335 if (len != 1) {
356 {
357 if (len != 1)
358 {
359 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 336 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
360 return 0; 337 return 0;
361 }
362
363 return EC_POINT_set_to_infinity(group, point);
364 } 338 }
365 339 return EC_POINT_set_to_infinity(group, point);
340 }
366 field_len = BN_num_bytes(&group->field); 341 field_len = BN_num_bytes(&group->field);
367 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len; 342 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
368 343
369 if (len != enc_len) 344 if (len != enc_len) {
370 {
371 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 345 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
372 return 0; 346 return 0;
373 } 347 }
374 348 if (ctx == NULL) {
375 if (ctx == NULL)
376 {
377 ctx = new_ctx = BN_CTX_new(); 349 ctx = new_ctx = BN_CTX_new();
378 if (ctx == NULL) 350 if (ctx == NULL)
379 return 0; 351 return 0;
380 } 352 }
381
382 BN_CTX_start(ctx); 353 BN_CTX_start(ctx);
383 x = BN_CTX_get(ctx); 354 x = BN_CTX_get(ctx);
384 y = BN_CTX_get(ctx); 355 y = BN_CTX_get(ctx);
385 if (y == NULL) goto err; 356 if (y == NULL)
357 goto err;
386 358
387 if (!BN_bin2bn(buf + 1, field_len, x)) goto err; 359 if (!BN_bin2bn(buf + 1, field_len, x))
388 if (BN_ucmp(x, &group->field) >= 0) 360 goto err;
389 { 361 if (BN_ucmp(x, &group->field) >= 0) {
390 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 362 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
391 goto err; 363 goto err;
392 } 364 }
393 365 if (form == POINT_CONVERSION_COMPRESSED) {
394 if (form == POINT_CONVERSION_COMPRESSED) 366 if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx))
395 { 367 goto err;
396 if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err; 368 } else {
397 } 369 if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
398 else 370 goto err;
399 { 371 if (BN_ucmp(y, &group->field) >= 0) {
400 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
401 if (BN_ucmp(y, &group->field) >= 0)
402 {
403 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 372 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
404 goto err; 373 goto err;
405 } 374 }
406 if (form == POINT_CONVERSION_HYBRID) 375 if (form == POINT_CONVERSION_HYBRID) {
407 { 376 if (y_bit != BN_is_odd(y)) {
408 if (y_bit != BN_is_odd(y))
409 {
410 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 377 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
411 goto err; 378 goto err;
412 }
413 } 379 }
414
415 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
416 } 380 }
417 381 if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
418 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */ 382 goto err;
419 { 383 }
384
385 if (!EC_POINT_is_on_curve(group, point, ctx)) { /* test required by
386 * X9.62 */
420 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); 387 ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
421 goto err; 388 goto err;
422 } 389 }
423
424 ret = 1; 390 ret = 1;
425 391
426 err: 392err:
427 BN_CTX_end(ctx); 393 BN_CTX_end(ctx);
428 if (new_ctx != NULL) 394 if (new_ctx != NULL)
429 BN_CTX_free(new_ctx); 395 BN_CTX_free(new_ctx);
430 return ret; 396 return ret;
431 } 397}
432