summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c4
-rw-r--r--src/lib/libcrypto/ec/ec_curve.c222
-rw-r--r--src/lib/libcrypto/ec/ec_local.h4
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}
2458LCRYPTO_ALIAS(EC_GROUP_new_by_curve_name); 2459LCRYPTO_ALIAS(EC_GROUP_new_by_curve_name);
2459 2460
2461static void
2462ec_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
2479static int
2480ec_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
2505static struct ec_list_element *
2506ec_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
2597static int
2598ec_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
2647static int
2648ec_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
2660int
2661ec_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
2460size_t 2680size_t
2461EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) 2681EC_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,
355int EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, 355int 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
358int ec_group_is_builtin_curve(const EC_GROUP *group);
359
358/* Public API in OpenSSL */ 360/* Public API in OpenSSL */
359const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); 361const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group);
360const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); 362const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);