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.c452
1 files changed, 338 insertions, 114 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 38ddd7af9f..bc472b73b7 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.52 2023/03/27 10:25:02 tb Exp $ */ 1/* $OpenBSD: ec_lib.c,v 1.53 2023/04/11 18:58:20 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 */
@@ -487,24 +487,52 @@ EC_GROUP_get_seed_len(const EC_GROUP *group)
487 487
488int 488int
489EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, 489EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
490 const BIGNUM *b, BN_CTX *ctx) 490 const BIGNUM *b, BN_CTX *ctx_in)
491{ 491{
492 BN_CTX *ctx;
493 int ret = 0;
494
495 if ((ctx = ctx_in) == NULL)
496 ctx = BN_CTX_new();
497 if (ctx == NULL)
498 goto err;
499
492 if (group->meth->group_set_curve == NULL) { 500 if (group->meth->group_set_curve == NULL) {
493 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 501 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
494 return 0; 502 goto err;
495 } 503 }
496 return group->meth->group_set_curve(group, p, a, b, ctx); 504 ret = group->meth->group_set_curve(group, p, a, b, ctx);
505
506 err:
507 if (ctx != ctx_in)
508 BN_CTX_free(ctx);
509
510 return ret;
497} 511}
498 512
499int 513int
500EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, 514EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
501 BN_CTX *ctx) 515 BN_CTX *ctx_in)
502{ 516{
517 BN_CTX *ctx;
518 int ret = 0;
519
520 if ((ctx = ctx_in) == NULL)
521 ctx = BN_CTX_new();
522 if (ctx == NULL)
523 goto err;
524
503 if (group->meth->group_get_curve == NULL) { 525 if (group->meth->group_get_curve == NULL) {
504 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 526 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
505 return 0; 527 return 0;
506 } 528 }
507 return group->meth->group_get_curve(group, p, a, b, ctx); 529 ret = group->meth->group_get_curve(group, p, a, b, ctx);
530
531 err:
532 if (ctx != ctx_in)
533 BN_CTX_free(ctx);
534
535 return ret;
508} 536}
509 537
510int 538int
@@ -549,13 +577,27 @@ EC_GROUP_get_degree(const EC_GROUP *group)
549 577
550 578
551int 579int
552EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 580EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx_in)
553{ 581{
582 BN_CTX *ctx;
583 int ret = 0;
584
585 if ((ctx = ctx_in) == NULL)
586 ctx = BN_CTX_new();
587 if (ctx == NULL)
588 goto err;
589
554 if (group->meth->group_check_discriminant == 0) { 590 if (group->meth->group_check_discriminant == 0) {
555 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 591 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
556 return 0; 592 return 0;
557 } 593 }
558 return group->meth->group_check_discriminant(group, ctx); 594 return group->meth->group_check_discriminant(group, ctx);
595
596 err:
597 if (ctx != ctx_in)
598 BN_CTX_free(ctx);
599
600 return ret;
559} 601}
560 602
561 603
@@ -803,9 +845,6 @@ EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data)
803 *ex_data = NULL; 845 *ex_data = NULL;
804} 846}
805 847
806
807/* functions for EC_POINT objects */
808
809EC_POINT * 848EC_POINT *
810EC_POINT_new(const EC_GROUP *group) 849EC_POINT_new(const EC_GROUP *group)
811{ 850{
@@ -867,7 +906,6 @@ EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
867 return dest->meth->point_copy(dest, src); 906 return dest->meth->point_copy(dest, src);
868} 907}
869 908
870
871EC_POINT * 909EC_POINT *
872EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) 910EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
873{ 911{
@@ -888,18 +926,16 @@ EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
888 return t; 926 return t;
889} 927}
890 928
891
892const EC_METHOD * 929const EC_METHOD *
893EC_POINT_method_of(const EC_POINT *point) 930EC_POINT_method_of(const EC_POINT *point)
894{ 931{
895 return point->meth; 932 return point->meth;
896} 933}
897 934
898
899int 935int
900EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 936EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
901{ 937{
902 if (group->meth->point_set_to_infinity == 0) { 938 if (group->meth->point_set_to_infinity == NULL) {
903 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 939 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
904 return 0; 940 return 0;
905 } 941 }
@@ -912,40 +948,70 @@ EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
912 948
913int 949int
914EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point, 950EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point,
915 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) 951 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx_in)
916{ 952{
953 BN_CTX *ctx;
954 int ret = 0;
955
956 if ((ctx = ctx_in) == NULL)
957 ctx = BN_CTX_new();
958 if (ctx == NULL)
959 goto err;
960
917 if (group->meth->point_set_Jprojective_coordinates == NULL) { 961 if (group->meth->point_set_Jprojective_coordinates == NULL) {
918 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 962 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
919 return 0; 963 goto err;
920 } 964 }
921 if (group->meth != point->meth) { 965 if (group->meth != point->meth) {
922 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 966 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
923 return 0; 967 goto err;
924 } 968 }
925 if (!group->meth->point_set_Jprojective_coordinates(group, point, 969 if (!group->meth->point_set_Jprojective_coordinates(group, point,
926 x, y, z, ctx)) 970 x, y, z, ctx))
927 return 0; 971 goto err;
972
928 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 973 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
929 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 974 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
930 return 0; 975 goto err;
931 } 976 }
932 return 1; 977
978 ret = 1;
979
980 err:
981 if (ctx != ctx_in)
982 BN_CTX_free(ctx);
983
984 return ret;
933} 985}
934 986
935int 987int
936EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group, 988EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group,
937 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) 989 const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx_in)
938{ 990{
991 BN_CTX *ctx;
992 int ret = 0;
993
994 if ((ctx = ctx_in) == NULL)
995 ctx = BN_CTX_new();
996 if (ctx == NULL)
997 goto err;
998
939 if (group->meth->point_get_Jprojective_coordinates == NULL) { 999 if (group->meth->point_get_Jprojective_coordinates == NULL) {
940 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1000 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
941 return 0; 1001 goto err;
942 } 1002 }
943 if (group->meth != point->meth) { 1003 if (group->meth != point->meth) {
944 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1004 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
945 return 0; 1005 goto err;
946 } 1006 }
947 return group->meth->point_get_Jprojective_coordinates(group, point, 1007 ret = group->meth->point_get_Jprojective_coordinates(group, point,
948 x, y, z, ctx); 1008 x, y, z, ctx);
1009
1010 err:
1011 if (ctx != ctx_in)
1012 BN_CTX_free(ctx);
1013
1014 return ret;
949} 1015}
950 1016
951int 1017int
@@ -964,23 +1030,39 @@ EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
964 1030
965int 1031int
966EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 1032EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
967 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 1033 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx_in)
968{ 1034{
1035 BN_CTX *ctx;
1036 int ret = 0;
1037
1038 if ((ctx = ctx_in) == NULL)
1039 ctx = BN_CTX_new();
1040 if (ctx == NULL)
1041 goto err;
1042
969 if (group->meth->point_set_affine_coordinates == NULL) { 1043 if (group->meth->point_set_affine_coordinates == NULL) {
970 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1044 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
971 return 0; 1045 goto err;
972 } 1046 }
973 if (group->meth != point->meth) { 1047 if (group->meth != point->meth) {
974 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1048 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
975 return 0; 1049 goto err;
976 } 1050 }
977 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx)) 1051 if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
978 return 0; 1052 goto err;
1053
979 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { 1054 if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
980 ECerror(EC_R_POINT_IS_NOT_ON_CURVE); 1055 ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
981 return 0; 1056 goto err;
982 } 1057 }
983 return 1; 1058
1059 ret = 1;
1060
1061 err:
1062 if (ctx != ctx_in)
1063 BN_CTX_free(ctx);
1064
1065 return ret;
984} 1066}
985 1067
986int 1068int
@@ -1001,8 +1083,16 @@ EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
1001 1083
1002int 1084int
1003EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, 1085EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
1004 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 1086 BIGNUM *x, BIGNUM *y, BN_CTX *ctx_in)
1005{ 1087{
1088 BN_CTX *ctx;
1089 int ret = 0;
1090
1091 if ((ctx = ctx_in) == NULL)
1092 ctx = BN_CTX_new();
1093 if (ctx == NULL)
1094 goto err;
1095
1006 if (group->meth->point_get_affine_coordinates == NULL) { 1096 if (group->meth->point_get_affine_coordinates == NULL) {
1007 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1097 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1008 return 0; 1098 return 0;
@@ -1011,7 +1101,13 @@ EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
1011 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1101 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1012 return 0; 1102 return 0;
1013 } 1103 }
1014 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 1104 ret = group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
1105
1106 err:
1107 if (ctx != ctx_in)
1108 BN_CTX_free(ctx);
1109
1110 return ret;
1015} 1111}
1016 1112
1017int 1113int
@@ -1032,38 +1128,74 @@ EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *poin
1032 1128
1033int 1129int
1034EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 1130EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1035 const EC_POINT *b, BN_CTX *ctx) 1131 const EC_POINT *b, BN_CTX *ctx_in)
1036{ 1132{
1037 if (group->meth->add == 0) { 1133 BN_CTX *ctx;
1134 int ret = 0;
1135
1136 if ((ctx = ctx_in) == NULL)
1137 ctx = BN_CTX_new();
1138 if (ctx == NULL)
1139 goto err;
1140
1141 if (group->meth->add == NULL) {
1038 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1142 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1039 return 0; 1143 goto err;
1040 } 1144 }
1041 if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) { 1145 if (group->meth != r->meth || group->meth != a->meth ||
1146 group->meth != b->meth) {
1042 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1147 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1043 return 0; 1148 goto err;
1044 } 1149 }
1045 return group->meth->add(group, r, a, b, ctx); 1150 ret = group->meth->add(group, r, a, b, ctx);
1046}
1047 1151
1152 err:
1153 if (ctx != ctx_in)
1154 BN_CTX_free(ctx);
1155
1156 return ret;
1157}
1048 1158
1049int 1159int
1050EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) 1160EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
1161 BN_CTX *ctx_in)
1051{ 1162{
1052 if (group->meth->dbl == 0) { 1163 BN_CTX *ctx;
1164 int ret = 0;
1165
1166 if ((ctx = ctx_in) == NULL)
1167 ctx = BN_CTX_new();
1168 if (ctx == NULL)
1169 goto err;
1170
1171 if (group->meth->dbl == NULL) {
1053 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1172 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1054 return 0; 1173 return 0;
1055 } 1174 }
1056 if ((group->meth != r->meth) || (r->meth != a->meth)) { 1175 if (group->meth != r->meth || r->meth != a->meth) {
1057 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1176 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1058 return 0; 1177 return 0;
1059 } 1178 }
1060 return group->meth->dbl(group, r, a, ctx); 1179 ret = group->meth->dbl(group, r, a, ctx);
1061}
1062 1180
1181 err:
1182 if (ctx != ctx_in)
1183 BN_CTX_free(ctx);
1184
1185 return ret;
1186}
1063 1187
1064int 1188int
1065EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) 1189EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx_in)
1066{ 1190{
1191 BN_CTX *ctx;
1192 int ret = 0;
1193
1194 if ((ctx = ctx_in) == NULL)
1195 ctx = BN_CTX_new();
1196 if (ctx == NULL)
1197 goto err;
1198
1067 if (group->meth->invert == 0) { 1199 if (group->meth->invert == 0) {
1068 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1200 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1069 return 0; 1201 return 0;
@@ -1073,13 +1205,18 @@ EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
1073 return 0; 1205 return 0;
1074 } 1206 }
1075 return group->meth->invert(group, a, ctx); 1207 return group->meth->invert(group, a, ctx);
1076}
1077 1208
1209 err:
1210 if (ctx != ctx_in)
1211 BN_CTX_free(ctx);
1212
1213 return ret;
1214}
1078 1215
1079int 1216int
1080EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 1217EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1081{ 1218{
1082 if (group->meth->is_at_infinity == 0) { 1219 if (group->meth->is_at_infinity == NULL) {
1083 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1220 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1084 return 0; 1221 return 0;
1085 } 1222 }
@@ -1090,114 +1227,184 @@ EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1090 return group->meth->is_at_infinity(group, point); 1227 return group->meth->is_at_infinity(group, point);
1091} 1228}
1092 1229
1093
1094int 1230int
1095EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) 1231EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
1232 BN_CTX *ctx_in)
1096{ 1233{
1097 if (group->meth->is_on_curve == 0) { 1234 BN_CTX *ctx;
1235 int ret = 0;
1236
1237 if ((ctx = ctx_in) == NULL)
1238 ctx = BN_CTX_new();
1239 if (ctx == NULL)
1240 goto err;
1241
1242 if (group->meth->is_on_curve == NULL) {
1098 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1243 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1099 return 0; 1244 goto err;
1100 } 1245 }
1101 if (group->meth != point->meth) { 1246 if (group->meth != point->meth) {
1102 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1247 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1103 return 0; 1248 goto err;
1104 } 1249 }
1105 return group->meth->is_on_curve(group, point, ctx); 1250 ret = group->meth->is_on_curve(group, point, ctx);
1106} 1251
1252 err:
1253 if (ctx != ctx_in)
1254 BN_CTX_free(ctx);
1107 1255
1256 return ret;
1257}
1108 1258
1109int 1259int
1110EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 1260EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
1111 BN_CTX *ctx) 1261 BN_CTX *ctx_in)
1112{ 1262{
1113 if (group->meth->point_cmp == 0) { 1263 BN_CTX *ctx;
1264 int ret = -1;
1265
1266 if ((ctx = ctx_in) == NULL)
1267 ctx = BN_CTX_new();
1268 if (ctx == NULL)
1269 goto err;
1270
1271 if (group->meth->point_cmp == NULL) {
1114 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1272 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1115 return -1; 1273 goto err;
1116 } 1274 }
1117 if ((group->meth != a->meth) || (a->meth != b->meth)) { 1275 if (group->meth != a->meth || a->meth != b->meth) {
1118 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1276 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1119 return -1; 1277 goto err;
1120 } 1278 }
1121 return group->meth->point_cmp(group, a, b, ctx); 1279 ret = group->meth->point_cmp(group, a, b, ctx);
1122} 1280
1281 err:
1282 if (ctx != ctx_in)
1283 BN_CTX_free(ctx);
1123 1284
1285 return ret;
1286}
1124 1287
1125int 1288int
1126EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 1289EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx_in)
1127{ 1290{
1128 if (group->meth->make_affine == 0) { 1291 BN_CTX *ctx;
1292 int ret = 0;
1293
1294 if ((ctx = ctx_in) == NULL)
1295 ctx = BN_CTX_new();
1296 if (ctx == NULL)
1297 goto err;
1298
1299 if (group->meth->make_affine == NULL) {
1129 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1300 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1130 return 0; 1301 goto err;
1131 } 1302 }
1132 if (group->meth != point->meth) { 1303 if (group->meth != point->meth) {
1133 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1304 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1134 return 0; 1305 goto err;
1135 } 1306 }
1136 return group->meth->make_affine(group, point, ctx); 1307 ret = group->meth->make_affine(group, point, ctx);
1137}
1138 1308
1309 err:
1310 if (ctx != ctx_in)
1311 BN_CTX_free(ctx);
1312
1313 return ret;
1314}
1139 1315
1140int 1316int
1141EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], 1317EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1142 BN_CTX *ctx) 1318 BN_CTX *ctx_in)
1143{ 1319{
1320 BN_CTX *ctx;
1144 size_t i; 1321 size_t i;
1322 int ret = 0;
1145 1323
1146 if (group->meth->points_make_affine == 0) { 1324 if ((ctx = ctx_in) == NULL)
1325 ctx = BN_CTX_new();
1326 if (ctx == NULL)
1327 goto err;
1328
1329 if (group->meth->points_make_affine == NULL) {
1147 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1330 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1148 return 0; 1331 goto err;
1149 } 1332 }
1150 for (i = 0; i < num; i++) { 1333 for (i = 0; i < num; i++) {
1151 if (group->meth != points[i]->meth) { 1334 if (group->meth != points[i]->meth) {
1152 ECerror(EC_R_INCOMPATIBLE_OBJECTS); 1335 ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1153 return 0; 1336 goto err;
1154 } 1337 }
1155 } 1338 }
1156 return group->meth->points_make_affine(group, num, points, ctx); 1339 ret = group->meth->points_make_affine(group, num, points, ctx);
1157}
1158 1340
1341 err:
1342 if (ctx != ctx_in)
1343 BN_CTX_free(ctx);
1344
1345 return ret;
1346}
1159 1347
1160/* Functions for point multiplication */
1161int 1348int
1162EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 1349EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1163 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) 1350 size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
1351 BN_CTX *ctx_in)
1164{ 1352{
1165 /* 1353 BN_CTX *ctx;
1166 * The function pointers must be set, and only support num == 0 and 1354 int ret = 0;
1167 * num == 1. 1355
1168 */ 1356 if ((ctx = ctx_in) == NULL)
1357 ctx = BN_CTX_new();
1358 if (ctx == NULL)
1359 goto err;
1360
1361 /* Only num == 0 and num == 1 is supported. */
1169 if (group->meth->mul_generator_ct == NULL || 1362 if (group->meth->mul_generator_ct == NULL ||
1170 group->meth->mul_single_ct == NULL || 1363 group->meth->mul_single_ct == NULL ||
1171 group->meth->mul_double_nonct == NULL || 1364 group->meth->mul_double_nonct == NULL ||
1172 num > 1) { 1365 num > 1) {
1173 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1366 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1174 return 0; 1367 goto err;
1175 } 1368 }
1176 1369
1177 /* Either bP or aG + bP, this is sane. */ 1370 if (num == 1 && points != NULL && scalars != NULL) {
1178 if (num == 1 && points != NULL && scalars != NULL) 1371 /* Either bP or aG + bP, this is sane. */
1179 return EC_POINT_mul(group, r, scalar, points[0], scalars[0], 1372 ret = EC_POINT_mul(group, r, scalar, points[0], scalars[0], ctx);
1180 ctx); 1373 } else if (scalar != NULL && points == NULL && scalars == NULL) {
1374 /* aG, this is sane */
1375 ret = EC_POINT_mul(group, r, scalar, NULL, NULL, ctx);
1376 } else {
1377 /* anything else is an error */
1378 ECerror(ERR_R_EC_LIB);
1379 goto err;
1380 }
1181 1381
1182 /* aG, this is sane */ 1382 err:
1183 if (scalar != NULL && points == NULL && scalars == NULL) 1383 if (ctx != ctx_in)
1184 return EC_POINT_mul(group, r, scalar, NULL, NULL, ctx); 1384 BN_CTX_free(ctx);
1185 1385
1186 /* anything else is an error */ 1386 return ret;
1187 ECerror(ERR_R_EC_LIB);
1188 return 0;
1189} 1387}
1190 1388
1191int 1389int
1192EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 1390EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1193 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) 1391 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx_in)
1194{ 1392{
1393 BN_CTX *ctx;
1394 int ret = 0;
1395
1396 if ((ctx = ctx_in) == NULL)
1397 ctx = BN_CTX_new();
1398 if (ctx == NULL)
1399 goto err;
1400
1195 if (group->meth->mul_generator_ct == NULL || 1401 if (group->meth->mul_generator_ct == NULL ||
1196 group->meth->mul_single_ct == NULL || 1402 group->meth->mul_single_ct == NULL ||
1197 group->meth->mul_double_nonct == NULL) { 1403 group->meth->mul_double_nonct == NULL) {
1198 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 1404 ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1199 return 0; 1405 goto err;
1200 } 1406 }
1407
1201 if (g_scalar != NULL && point == NULL && p_scalar == NULL) { 1408 if (g_scalar != NULL && point == NULL && p_scalar == NULL) {
1202 /* 1409 /*
1203 * In this case we want to compute g_scalar * GeneratorPoint: 1410 * In this case we want to compute g_scalar * GeneratorPoint:
@@ -1207,52 +1414,69 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1207 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually 1414 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually
1208 * set and we always call the constant time version. 1415 * set and we always call the constant time version.
1209 */ 1416 */
1210 return group->meth->mul_generator_ct(group, r, g_scalar, ctx); 1417 ret = group->meth->mul_generator_ct(group, r, g_scalar, ctx);
1211 } 1418 } else if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
1212 if (g_scalar == NULL && point != NULL && p_scalar != NULL) { 1419 /*
1213 /* In this case we want to compute p_scalar * GenericPoint: 1420 * In this case we want to compute p_scalar * GenericPoint:
1214 * this codepath is reached most prominently by the second half 1421 * this codepath is reached most prominently by the second half
1215 * of ECDH, where the secret scalar is multiplied by the peer's 1422 * of ECDH, where the secret scalar is multiplied by the peer's
1216 * public point. To protect the secret scalar, we ignore if 1423 * public point. To protect the secret scalar, we ignore if
1217 * BN_FLG_CONSTTIME is actually set and we always call the 1424 * BN_FLG_CONSTTIME is actually set and we always call the
1218 * constant time version. 1425 * constant time version.
1219 */ 1426 */
1220 return group->meth->mul_single_ct(group, r, p_scalar, point, 1427 ret = group->meth->mul_single_ct(group, r, p_scalar, point, ctx);
1221 ctx); 1428 } else if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
1222 }
1223 if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
1224 /* 1429 /*
1225 * In this case we want to compute 1430 * In this case we want to compute
1226 * g_scalar * GeneratorPoint + p_scalar * GenericPoint: 1431 * g_scalar * GeneratorPoint + p_scalar * GenericPoint:
1227 * this codepath is reached most prominently by ECDSA signature 1432 * this codepath is reached most prominently by ECDSA signature
1228 * verification. So we call the non-ct version. 1433 * verification. So we call the non-ct version.
1229 */ 1434 */
1230 return group->meth->mul_double_nonct(group, r, g_scalar, 1435 ret = group->meth->mul_double_nonct(group, r, g_scalar,
1231 p_scalar, point, ctx); 1436 p_scalar, point, ctx);
1437 } else {
1438 /* Anything else is an error. */
1439 ECerror(ERR_R_EC_LIB);
1440 goto err;
1232 } 1441 }
1233 1442
1234 /* Anything else is an error. */ 1443 err:
1235 ECerror(ERR_R_EC_LIB); 1444 if (ctx != ctx_in)
1236 return 0; 1445 BN_CTX_free(ctx);
1446
1447 return ret;
1237} 1448}
1238 1449
1239int 1450int
1240EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 1451EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx_in)
1241{ 1452{
1242 if (group->meth->precompute_mult != 0) 1453 BN_CTX *ctx;
1243 return group->meth->precompute_mult(group, ctx); 1454 int ret = 0;
1244 else 1455
1245 return 1; /* nothing to do, so report success */ 1456 if (group->meth->precompute_mult == NULL)
1457 return 1;
1458
1459 if ((ctx = ctx_in) == NULL)
1460 ctx = BN_CTX_new();
1461 if (ctx == NULL)
1462 goto err;
1463
1464 ret = group->meth->precompute_mult(group, ctx);
1465
1466 err:
1467 if (ctx != ctx_in)
1468 BN_CTX_free(ctx);
1469
1470 return ret;
1246} 1471}
1247 1472
1248int 1473int
1249EC_GROUP_have_precompute_mult(const EC_GROUP *group) 1474EC_GROUP_have_precompute_mult(const EC_GROUP *group)
1250{ 1475{
1251 if (group->meth->have_precompute_mult != 0) 1476 if (group->meth->have_precompute_mult == NULL)
1252 return group->meth->have_precompute_mult(group); 1477 return 0;
1253 else 1478
1254 return 0; /* cannot tell whether precomputation has 1479 return group->meth->have_precompute_mult(group);
1255 * been performed */
1256} 1480}
1257 1481
1258int 1482int