summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/ec/ec_field.c17
-rw-r--r--src/lib/libcrypto/ec/ec_internal.h4
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c10
-rw-r--r--src/lib/libcrypto/ec/ec_local.h3
-rw-r--r--src/lib/libcrypto/ec/ecp_hp_methods.c123
5 files changed, 132 insertions, 25 deletions
diff --git a/src/lib/libcrypto/ec/ec_field.c b/src/lib/libcrypto/ec/ec_field.c
index ec1c7d11e0..6576526e77 100644
--- a/src/lib/libcrypto/ec/ec_field.c
+++ b/src/lib/libcrypto/ec/ec_field.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_field.c,v 1.1 2025/05/25 05:12:05 jsing Exp $ */ 1/* $OpenBSD: ec_field.c,v 1.3 2025/08/02 16:20:00 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -131,6 +131,19 @@ ec_field_element_copy(EC_FIELD_ELEMENT *dst, const EC_FIELD_ELEMENT *src)
131 memcpy(dst, src, sizeof(EC_FIELD_ELEMENT)); 131 memcpy(dst, src, sizeof(EC_FIELD_ELEMENT));
132} 132}
133 133
134void
135ec_field_element_select(const EC_FIELD_MODULUS *fm, EC_FIELD_ELEMENT *r,
136 const EC_FIELD_ELEMENT *a, const EC_FIELD_ELEMENT *b, int conditional)
137{
138 BN_ULONG mask;
139 int i;
140
141 mask = bn_ct_eq_zero_mask(conditional);
142
143 for (i = 0; i < fm->n; i++)
144 r->w[i] = (a->w[i] & mask) | (b->w[i] & ~mask);
145}
146
134int 147int
135ec_field_element_equal(const EC_FIELD_MODULUS *fm, const EC_FIELD_ELEMENT *a, 148ec_field_element_equal(const EC_FIELD_MODULUS *fm, const EC_FIELD_ELEMENT *a,
136 const EC_FIELD_ELEMENT *b) 149 const EC_FIELD_ELEMENT *b)
@@ -185,5 +198,5 @@ ec_field_element_sqr(const EC_FIELD_MODULUS *m, EC_FIELD_ELEMENT *r,
185{ 198{
186 BN_ULONG t[EC_FIELD_ELEMENT_MAX_WORDS * 2 + 2]; 199 BN_ULONG t[EC_FIELD_ELEMENT_MAX_WORDS * 2 + 2];
187 200
188 bn_mod_mul_words(r->w, a->w, a->w, m->m.w, t, m->minv0, m->n); 201 bn_mod_sqr_words(r->w, a->w, m->m.w, t, m->minv0, m->n);
189} 202}
diff --git a/src/lib/libcrypto/ec/ec_internal.h b/src/lib/libcrypto/ec/ec_internal.h
index 29b447e8c9..327d9ea94d 100644
--- a/src/lib/libcrypto/ec/ec_internal.h
+++ b/src/lib/libcrypto/ec/ec_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_internal.h,v 1.1 2025/05/25 05:12:05 jsing Exp $ */ 1/* $OpenBSD: ec_internal.h,v 1.2 2025/08/02 15:44:09 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -46,6 +46,8 @@ int ec_field_element_to_bn(const EC_FIELD_MODULUS *fm, const EC_FIELD_ELEMENT *f
46 BIGNUM *bn, BN_CTX *ctx); 46 BIGNUM *bn, BN_CTX *ctx);
47 47
48void ec_field_element_copy(EC_FIELD_ELEMENT *dst, const EC_FIELD_ELEMENT *src); 48void ec_field_element_copy(EC_FIELD_ELEMENT *dst, const EC_FIELD_ELEMENT *src);
49void ec_field_element_select(const EC_FIELD_MODULUS *fm, EC_FIELD_ELEMENT *r,
50 const EC_FIELD_ELEMENT *a, const EC_FIELD_ELEMENT *b, int conditional);
49 51
50int ec_field_element_equal(const EC_FIELD_MODULUS *fm, const EC_FIELD_ELEMENT *a, 52int ec_field_element_equal(const EC_FIELD_MODULUS *fm, const EC_FIELD_ELEMENT *a,
51 const EC_FIELD_ELEMENT *b); 53 const EC_FIELD_ELEMENT *b);
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 7cc7efe73f..36f42ecc05 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_lib.c,v 1.125 2025/05/24 08:25:58 jsing Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.126 2025/08/02 15:47:27 jsing 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 */
@@ -165,6 +165,10 @@ EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src)
165 165
166 dst->a_is_minus3 = src->a_is_minus3; 166 dst->a_is_minus3 = src->a_is_minus3;
167 167
168 memcpy(&dst->fm, &src->fm, sizeof(src->fm));
169 memcpy(&dst->fe_a, &src->fe_a, sizeof(src->fe_a));
170 memcpy(&dst->fe_b, &src->fe_b, sizeof(src->fe_b));
171
168 BN_MONT_CTX_free(dst->mont_ctx); 172 BN_MONT_CTX_free(dst->mont_ctx);
169 dst->mont_ctx = NULL; 173 dst->mont_ctx = NULL;
170 if (src->mont_ctx != NULL) { 174 if (src->mont_ctx != NULL) {
@@ -860,6 +864,10 @@ EC_POINT_copy(EC_POINT *dst, const EC_POINT *src)
860 return 0; 864 return 0;
861 dst->Z_is_one = src->Z_is_one; 865 dst->Z_is_one = src->Z_is_one;
862 866
867 memcpy(&dst->fe_x, &src->fe_x, sizeof(dst->fe_x));
868 memcpy(&dst->fe_y, &src->fe_y, sizeof(dst->fe_y));
869 memcpy(&dst->fe_z, &src->fe_z, sizeof(dst->fe_z));
870
863 return 1; 871 return 1;
864} 872}
865LCRYPTO_ALIAS(EC_POINT_copy); 873LCRYPTO_ALIAS(EC_POINT_copy);
diff --git a/src/lib/libcrypto/ec/ec_local.h b/src/lib/libcrypto/ec/ec_local.h
index 75a3e25247..eac9e6d26c 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.69 2025/05/25 05:19:26 jsing Exp $ */ 1/* $OpenBSD: ec_local.h,v 1.70 2025/08/03 15:07:57 jsing 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 */
@@ -184,6 +184,7 @@ struct ec_point_st {
184 184
185const EC_METHOD *EC_GFp_simple_method(void); 185const EC_METHOD *EC_GFp_simple_method(void);
186const EC_METHOD *EC_GFp_mont_method(void); 186const EC_METHOD *EC_GFp_mont_method(void);
187const EC_METHOD *EC_GFp_homogeneous_projective_method(void);
187 188
188/* Compute r = scalar1 * point1 + scalar2 * point2 in non-constant time. */ 189/* Compute r = scalar1 * point1 + scalar2 * point2 in non-constant time. */
189int ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar1, 190int ec_wnaf_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar1,
diff --git a/src/lib/libcrypto/ec/ecp_hp_methods.c b/src/lib/libcrypto/ec/ecp_hp_methods.c
index c62334e7c8..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.3 2025/06/01 03:23:33 tb 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
34static int 30static int
35ec_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 31ec_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)
@@ -439,10 +435,6 @@ ec_point_dbl_a1(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *c
439 ec_field_element_add(&group->fm, &b3, &gb, &gb); 435 ec_field_element_add(&group->fm, &b3, &gb, &gb);
440 ec_field_element_add(&group->fm, &b3, &b3, &gb); 436 ec_field_element_add(&group->fm, &b3, &b3, &gb);
441 437
442 /* b3 := 3 * b ; */
443 ec_field_element_add(&group->fm, &b3, &gb, &gb);
444 ec_field_element_add(&group->fm, &b3, &b3, &gb);
445
446 /* t0 := X^2; t1 := Y^2; t2 := Z^2 ; */ 438 /* t0 := X^2; t1 := Y^2; t2 := Z^2 ; */
447 ec_field_element_sqr(&group->fm, &t0, &X1); 439 ec_field_element_sqr(&group->fm, &t0, &X1);
448 ec_field_element_sqr(&group->fm, &t1, &Y1); 440 ec_field_element_sqr(&group->fm, &t1, &Y1);
@@ -785,38 +777,129 @@ ec_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
785} 777}
786#endif 778#endif
787 779
780static void
781ec_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
788static int 789static int
789ec_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, 790ec_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point,
790 BN_CTX *ctx) 791 BN_CTX *ctx)
791{ 792{
792 EC_POINT *rr; 793 BIGNUM *cardinality;
793 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;
794 int ret = 0; 800 int ret = 0;
795 801
796 /* 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 }
797 835
798 if ((rr = EC_POINT_new(group)) == NULL) 836 if ((rr = EC_POINT_new(group)) == NULL)
799 goto err; 837 goto err;
838 if ((t = EC_POINT_new(group)) == NULL)
839 goto err;
800 840
801 bits = BN_num_bits(scalar); 841 if (!EC_POINT_set_to_infinity(group, rr))
842 goto err;
843
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 }
802 855
803 EC_POINT_copy(rr, point); 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;
804 866
805 for (i = bits - 2; i >= 0; i--) {
806 if (!EC_POINT_dbl(group, rr, rr, ctx)) 867 if (!EC_POINT_dbl(group, rr, rr, ctx))
807 goto err; 868 goto err;
808 if (BN_is_bit_set(scalar, i)) { 869 if (!EC_POINT_dbl(group, rr, rr, ctx))
809 if (!EC_POINT_add(group, rr, rr, point, ctx)) 870 goto err;
810 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);
811 } 883 }
884 if (!EC_POINT_add(group, rr, rr, t, ctx))
885 goto err;
812 } 886 }
813 887
814 EC_POINT_copy(r, rr); 888 if (!EC_POINT_copy(r, rr))
889 goto err;
815 890
816 ret = 1; 891 ret = 1;
817 892
818 err: 893 err:
894 for (i = 0; i < 15; i++)
895 EC_POINT_free(multiples[i]);
896
819 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);
820 903
821 return ret; 904 return ret;
822} 905}