diff options
Diffstat (limited to 'src')
-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 | } |