diff options
Diffstat (limited to 'src/lib/libcrypto')
| -rw-r--r-- | src/lib/libcrypto/ec/ecp_hp_methods.c | 119 | 
1 files changed, 103 insertions, 16 deletions
| diff --git a/src/lib/libcrypto/ec/ecp_hp_methods.c b/src/lib/libcrypto/ec/ecp_hp_methods.c index bd414f49aa..0b34a55b9d 100644 --- a/src/lib/libcrypto/ec/ecp_hp_methods.c +++ b/src/lib/libcrypto/ec/ecp_hp_methods.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ecp_hp_methods.c,v 1.4 2025/08/03 15:08:28 jsing Exp $ */ | 1 | /* $OpenBSD: ecp_hp_methods.c,v 1.5 2025/08/03 15:44:00 jsing Exp $ */ | 
| 2 | /* | 2 | /* | 
| 3 | * Copyright (c) 2024-2025 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2024-2025 Joel Sing <jsing@openbsd.org> | 
| 4 | * | 4 | * | 
| @@ -22,15 +22,11 @@ | |||
| 22 | #include <openssl/err.h> | 22 | #include <openssl/err.h> | 
| 23 | 23 | ||
| 24 | #include "bn_internal.h" | 24 | #include "bn_internal.h" | 
| 25 | #include "crypto_internal.h" | ||
| 25 | #include "ec_local.h" | 26 | #include "ec_local.h" | 
| 26 | #include "ec_internal.h" | 27 | #include "ec_internal.h" | 
| 27 | #include "err_local.h" | 28 | #include "err_local.h" | 
| 28 | 29 | ||
| 29 | /* | ||
| 30 | * TODO: | ||
| 31 | * - Constant time and blinding for scalar multiplication | ||
| 32 | */ | ||
| 33 | |||
| 34 | static int | 30 | static int | 
| 35 | ec_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, | 31 | ec_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, | 
| 36 | const BIGNUM *b, BN_CTX *ctx) | 32 | const BIGNUM *b, BN_CTX *ctx) | 
| @@ -781,38 +777,129 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], | |||
| 781 | } | 777 | } | 
| 782 | #endif | 778 | #endif | 
| 783 | 779 | ||
| 780 | static void | ||
| 781 | ec_point_select(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, | ||
| 782 | const EC_POINT *b, int conditional) | ||
| 783 | { | ||
| 784 | ec_field_element_select(&group->fm, &r->fe_x, &a->fe_x, &b->fe_x, conditional); | ||
| 785 | ec_field_element_select(&group->fm, &r->fe_y, &a->fe_y, &b->fe_y, conditional); | ||
| 786 | ec_field_element_select(&group->fm, &r->fe_z, &a->fe_z, &b->fe_z, conditional); | ||
| 787 | } | ||
| 788 | |||
| 784 | static int | 789 | static int | 
| 785 | ec_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, | 790 | ec_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, | 
| 786 | BN_CTX *ctx) | 791 | BN_CTX *ctx) | 
| 787 | { | 792 | { | 
| 788 | EC_POINT *rr; | 793 | BIGNUM *cardinality; | 
| 789 | int bits, i; | 794 | EC_POINT *multiples[15]; | 
| 795 | EC_POINT *rr = NULL, *t = NULL; | ||
| 796 | uint8_t *scalar_bytes = NULL; | ||
| 797 | int scalar_len = 0; | ||
| 798 | uint8_t j, wv; | ||
| 799 | int conditional, i; | ||
| 790 | int ret = 0; | 800 | int ret = 0; | 
| 791 | 801 | ||
| 792 | /* XXX - need constant time and blinding. */ | 802 | memset(multiples, 0, sizeof(multiples)); | 
| 803 | |||
| 804 | BN_CTX_start(ctx); | ||
| 805 | |||
| 806 | /* XXX - consider blinding. */ | ||
| 807 | |||
| 808 | if ((cardinality = BN_CTX_get(ctx)) == NULL) | ||
| 809 | goto err; | ||
| 810 | if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) | ||
| 811 | goto err; | ||
| 812 | |||
| 813 | /* XXX - handle scalar > cardinality and/or negative. */ | ||
| 814 | |||
| 815 | /* Convert scalar into big endian bytes. */ | ||
| 816 | scalar_len = BN_num_bytes(cardinality); | ||
| 817 | if ((scalar_bytes = calloc(1, scalar_len)) == NULL) | ||
| 818 | goto err; | ||
| 819 | if (!BN_bn2binpad(scalar, scalar_bytes, scalar_len)) | ||
| 820 | goto err; | ||
| 821 | |||
| 822 | /* Compute multiples of point. */ | ||
| 823 | if ((multiples[0] = EC_POINT_dup(point, group)) == NULL) | ||
| 824 | goto err; | ||
| 825 | for (i = 1; i < 15; i += 2) { | ||
| 826 | if ((multiples[i] = EC_POINT_new(group)) == NULL) | ||
| 827 | goto err; | ||
| 828 | if (!EC_POINT_dbl(group, multiples[i], multiples[i / 2], ctx)) | ||
| 829 | goto err; | ||
| 830 | if ((multiples[i + 1] = EC_POINT_new(group)) == NULL) | ||
| 831 | goto err; | ||
| 832 | if (!EC_POINT_add(group, multiples[i + 1], multiples[i], point, ctx)) | ||
| 833 | goto err; | ||
| 834 | } | ||
| 793 | 835 | ||
| 794 | if ((rr = EC_POINT_new(group)) == NULL) | 836 | if ((rr = EC_POINT_new(group)) == NULL) | 
| 795 | goto err; | 837 | goto err; | 
| 838 | if ((t = EC_POINT_new(group)) == NULL) | ||
| 839 | goto err; | ||
| 796 | 840 | ||
| 797 | bits = BN_num_bits(scalar); | 841 | if (!EC_POINT_set_to_infinity(group, rr)) | 
| 842 | goto err; | ||
| 798 | 843 | ||
| 799 | EC_POINT_copy(rr, point); | 844 | for (i = 0; i < scalar_len; i++) { | 
| 845 | if (i != 0) { | ||
| 846 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | ||
| 847 | goto err; | ||
| 848 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | ||
| 849 | goto err; | ||
| 850 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | ||
| 851 | goto err; | ||
| 852 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | ||
| 853 | goto err; | ||
| 854 | } | ||
| 855 | |||
| 856 | if (!EC_POINT_set_to_infinity(group, t)) | ||
| 857 | goto err; | ||
| 858 | |||
| 859 | wv = scalar_bytes[i] >> 4; | ||
| 860 | for (j = 1; j < 16; j++) { | ||
| 861 | conditional = crypto_ct_eq_u8(j, wv); | ||
| 862 | ec_point_select(group, t, t, multiples[j - 1], conditional); | ||
| 863 | } | ||
| 864 | if (!EC_POINT_add(group, rr, rr, t, ctx)) | ||
| 865 | goto err; | ||
| 800 | 866 | ||
| 801 | for (i = bits - 2; i >= 0; i--) { | ||
| 802 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | 867 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | 
| 803 | goto err; | 868 | goto err; | 
| 804 | if (BN_is_bit_set(scalar, i)) { | 869 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | 
| 805 | if (!EC_POINT_add(group, rr, rr, point, ctx)) | 870 | goto err; | 
| 806 | goto err; | 871 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | 
| 872 | goto err; | ||
| 873 | if (!EC_POINT_dbl(group, rr, rr, ctx)) | ||
| 874 | goto err; | ||
| 875 | |||
| 876 | if (!EC_POINT_set_to_infinity(group, t)) | ||
| 877 | goto err; | ||
| 878 | |||
| 879 | wv = scalar_bytes[i] & 0xf; | ||
| 880 | for (j = 1; j < 16; j++) { | ||
| 881 | conditional = crypto_ct_eq_u8(j, wv); | ||
| 882 | ec_point_select(group, t, t, multiples[j - 1], conditional); | ||
| 807 | } | 883 | } | 
| 884 | if (!EC_POINT_add(group, rr, rr, t, ctx)) | ||
| 885 | goto err; | ||
| 808 | } | 886 | } | 
| 809 | 887 | ||
| 810 | EC_POINT_copy(r, rr); | 888 | if (!EC_POINT_copy(r, rr)) | 
| 889 | goto err; | ||
| 811 | 890 | ||
| 812 | ret = 1; | 891 | ret = 1; | 
| 813 | 892 | ||
| 814 | err: | 893 | err: | 
| 894 | for (i = 0; i < 15; i++) | ||
| 895 | EC_POINT_free(multiples[i]); | ||
| 896 | |||
| 815 | EC_POINT_free(rr); | 897 | EC_POINT_free(rr); | 
| 898 | EC_POINT_free(t); | ||
| 899 | |||
| 900 | freezero(scalar_bytes, scalar_len); | ||
| 901 | |||
| 902 | BN_CTX_end(ctx); | ||
| 816 | 903 | ||
| 817 | return ret; | 904 | return ret; | 
| 818 | } | 905 | } | 
