diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/ec/ec_asn1.c | 4 | ||||
| -rw-r--r-- | src/lib/libcrypto/ec/ec_curve.c | 222 | ||||
| -rw-r--r-- | src/lib/libcrypto/ec/ec_local.h | 4 |
3 files changed, 227 insertions, 3 deletions
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c index 289bc3b271..548afb2d1a 100644 --- a/src/lib/libcrypto/ec/ec_asn1.c +++ b/src/lib/libcrypto/ec/ec_asn1.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ec_asn1.c,v 1.74 2024/10/17 14:34:06 tb Exp $ */ | 1 | /* $OpenBSD: ec_asn1.c,v 1.75 2024/10/18 17:27:07 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Written by Nils Larsch for the OpenSSL project. | 3 | * Written by Nils Larsch for the OpenSSL project. |
| 4 | */ | 4 | */ |
| @@ -993,6 +993,8 @@ ec_asn1_parameters2group(const ECPARAMETERS *params) | |||
| 993 | 993 | ||
| 994 | if (!ec_asn1_parameters_extract_prime_group(params, &group)) | 994 | if (!ec_asn1_parameters_extract_prime_group(params, &group)) |
| 995 | goto err; | 995 | goto err; |
| 996 | if (!ec_group_is_builtin_curve(group)) | ||
| 997 | goto err; | ||
| 996 | 998 | ||
| 997 | return group; | 999 | return group; |
| 998 | 1000 | ||
diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c index dc7779358d..2529229ba5 100644 --- a/src/lib/libcrypto/ec/ec_curve.c +++ b/src/lib/libcrypto/ec/ec_curve.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ec_curve.c,v 1.43 2024/03/24 06:05:41 tb Exp $ */ | 1 | /* $OpenBSD: ec_curve.c,v 1.44 2024/10/18 17:27:07 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Written by Nils Larsch for the OpenSSL project. | 3 | * Written by Nils Larsch for the OpenSSL project. |
| 4 | */ | 4 | */ |
| @@ -69,6 +69,7 @@ | |||
| 69 | * | 69 | * |
| 70 | */ | 70 | */ |
| 71 | 71 | ||
| 72 | #include <limits.h> | ||
| 72 | #include <string.h> | 73 | #include <string.h> |
| 73 | 74 | ||
| 74 | #include <openssl/opensslconf.h> | 75 | #include <openssl/opensslconf.h> |
| @@ -2457,6 +2458,225 @@ EC_GROUP_new_by_curve_name(int nid) | |||
| 2457 | } | 2458 | } |
| 2458 | LCRYPTO_ALIAS(EC_GROUP_new_by_curve_name); | 2459 | LCRYPTO_ALIAS(EC_GROUP_new_by_curve_name); |
| 2459 | 2460 | ||
| 2461 | static void | ||
| 2462 | ec_list_element_free(struct ec_list_element *curve) | ||
| 2463 | { | ||
| 2464 | if (curve == NULL) | ||
| 2465 | return; | ||
| 2466 | |||
| 2467 | /* PERM UGLY CASTS */ | ||
| 2468 | free((uint8_t *)curve->seed); | ||
| 2469 | free((uint8_t *)curve->p); | ||
| 2470 | free((uint8_t *)curve->a); | ||
| 2471 | free((uint8_t *)curve->b); | ||
| 2472 | free((uint8_t *)curve->x); | ||
| 2473 | free((uint8_t *)curve->y); | ||
| 2474 | free((uint8_t *)curve->order); | ||
| 2475 | |||
| 2476 | free(curve); | ||
| 2477 | } | ||
| 2478 | |||
| 2479 | static int | ||
| 2480 | ec_list_element_encode_parameter(const BIGNUM *bn, int param_len, | ||
| 2481 | const uint8_t **out_param) | ||
| 2482 | { | ||
| 2483 | uint8_t *buf = NULL; | ||
| 2484 | int ret = 0; | ||
| 2485 | |||
| 2486 | if (out_param == NULL || *out_param != NULL) | ||
| 2487 | goto err; | ||
| 2488 | |||
| 2489 | if ((buf = calloc(1, param_len)) == NULL) | ||
| 2490 | goto err; | ||
| 2491 | if (BN_bn2binpad(bn, buf, param_len) != param_len) | ||
| 2492 | goto err; | ||
| 2493 | |||
| 2494 | *out_param = buf; | ||
| 2495 | buf = NULL; | ||
| 2496 | |||
| 2497 | ret = 1; | ||
| 2498 | |||
| 2499 | err: | ||
| 2500 | free(buf); | ||
| 2501 | |||
| 2502 | return ret; | ||
| 2503 | } | ||
| 2504 | |||
| 2505 | static struct ec_list_element * | ||
| 2506 | ec_list_element_from_group(const EC_GROUP *group) | ||
| 2507 | { | ||
| 2508 | struct ec_list_element *curve = NULL; | ||
| 2509 | BN_CTX *ctx; | ||
| 2510 | BIGNUM *p, *a, *b, *x, *y; | ||
| 2511 | const EC_POINT *generator = NULL; | ||
| 2512 | const BIGNUM *order, *cofactor; | ||
| 2513 | size_t seed_len; | ||
| 2514 | |||
| 2515 | if ((ctx = BN_CTX_new()) == NULL) | ||
| 2516 | goto err; | ||
| 2517 | BN_CTX_start(ctx); | ||
| 2518 | |||
| 2519 | if ((p = BN_CTX_get(ctx)) == NULL) | ||
| 2520 | goto err; | ||
| 2521 | if ((a = BN_CTX_get(ctx)) == NULL) | ||
| 2522 | goto err; | ||
| 2523 | if ((b = BN_CTX_get(ctx)) == NULL) | ||
| 2524 | goto err; | ||
| 2525 | if ((x = BN_CTX_get(ctx)) == NULL) | ||
| 2526 | goto err; | ||
| 2527 | if ((y = BN_CTX_get(ctx)) == NULL) | ||
| 2528 | goto err; | ||
| 2529 | |||
| 2530 | if (!EC_GROUP_get_curve(group, p, a, b, ctx)) | ||
| 2531 | goto err; | ||
| 2532 | if ((generator = EC_GROUP_get0_generator(group)) == NULL) | ||
| 2533 | goto err; | ||
| 2534 | if (!EC_POINT_get_affine_coordinates(group, generator, x, y, ctx)) | ||
| 2535 | goto err; | ||
| 2536 | if ((order = EC_GROUP_get0_order(group)) == NULL) | ||
| 2537 | goto err; | ||
| 2538 | |||
| 2539 | if ((curve = calloc(1, sizeof(*curve))) == NULL) | ||
| 2540 | goto err; | ||
| 2541 | |||
| 2542 | curve->param_len = BN_num_bytes(p); | ||
| 2543 | if (BN_num_bytes(order) > curve->param_len) | ||
| 2544 | curve->param_len = BN_num_bytes(order); | ||
| 2545 | |||
| 2546 | if (!ec_list_element_encode_parameter(p, curve->param_len, &curve->p)) | ||
| 2547 | goto err; | ||
| 2548 | if (!ec_list_element_encode_parameter(a, curve->param_len, &curve->a)) | ||
| 2549 | goto err; | ||
| 2550 | if (!ec_list_element_encode_parameter(b, curve->param_len, &curve->b)) | ||
| 2551 | goto err; | ||
| 2552 | if (!ec_list_element_encode_parameter(x, curve->param_len, &curve->x)) | ||
| 2553 | goto err; | ||
| 2554 | if (!ec_list_element_encode_parameter(y, curve->param_len, &curve->y)) | ||
| 2555 | goto err; | ||
| 2556 | if (!ec_list_element_encode_parameter(order, curve->param_len, &curve->order)) | ||
| 2557 | goto err; | ||
| 2558 | |||
| 2559 | if ((cofactor = EC_GROUP_get0_cofactor(group)) != NULL) { | ||
| 2560 | BN_ULONG cofactor_word; | ||
| 2561 | |||
| 2562 | if ((cofactor_word = BN_get_word(cofactor)) == BN_MASK2) | ||
| 2563 | goto err; | ||
| 2564 | if (cofactor_word > INT_MAX) | ||
| 2565 | goto err; | ||
| 2566 | |||
| 2567 | curve->cofactor = cofactor_word; | ||
| 2568 | } | ||
| 2569 | |||
| 2570 | if ((seed_len = EC_GROUP_get_seed_len(group)) > 0) { | ||
| 2571 | uint8_t *seed; | ||
| 2572 | |||
| 2573 | if (seed_len > INT_MAX) | ||
| 2574 | goto err; | ||
| 2575 | if ((seed = calloc(1, seed_len)) == NULL) | ||
| 2576 | goto err; | ||
| 2577 | memcpy(seed, EC_GROUP_get0_seed(group), seed_len); | ||
| 2578 | |||
| 2579 | curve->seed = seed; | ||
| 2580 | curve->seed_len = seed_len; | ||
| 2581 | } | ||
| 2582 | |||
| 2583 | BN_CTX_end(ctx); | ||
| 2584 | BN_CTX_free(ctx); | ||
| 2585 | |||
| 2586 | return curve; | ||
| 2587 | |||
| 2588 | err: | ||
| 2589 | BN_CTX_end(ctx); | ||
| 2590 | BN_CTX_free(ctx); | ||
| 2591 | |||
| 2592 | ec_list_element_free(curve); | ||
| 2593 | |||
| 2594 | return NULL; | ||
| 2595 | } | ||
| 2596 | |||
| 2597 | static int | ||
| 2598 | ec_list_element_cmp(const struct ec_list_element *a, const struct ec_list_element *b) | ||
| 2599 | { | ||
| 2600 | int cmp; | ||
| 2601 | |||
| 2602 | /* Treat nid as optional. The OID isn't part of EC parameters. */ | ||
| 2603 | if (a->nid != NID_undef && b->nid != NID_undef) { | ||
| 2604 | if (a->nid < b->nid) | ||
| 2605 | return -1; | ||
| 2606 | if (a->nid > b->nid) | ||
| 2607 | return 1; | ||
| 2608 | } | ||
| 2609 | |||
| 2610 | if (a->cofactor < b->cofactor) | ||
| 2611 | return -1; | ||
| 2612 | if (a->cofactor > b->cofactor) | ||
| 2613 | return 1; | ||
| 2614 | if (a->param_len < b->param_len) | ||
| 2615 | return -1; | ||
| 2616 | if (a->param_len > b->param_len) | ||
| 2617 | return 1; | ||
| 2618 | |||
| 2619 | if ((cmp = memcmp(a->p, b->p, a->param_len)) != 0) | ||
| 2620 | return cmp; | ||
| 2621 | if ((cmp = memcmp(a->a, b->a, a->param_len)) != 0) | ||
| 2622 | return cmp; | ||
| 2623 | if ((cmp = memcmp(a->b, b->b, a->param_len)) != 0) | ||
| 2624 | return cmp; | ||
| 2625 | if ((cmp = memcmp(a->x, b->x, a->param_len)) != 0) | ||
| 2626 | return cmp; | ||
| 2627 | if ((cmp = memcmp(a->y, b->y, a->param_len)) != 0) | ||
| 2628 | return cmp; | ||
| 2629 | if ((cmp = memcmp(a->order, b->order, a->param_len)) != 0) | ||
| 2630 | return cmp; | ||
| 2631 | |||
| 2632 | /* Seed is optional, not used for computation. Must match if present. */ | ||
| 2633 | if (a->seed_len != 0 && b->seed_len != 0) { | ||
| 2634 | if (a->seed_len < b->seed_len) | ||
| 2635 | return -1; | ||
| 2636 | if (a->seed_len > b->seed_len) | ||
| 2637 | return 1; | ||
| 2638 | if (a->seed != NULL && b->seed != NULL) { | ||
| 2639 | if ((cmp = memcmp(a->seed, b->seed, a->seed_len)) != 0) | ||
| 2640 | return cmp; | ||
| 2641 | } | ||
| 2642 | } | ||
| 2643 | |||
| 2644 | return 0; | ||
| 2645 | } | ||
| 2646 | |||
| 2647 | static int | ||
| 2648 | ec_group_nid_from_curve(const struct ec_list_element *curve) | ||
| 2649 | { | ||
| 2650 | size_t i; | ||
| 2651 | |||
| 2652 | for (i = 0; i < CURVE_LIST_LENGTH; i++) { | ||
| 2653 | if (ec_list_element_cmp(curve, &curve_list[i]) == 0) | ||
| 2654 | return curve_list[i].nid; | ||
| 2655 | } | ||
| 2656 | |||
| 2657 | return NID_undef; | ||
| 2658 | } | ||
| 2659 | |||
| 2660 | int | ||
| 2661 | ec_group_is_builtin_curve(const EC_GROUP *group) | ||
| 2662 | { | ||
| 2663 | struct ec_list_element *curve; | ||
| 2664 | int ret = 0; | ||
| 2665 | |||
| 2666 | if ((curve = ec_list_element_from_group(group)) == NULL) | ||
| 2667 | goto err; | ||
| 2668 | |||
| 2669 | if (ec_group_nid_from_curve(curve) == NID_undef) | ||
| 2670 | goto err; | ||
| 2671 | |||
| 2672 | ret = 1; | ||
| 2673 | |||
| 2674 | err: | ||
| 2675 | ec_list_element_free(curve); | ||
| 2676 | |||
| 2677 | return ret; | ||
| 2678 | } | ||
| 2679 | |||
| 2460 | size_t | 2680 | size_t |
| 2461 | EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) | 2681 | EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) |
| 2462 | { | 2682 | { |
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h index ca55770ba8..b837e291f7 100644 --- a/src/lib/libcrypto/ec/ec_local.h +++ b/src/lib/libcrypto/ec/ec_local.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ec_local.h,v 1.29 2024/10/15 06:27:43 tb Exp $ */ | 1 | /* $OpenBSD: ec_local.h,v 1.30 2024/10/18 17:27:07 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Originally written by Bodo Moeller for the OpenSSL project. | 3 | * Originally written by Bodo Moeller for the OpenSSL project. |
| 4 | */ | 4 | */ |
| @@ -355,6 +355,8 @@ int EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *p, | |||
| 355 | int EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, | 355 | int EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, |
| 356 | const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); | 356 | const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); |
| 357 | 357 | ||
| 358 | int ec_group_is_builtin_curve(const EC_GROUP *group); | ||
| 359 | |||
| 358 | /* Public API in OpenSSL */ | 360 | /* Public API in OpenSSL */ |
| 359 | const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); | 361 | const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); |
| 360 | const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); | 362 | const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); |
