summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/ec/ecp_hp_methods.c119
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
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)
@@ -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
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
784static int 789static int
785ec_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,
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}