diff options
-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); |