summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec/ec_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec/ec_lib.c')
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c63
1 files changed, 44 insertions, 19 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 7982d23f06..30b2cf95b8 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.123 2025/03/24 13:07:04 jsing Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.131 2025/12/26 18:49:13 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 */
@@ -68,12 +68,12 @@
68 68
69#include <openssl/bn.h> 69#include <openssl/bn.h>
70#include <openssl/ec.h> 70#include <openssl/ec.h>
71#include <openssl/err.h>
72#include <openssl/objects.h> 71#include <openssl/objects.h>
73#include <openssl/opensslv.h> 72#include <openssl/opensslv.h>
74 73
75#include "bn_local.h" 74#include "bn_local.h"
76#include "ec_local.h" 75#include "ec_local.h"
76#include "err_local.h"
77 77
78EC_GROUP * 78EC_GROUP *
79EC_GROUP_new(const EC_METHOD *meth) 79EC_GROUP_new(const EC_METHOD *meth)
@@ -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) {
@@ -788,6 +792,16 @@ EC_GROUP_cmp(const EC_GROUP *group1, const EC_GROUP *group2, BN_CTX *ctx_in)
788} 792}
789LCRYPTO_ALIAS(EC_GROUP_cmp); 793LCRYPTO_ALIAS(EC_GROUP_cmp);
790 794
795int
796ec_group_and_point_compatible(const EC_GROUP *group, const EC_POINT *point)
797{
798 if (group->meth != point->meth)
799 return 0;
800 if (group->nid == NID_undef || point->nid == NID_undef)
801 return 1;
802 return group->nid == point->nid;
803}
804
791EC_POINT * 805EC_POINT *
792EC_POINT_new(const EC_GROUP *group) 806EC_POINT_new(const EC_GROUP *group)
793{ 807{
@@ -811,6 +825,7 @@ EC_POINT_new(const EC_GROUP *group)
811 goto err; 825 goto err;
812 826
813 point->meth = group->meth; 827 point->meth = group->meth;
828 point->nid = group->nid;
814 829
815 return point; 830 return point;
816 831
@@ -852,6 +867,8 @@ EC_POINT_copy(EC_POINT *dst, const EC_POINT *src)
852 if (dst == src) 867 if (dst == src)
853 return 1; 868 return 1;
854 869
870 dst->nid = src->nid;
871
855 if (!bn_copy(dst->X, src->X)) 872 if (!bn_copy(dst->X, src->X))
856 return 0; 873 return 0;
857 if (!bn_copy(dst->Y, src->Y)) 874 if (!bn_copy(dst->Y, src->Y))
@@ -860,6 +877,10 @@ EC_POINT_copy(EC_POINT *dst, const EC_POINT *src)
860 return 0; 877 return 0;
861 dst->Z_is_one = src->Z_is_one; 878 dst->Z_is_one = src->Z_is_one;
862 879
880 memcpy(&dst->fe_x, &src->fe_x, sizeof(dst->fe_x));
881 memcpy(&dst->fe_y, &src->fe_y, sizeof(dst->fe_y));
882 memcpy(&dst->fe_z, &src->fe_z, sizeof(dst->fe_z));
883
863 return 1; 884 return 1;
864} 885}
865LCRYPTO_ALIAS(EC_POINT_copy); 886LCRYPTO_ALIAS(EC_POINT_copy);
@@ -890,15 +911,11 @@ LCRYPTO_ALIAS(EC_POINT_dup);
890int 911int
891EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 912EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
892{ 913{
893 if (group->meth != point->meth) { 914 if (!ec_group_and_point_compatible(group, point)) {
894 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 915 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
895 return 0; 916 return 0;
896 } 917 }
897 918 return group->meth->point_set_to_infinity(group, point);
898 BN_zero(point->Z);
899 point->Z_is_one = 0;
900
901 return 1;
902} 919}
903LCRYPTO_ALIAS(EC_POINT_set_to_infinity); 920LCRYPTO_ALIAS(EC_POINT_set_to_infinity);
904 921
@@ -918,7 +935,7 @@ EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
918 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 935 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
919 goto err; 936 goto err;
920 } 937 }
921 if (group->meth != point->meth) { 938 if (!ec_group_and_point_compatible(group, point)) {
922 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 939 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
923 goto err; 940 goto err;
924 } 941 }
@@ -969,7 +986,7 @@ EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
969 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 986 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
970 goto err; 987 goto err;
971 } 988 }
972 if (group->meth != point->meth) { 989 if (!ec_group_and_point_compatible(group, point)) {
973 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 990 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
974 goto err; 991 goto err;
975 } 992 }
@@ -1119,8 +1136,9 @@ EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1119 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1136 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1120 goto err; 1137 goto err;
1121 } 1138 }
1122 if (group->meth != r->meth || group->meth != a->meth || 1139 if (!ec_group_and_point_compatible(group, r) ||
1123 group->meth != b->meth) { 1140 !ec_group_and_point_compatible(group, a) ||
1141 !ec_group_and_point_compatible(group, b)) {
1124 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1142 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1125 goto err; 1143 goto err;
1126 } 1144 }
@@ -1150,7 +1168,8 @@ EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1150 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1168 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1151 goto err; 1169 goto err;
1152 } 1170 }
1153 if (group->meth != r->meth || r->meth != a->meth) { 1171 if (!ec_group_and_point_compatible(group, r) ||
1172 !ec_group_and_point_compatible(group, a)) {
1154 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1173 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1155 goto err; 1174 goto err;
1156 } 1175 }
@@ -1179,7 +1198,7 @@ EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx_in)
1179 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1198 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1180 goto err; 1199 goto err;
1181 } 1200 }
1182 if (group->meth != a->meth) { 1201 if (!ec_group_and_point_compatible(group, a)) {
1183 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1202 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1184 goto err; 1203 goto err;
1185 } 1204 }
@@ -1196,12 +1215,11 @@ LCRYPTO_ALIAS(EC_POINT_invert);
1196int 1215int
1197EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 1216EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1198{ 1217{
1199 if (group->meth != point->meth) { 1218 if (!ec_group_and_point_compatible(group, point)) {
1200 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1219 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1201 return 0; 1220 return 0;
1202 } 1221 }
1203 1222 return group->meth->point_is_at_infinity(group, point);
1204 return BN_is_zero(point->Z);
1205} 1223}
1206LCRYPTO_ALIAS(EC_POINT_is_at_infinity); 1224LCRYPTO_ALIAS(EC_POINT_is_at_infinity);
1207 1225
@@ -1221,7 +1239,7 @@ EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
1221 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1239 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1222 goto err; 1240 goto err;
1223 } 1241 }
1224 if (group->meth != point->meth) { 1242 if (!ec_group_and_point_compatible(group, point)) {
1225 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1243 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1226 goto err; 1244 goto err;
1227 } 1245 }
@@ -1251,7 +1269,8 @@ EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
1251 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1269 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1252 goto err; 1270 goto err;
1253 } 1271 }
1254 if (group->meth != a->meth || a->meth != b->meth) { 1272 if (!ec_group_and_point_compatible(group, a) ||
1273 !ec_group_and_point_compatible(group, b)) {
1255 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1274 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1256 goto err; 1275 goto err;
1257 } 1276 }
@@ -1324,6 +1343,12 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1324 goto err; 1343 goto err;
1325 } 1344 }
1326 1345
1346 if (!ec_group_and_point_compatible(group, r) ||
1347 (point != NULL && !ec_group_and_point_compatible(group, point))) {
1348 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1349 goto err;
1350 }
1351
1327 if (g_scalar != NULL && point == NULL && p_scalar == NULL) { 1352 if (g_scalar != NULL && point == NULL && p_scalar == NULL) {
1328 /* 1353 /*
1329 * In this case we want to compute g_scalar * GeneratorPoint: 1354 * In this case we want to compute g_scalar * GeneratorPoint: