summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec/ec2_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/ec2_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/ec2_oct.c311
1 files changed, 142 insertions, 169 deletions
diff --git a/src/lib/libcrypto/ec/ec2_oct.c b/src/lib/libcrypto/ec/ec2_oct.c
index f1d75e5ddf..a856a5b1a7 100644
--- a/src/lib/libcrypto/ec/ec2_oct.c
+++ b/src/lib/libcrypto/ec/ec2_oct.c
@@ -21,7 +21,7 @@
21 * are met: 21 * are met:
22 * 22 *
23 * 1. Redistributions of source code must retain the above copyright 23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer. 24 * notice, this list of conditions and the following disclaimer.
25 * 25 *
26 * 2. Redistributions in binary form must reproduce the above copyright 26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in 27 * notice, this list of conditions and the following disclaimer in
@@ -74,11 +74,11 @@
74#ifndef OPENSSL_NO_EC2M 74#ifndef OPENSSL_NO_EC2M
75 75
76/* Calculates and sets the affine coordinates of an EC_POINT from the given 76/* Calculates and sets the affine coordinates of an EC_POINT from the given
77 * compressed coordinates. Uses algorithm 2.3.4 of SEC 1. 77 * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
78 * Note that the simple implementation only uses affine coordinates. 78 * Note that the simple implementation only uses affine coordinates.
79 * 79 *
80 * The method is from the following publication: 80 * The method is from the following publication:
81 * 81 *
82 * Harper, Menezes, Vanstone: 82 * Harper, Menezes, Vanstone:
83 * "Public-Key Cryptosystems with Very Small Key Lengths", 83 * "Public-Key Cryptosystems with Very Small Key Lengths",
84 * EUROCRYPT '92, Springer-Verlag LNCS 658, 84 * EUROCRYPT '92, Springer-Verlag LNCS 658,
@@ -88,9 +88,10 @@
88 * the same method, but claim no priority date earlier than July 29, 1994 88 * the same method, but claim no priority date earlier than July 29, 1994
89 * (and additionally fail to cite the EUROCRYPT '92 publication as prior art). 89 * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
90 */ 90 */
91int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 91int
92 const BIGNUM *x_, int y_bit, BN_CTX *ctx) 92ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
93 { 93 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
94{
94 BN_CTX *new_ctx = NULL; 95 BN_CTX *new_ctx = NULL;
95 BIGNUM *tmp, *x, *y, *z; 96 BIGNUM *tmp, *x, *y, *z;
96 int ret = 0, z0; 97 int ret = 0, z0;
@@ -98,13 +99,11 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p
98 /* clear error queue */ 99 /* clear error queue */
99 ERR_clear_error(); 100 ERR_clear_error();
100 101
101 if (ctx == NULL) 102 if (ctx == NULL) {
102 {
103 ctx = new_ctx = BN_CTX_new(); 103 ctx = new_ctx = BN_CTX_new();
104 if (ctx == NULL) 104 if (ctx == NULL)
105 return 0; 105 return 0;
106 } 106 }
107
108 y_bit = (y_bit != 0) ? 1 : 0; 107 y_bit = (y_bit != 0) ? 1 : 0;
109 108
110 BN_CTX_start(ctx); 109 BN_CTX_start(ctx);
@@ -112,59 +111,65 @@ int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p
112 x = BN_CTX_get(ctx); 111 x = BN_CTX_get(ctx);
113 y = BN_CTX_get(ctx); 112 y = BN_CTX_get(ctx);
114 z = BN_CTX_get(ctx); 113 z = BN_CTX_get(ctx);
115 if (z == NULL) goto err; 114 if (z == NULL)
115 goto err;
116 116
117 if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err; 117 if (!BN_GF2m_mod_arr(x, x_, group->poly))
118 if (BN_is_zero(x)) 118 goto err;
119 { 119 if (BN_is_zero(x)) {
120 if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err; 120 if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx))
121 } 121 goto err;
122 else 122 } else {
123 { 123 if (!group->meth->field_sqr(group, tmp, x, ctx))
124 if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err; 124 goto err;
125 if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err; 125 if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx))
126 if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err; 126 goto err;
127 if (!BN_GF2m_add(tmp, x, tmp)) goto err; 127 if (!BN_GF2m_add(tmp, &group->a, tmp))
128 if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) 128 goto err;
129 { 129 if (!BN_GF2m_add(tmp, x, tmp))
130 goto err;
131 if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) {
130 unsigned long err = ERR_peek_last_error(); 132 unsigned long err = ERR_peek_last_error();
131 133
132 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) 134 if (ERR_GET_LIB(err) == ERR_LIB_BN &&
133 { 135 ERR_GET_REASON(err) == BN_R_NO_SOLUTION) {
134 ERR_clear_error(); 136 ERR_clear_error();
135 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); 137 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
136 } 138 } else
137 else
138 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB); 139 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB);
139 goto err; 140 goto err;
140 } 141 }
141 z0 = (BN_is_odd(z)) ? 1 : 0; 142 z0 = (BN_is_odd(z)) ? 1 : 0;
142 if (!group->meth->field_mul(group, y, x, z, ctx)) goto err; 143 if (!group->meth->field_mul(group, y, x, z, ctx))
143 if (z0 != y_bit) 144 goto err;
144 { 145 if (z0 != y_bit) {
145 if (!BN_GF2m_add(y, y, x)) goto err; 146 if (!BN_GF2m_add(y, y, x))
146 } 147 goto err;
147 } 148 }
149 }
148 150
149 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; 151 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
152 goto err;
150 153
151 ret = 1; 154 ret = 1;
152 155
153 err: 156err:
154 BN_CTX_end(ctx); 157 BN_CTX_end(ctx);
155 if (new_ctx != NULL) 158 if (new_ctx != NULL)
156 BN_CTX_free(new_ctx); 159 BN_CTX_free(new_ctx);
157 return ret; 160 return ret;
158 } 161}
159 162
160 163
161/* Converts an EC_POINT to an octet string. 164/* Converts an EC_POINT to an octet string.
162 * If buf is NULL, the encoded length will be returned. 165 * If buf is NULL, the encoded length will be returned.
163 * If the length len of buf is smaller than required an error will be returned. 166 * If the length len of buf is smaller than required an error will be returned.
164 */ 167 */
165size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, 168size_t
166 unsigned char *buf, size_t len, BN_CTX *ctx) 169ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
167 { 170 point_conversion_form_t form,
171 unsigned char *buf, size_t len, BN_CTX * ctx)
172{
168 size_t ret; 173 size_t ret;
169 BN_CTX *new_ctx = NULL; 174 BN_CTX *new_ctx = NULL;
170 int used_ctx = 0; 175 int used_ctx = 0;
@@ -172,131 +177,114 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po
172 size_t field_len, i, skip; 177 size_t field_len, i, skip;
173 178
174 if ((form != POINT_CONVERSION_COMPRESSED) 179 if ((form != POINT_CONVERSION_COMPRESSED)
175 && (form != POINT_CONVERSION_UNCOMPRESSED) 180 && (form != POINT_CONVERSION_UNCOMPRESSED)
176 && (form != POINT_CONVERSION_HYBRID)) 181 && (form != POINT_CONVERSION_HYBRID)) {
177 {
178 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); 182 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
179 goto err; 183 goto err;
180 } 184 }
181 185 if (EC_POINT_is_at_infinity(group, point)) {
182 if (EC_POINT_is_at_infinity(group, point))
183 {
184 /* encodes to a single 0 octet */ 186 /* encodes to a single 0 octet */
185 if (buf != NULL) 187 if (buf != NULL) {
186 { 188 if (len < 1) {
187 if (len < 1)
188 {
189 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); 189 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
190 return 0; 190 return 0;
191 }
192 buf[0] = 0;
193 } 191 }
194 return 1; 192 buf[0] = 0;
195 } 193 }
196 194 return 1;
197 195 }
198 /* ret := required output buffer length */ 196 /* ret := required output buffer length */
199 field_len = (EC_GROUP_get_degree(group) + 7) / 8; 197 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
200 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len; 198 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len :
199 1 + 2 * field_len;
201 200
202 /* if 'buf' is NULL, just return required length */ 201 /* if 'buf' is NULL, just return required length */
203 if (buf != NULL) 202 if (buf != NULL) {
204 { 203 if (len < ret) {
205 if (len < ret)
206 {
207 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); 204 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
208 goto err; 205 goto err;
209 } 206 }
210 207 if (ctx == NULL) {
211 if (ctx == NULL)
212 {
213 ctx = new_ctx = BN_CTX_new(); 208 ctx = new_ctx = BN_CTX_new();
214 if (ctx == NULL) 209 if (ctx == NULL)
215 return 0; 210 return 0;
216 } 211 }
217
218 BN_CTX_start(ctx); 212 BN_CTX_start(ctx);
219 used_ctx = 1; 213 used_ctx = 1;
220 x = BN_CTX_get(ctx); 214 x = BN_CTX_get(ctx);
221 y = BN_CTX_get(ctx); 215 y = BN_CTX_get(ctx);
222 yxi = BN_CTX_get(ctx); 216 yxi = BN_CTX_get(ctx);
223 if (yxi == NULL) goto err; 217 if (yxi == NULL)
218 goto err;
224 219
225 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; 220 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
221 goto err;
226 222
227 buf[0] = form; 223 buf[0] = form;
228 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) 224 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) {
229 { 225 if (!group->meth->field_div(group, yxi, y, x, ctx))
230 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; 226 goto err;
231 if (BN_is_odd(yxi)) buf[0]++; 227 if (BN_is_odd(yxi))
232 } 228 buf[0]++;
233 229 }
234 i = 1; 230 i = 1;
235 231
236 skip = field_len - BN_num_bytes(x); 232 skip = field_len - BN_num_bytes(x);
237 if (skip > field_len) 233 if (skip > field_len) {
238 {
239 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); 234 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
240 goto err; 235 goto err;
241 } 236 }
242 while (skip > 0) 237 while (skip > 0) {
243 {
244 buf[i++] = 0; 238 buf[i++] = 0;
245 skip--; 239 skip--;
246 } 240 }
247 skip = BN_bn2bin(x, buf + i); 241 skip = BN_bn2bin(x, buf + i);
248 i += skip; 242 i += skip;
249 if (i != 1 + field_len) 243 if (i != 1 + field_len) {
250 {
251 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); 244 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
252 goto err; 245 goto err;
253 } 246 }
254 247 if (form == POINT_CONVERSION_UNCOMPRESSED ||
255 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID) 248 form == POINT_CONVERSION_HYBRID) {
256 {
257 skip = field_len - BN_num_bytes(y); 249 skip = field_len - BN_num_bytes(y);
258 if (skip > field_len) 250 if (skip > field_len) {
259 {
260 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); 251 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
261 goto err; 252 goto err;
262 } 253 }
263 while (skip > 0) 254 while (skip > 0) {
264 {
265 buf[i++] = 0; 255 buf[i++] = 0;
266 skip--; 256 skip--;
267 } 257 }
268 skip = BN_bn2bin(y, buf + i); 258 skip = BN_bn2bin(y, buf + i);
269 i += skip; 259 i += skip;
270 } 260 }
271 261 if (i != ret) {
272 if (i != ret)
273 {
274 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); 262 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
275 goto err; 263 goto err;
276 }
277 } 264 }
278 265 }
279 if (used_ctx) 266 if (used_ctx)
280 BN_CTX_end(ctx); 267 BN_CTX_end(ctx);
281 if (new_ctx != NULL) 268 if (new_ctx != NULL)
282 BN_CTX_free(new_ctx); 269 BN_CTX_free(new_ctx);
283 return ret; 270 return ret;
284 271
285 err: 272err:
286 if (used_ctx) 273 if (used_ctx)
287 BN_CTX_end(ctx); 274 BN_CTX_end(ctx);
288 if (new_ctx != NULL) 275 if (new_ctx != NULL)
289 BN_CTX_free(new_ctx); 276 BN_CTX_free(new_ctx);
290 return 0; 277 return 0;
291 } 278}
292 279
293 280
294/* Converts an octet string representation to an EC_POINT. 281/* Converts an octet string representation to an EC_POINT.
295 * Note that the simple implementation only uses affine coordinates. 282 * Note that the simple implementation only uses affine coordinates.
296 */ 283 */
297int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, 284int
298 const unsigned char *buf, size_t len, BN_CTX *ctx) 285ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
299 { 286 const unsigned char *buf, size_t len, BN_CTX *ctx)
287{
300 point_conversion_form_t form; 288 point_conversion_form_t form;
301 int y_bit; 289 int y_bit;
302 BN_CTX *new_ctx = NULL; 290 BN_CTX *new_ctx = NULL;
@@ -304,104 +292,89 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
304 size_t field_len, enc_len; 292 size_t field_len, enc_len;
305 int ret = 0; 293 int ret = 0;
306 294
307 if (len == 0) 295 if (len == 0) {
308 {
309 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); 296 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
310 return 0; 297 return 0;
311 } 298 }
312 form = buf[0]; 299 form = buf[0];
313 y_bit = form & 1; 300 y_bit = form & 1;
314 form = form & ~1U; 301 form = form & ~1U;
315 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) 302 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
316 && (form != POINT_CONVERSION_UNCOMPRESSED) 303 (form != POINT_CONVERSION_UNCOMPRESSED) &&
317 && (form != POINT_CONVERSION_HYBRID)) 304 (form != POINT_CONVERSION_HYBRID)) {
318 {
319 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 305 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
320 return 0; 306 return 0;
321 } 307 }
322 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) 308 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
323 {
324 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 309 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
325 return 0; 310 return 0;
326 } 311 }
327 312 if (form == 0) {
328 if (form == 0) 313 if (len != 1) {
329 {
330 if (len != 1)
331 {
332 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 314 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
333 return 0; 315 return 0;
334 }
335
336 return EC_POINT_set_to_infinity(group, point);
337 } 316 }
338 317 return EC_POINT_set_to_infinity(group, point);
318 }
339 field_len = (EC_GROUP_get_degree(group) + 7) / 8; 319 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
340 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len; 320 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len :
321 1 + 2 * field_len;
341 322
342 if (len != enc_len) 323 if (len != enc_len) {
343 {
344 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 324 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
345 return 0; 325 return 0;
346 } 326 }
347 327 if (ctx == NULL) {
348 if (ctx == NULL)
349 {
350 ctx = new_ctx = BN_CTX_new(); 328 ctx = new_ctx = BN_CTX_new();
351 if (ctx == NULL) 329 if (ctx == NULL)
352 return 0; 330 return 0;
353 } 331 }
354
355 BN_CTX_start(ctx); 332 BN_CTX_start(ctx);
356 x = BN_CTX_get(ctx); 333 x = BN_CTX_get(ctx);
357 y = BN_CTX_get(ctx); 334 y = BN_CTX_get(ctx);
358 yxi = BN_CTX_get(ctx); 335 yxi = BN_CTX_get(ctx);
359 if (yxi == NULL) goto err; 336 if (yxi == NULL)
337 goto err;
360 338
361 if (!BN_bin2bn(buf + 1, field_len, x)) goto err; 339 if (!BN_bin2bn(buf + 1, field_len, x))
362 if (BN_ucmp(x, &group->field) >= 0) 340 goto err;
363 { 341 if (BN_ucmp(x, &group->field) >= 0) {
364 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 342 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
365 goto err; 343 goto err;
366 } 344 }
367 345 if (form == POINT_CONVERSION_COMPRESSED) {
368 if (form == POINT_CONVERSION_COMPRESSED) 346 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx))
369 { 347 goto err;
370 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err; 348 } else {
371 } 349 if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
372 else 350 goto err;
373 { 351 if (BN_ucmp(y, &group->field) >= 0) {
374 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
375 if (BN_ucmp(y, &group->field) >= 0)
376 {
377 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 352 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
378 goto err; 353 goto err;
379 } 354 }
380 if (form == POINT_CONVERSION_HYBRID) 355 if (form == POINT_CONVERSION_HYBRID) {
381 { 356 if (!group->meth->field_div(group, yxi, y, x, ctx))
382 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; 357 goto err;
383 if (y_bit != BN_is_odd(yxi)) 358 if (y_bit != BN_is_odd(yxi)) {
384 {
385 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); 359 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
386 goto err; 360 goto err;
387 }
388 } 361 }
389
390 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
391 } 362 }
392 363 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
393 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */ 364 goto err;
394 { 365 }
366
367 if (!EC_POINT_is_on_curve(group, point, ctx)) {
368 /* test required by X9.62 */
395 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); 369 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
396 goto err; 370 goto err;
397 } 371 }
398
399 ret = 1; 372 ret = 1;
400 373
401 err: 374err:
402 BN_CTX_end(ctx); 375 BN_CTX_end(ctx);
403 if (new_ctx != NULL) 376 if (new_ctx != NULL)
404 BN_CTX_free(new_ctx); 377 BN_CTX_free(new_ctx);
405 return ret; 378 return ret;
406 } 379}
407#endif 380#endif