summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/ec/ec_key.c139
1 files changed, 80 insertions, 59 deletions
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c
index bad4779ed1..2ef5d75d47 100644
--- a/src/lib/libcrypto/ec/ec_key.c
+++ b/src/lib/libcrypto/ec/ec_key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_key.c,v 1.29 2022/11/26 16:08:52 tb Exp $ */ 1/* $OpenBSD: ec_key.c,v 1.30 2023/01/14 15:10:45 jsing Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project. 3 * Written by Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -259,84 +259,93 @@ EC_KEY_generate_key(EC_KEY *eckey)
259int 259int
260ossl_ec_key_gen(EC_KEY *eckey) 260ossl_ec_key_gen(EC_KEY *eckey)
261{ 261{
262 int ok = 0;
263 BN_CTX *ctx = NULL; 262 BN_CTX *ctx = NULL;
264 BIGNUM *priv_key = NULL, *order = NULL; 263 BIGNUM *priv_key = NULL;
265 EC_POINT *pub_key = NULL; 264 EC_POINT *pub_key = NULL;
265 BIGNUM *order;
266 int ret = 0;
266 267
267 if (!eckey || !eckey->group) { 268 if (eckey == NULL || eckey->group == NULL) {
268 ECerror(ERR_R_PASSED_NULL_PARAMETER); 269 ECerror(ERR_R_PASSED_NULL_PARAMETER);
269 return 0; 270 goto err;
270 } 271 }
271 272
272 if ((order = BN_new()) == NULL) 273 if ((priv_key = BN_new()) == NULL)
273 goto err; 274 goto err;
275 if ((pub_key = EC_POINT_new(eckey->group)) == NULL)
276 goto err;
277
274 if ((ctx = BN_CTX_new()) == NULL) 278 if ((ctx = BN_CTX_new()) == NULL)
275 goto err; 279 goto err;
276 280
277 if ((priv_key = eckey->priv_key) == NULL) { 281 BN_CTX_start(ctx);
278 if ((priv_key = BN_new()) == NULL)
279 goto err;
280 }
281 282
282 if (!EC_GROUP_get_order(eckey->group, order, ctx)) 283 if ((order = BN_CTX_get(ctx)) == NULL)
283 goto err; 284 goto err;
284 285
286 if (!EC_GROUP_get_order(eckey->group, order, ctx))
287 goto err;
285 if (!bn_rand_interval(priv_key, BN_value_one(), order)) 288 if (!bn_rand_interval(priv_key, BN_value_one(), order))
286 goto err; 289 goto err;
287
288 if ((pub_key = eckey->pub_key) == NULL) {
289 if ((pub_key = EC_POINT_new(eckey->group)) == NULL)
290 goto err;
291 }
292
293 if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) 290 if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
294 goto err; 291 goto err;
295 292
293 BN_free(eckey->priv_key);
296 eckey->priv_key = priv_key; 294 eckey->priv_key = priv_key;
295 priv_key = NULL;
296
297 EC_POINT_free(eckey->pub_key);
297 eckey->pub_key = pub_key; 298 eckey->pub_key = pub_key;
299 pub_key = NULL;
298 300
299 ok = 1; 301 ret = 1;
300 302
301 err: 303 err:
302 BN_free(order); 304 EC_POINT_free(pub_key);
303 if (eckey->pub_key == NULL) 305 BN_free(priv_key);
304 EC_POINT_free(pub_key); 306 BN_CTX_end(ctx);
305 if (eckey->priv_key == NULL)
306 BN_free(priv_key);
307 BN_CTX_free(ctx); 307 BN_CTX_free(ctx);
308 return (ok); 308
309 return ret;
309} 310}
310 311
311int 312int
312EC_KEY_check_key(const EC_KEY *eckey) 313EC_KEY_check_key(const EC_KEY *eckey)
313{ 314{
314 int ok = 0;
315 BN_CTX *ctx = NULL; 315 BN_CTX *ctx = NULL;
316 const BIGNUM *order = NULL;
317 EC_POINT *point = NULL; 316 EC_POINT *point = NULL;
317 BIGNUM *order;
318 int ret = 0;
318 319
319 if (!eckey || !eckey->group || !eckey->pub_key) { 320 if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
320 ECerror(ERR_R_PASSED_NULL_PARAMETER); 321 ECerror(ERR_R_PASSED_NULL_PARAMETER);
321 return 0; 322 goto err;
322 } 323 }
324
323 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key) > 0) { 325 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key) > 0) {
324 ECerror(EC_R_POINT_AT_INFINITY); 326 ECerror(EC_R_POINT_AT_INFINITY);
325 goto err; 327 goto err;
326 } 328 }
329
327 if ((ctx = BN_CTX_new()) == NULL) 330 if ((ctx = BN_CTX_new()) == NULL)
328 goto err; 331 goto err;
332
333 BN_CTX_start(ctx);
334
335 if ((order = BN_CTX_get(ctx)) == NULL)
336 goto err;
337
329 if ((point = EC_POINT_new(eckey->group)) == NULL) 338 if ((point = EC_POINT_new(eckey->group)) == NULL)
330 goto err; 339 goto err;
331 340
332 /* testing whether the pub_key is on the elliptic curve */ 341 /* Ensure public key is on the elliptic curve. */
333 if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { 342 if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
334 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 343 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
335 goto err; 344 goto err;
336 } 345 }
337 /* testing whether pub_key * order is the point at infinity */ 346
338 order = &eckey->group->order; 347 /* Ensure public key multiplied by the order is the point at infinity. */
339 if (BN_is_zero(order)) { 348 if (!EC_GROUP_get_order(eckey->group, order, ctx)) {
340 ECerror(EC_R_INVALID_GROUP_ORDER); 349 ECerror(EC_R_INVALID_GROUP_ORDER);
341 goto err; 350 goto err;
342 } 351 }
@@ -348,84 +357,90 @@ EC_KEY_check_key(const EC_KEY *eckey)
348 ECerror(EC_R_WRONG_ORDER); 357 ECerror(EC_R_WRONG_ORDER);
349 goto err; 358 goto err;
350 } 359 }
360
351 /* 361 /*
352 * in case the priv_key is present : check if generator * priv_key == 362 * If the private key is present, ensure that the private key multiplied
353 * pub_key 363 * by the generator matches the public key.
354 */ 364 */
355 if (eckey->priv_key) { 365 if (eckey->priv_key != NULL) {
356 if (BN_cmp(eckey->priv_key, order) >= 0) { 366 if (BN_cmp(eckey->priv_key, order) >= 0) {
357 ECerror(EC_R_WRONG_ORDER); 367 ECerror(EC_R_WRONG_ORDER);
358 goto err; 368 goto err;
359 } 369 }
360 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, 370 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL,
361 NULL, NULL, ctx)) { 371 NULL, ctx)) {
362 ECerror(ERR_R_EC_LIB); 372 ECerror(ERR_R_EC_LIB);
363 goto err; 373 goto err;
364 } 374 }
365 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, 375 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
366 ctx) != 0) { 376 ctx) != 0) {
367 ECerror(EC_R_INVALID_PRIVATE_KEY); 377 ECerror(EC_R_INVALID_PRIVATE_KEY);
368 goto err; 378 goto err;
369 } 379 }
370 } 380 }
371 ok = 1; 381
382 ret = 1;
383
372 err: 384 err:
385 BN_CTX_end(ctx);
373 BN_CTX_free(ctx); 386 BN_CTX_free(ctx);
374 EC_POINT_free(point); 387 EC_POINT_free(point);
375 return (ok); 388
389 return ret;
376} 390}
377 391
378int 392int
379EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y) 393EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y)
380{ 394{
381 BN_CTX *ctx = NULL; 395 BN_CTX *ctx = NULL;
382 BIGNUM *tx, *ty;
383 EC_POINT *point = NULL; 396 EC_POINT *point = NULL;
384 int ok = 0; 397 BIGNUM *tx, *ty;
398 int ret = 0;
385 399
386 if (!key || !key->group || !x || !y) { 400 if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
387 ECerror(ERR_R_PASSED_NULL_PARAMETER); 401 ECerror(ERR_R_PASSED_NULL_PARAMETER);
388 return 0;
389 }
390 ctx = BN_CTX_new();
391 if (!ctx)
392 goto err; 402 goto err;
403 }
393 404
394 point = EC_POINT_new(key->group); 405 if ((ctx = BN_CTX_new()) == NULL)
395
396 if (!point)
397 goto err; 406 goto err;
398 407
408 BN_CTX_start(ctx);
409
399 if ((tx = BN_CTX_get(ctx)) == NULL) 410 if ((tx = BN_CTX_get(ctx)) == NULL)
400 goto err; 411 goto err;
401 if ((ty = BN_CTX_get(ctx)) == NULL) 412 if ((ty = BN_CTX_get(ctx)) == NULL)
402 goto err; 413 goto err;
403 414
415 if ((point = EC_POINT_new(key->group)) == NULL)
416 goto err;
417
404 if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx)) 418 if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx))
405 goto err; 419 goto err;
406 if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx)) 420 if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx))
407 goto err; 421 goto err;
422
408 /* 423 /*
409 * Check if retrieved coordinates match originals: if not values are 424 * Check if retrieved coordinates match originals: if not values are
410 * out of range. 425 * out of range.
411 */ 426 */
412 if (BN_cmp(x, tx) || BN_cmp(y, ty)) { 427 if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) {
413 ECerror(EC_R_COORDINATES_OUT_OF_RANGE); 428 ECerror(EC_R_COORDINATES_OUT_OF_RANGE);
414 goto err; 429 goto err;
415 } 430 }
416 if (!EC_KEY_set_public_key(key, point)) 431 if (!EC_KEY_set_public_key(key, point))
417 goto err; 432 goto err;
418
419 if (EC_KEY_check_key(key) == 0) 433 if (EC_KEY_check_key(key) == 0)
420 goto err; 434 goto err;
421 435
422 ok = 1; 436 ret = 1;
423 437
424 err: 438 err:
439 BN_CTX_end(ctx);
425 BN_CTX_free(ctx); 440 BN_CTX_free(ctx);
426 EC_POINT_free(point); 441 EC_POINT_free(point);
427 return ok;
428 442
443 return ret;
429} 444}
430 445
431const EC_GROUP * 446const EC_GROUP *
@@ -457,9 +472,12 @@ EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
457 if (key->meth->set_private != NULL && 472 if (key->meth->set_private != NULL &&
458 key->meth->set_private(key, priv_key) == 0) 473 key->meth->set_private(key, priv_key) == 0)
459 return 0; 474 return 0;
460 BN_clear_free(key->priv_key); 475
461 key->priv_key = BN_dup(priv_key); 476 BN_free(key->priv_key);
462 return (key->priv_key == NULL) ? 0 : 1; 477 if ((key->priv_key = BN_dup(priv_key)) == NULL)
478 return 0;
479
480 return 1;
463} 481}
464 482
465const EC_POINT * 483const EC_POINT *
@@ -474,9 +492,12 @@ EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
474 if (key->meth->set_public != NULL && 492 if (key->meth->set_public != NULL &&
475 key->meth->set_public(key, pub_key) == 0) 493 key->meth->set_public(key, pub_key) == 0)
476 return 0; 494 return 0;
495
477 EC_POINT_free(key->pub_key); 496 EC_POINT_free(key->pub_key);
478 key->pub_key = EC_POINT_dup(pub_key, key->group); 497 if ((key->pub_key = EC_POINT_dup(pub_key, key->group)) == NULL)
479 return (key->pub_key == NULL) ? 0 : 1; 498 return 0;
499
500 return 1;
480} 501}
481 502
482unsigned int 503unsigned int