diff options
author | tb <> | 2018-07-16 17:32:39 +0000 |
---|---|---|
committer | tb <> | 2018-07-16 17:32:39 +0000 |
commit | cb198f135c139c2e0ab679576187b5a4c9876304 (patch) | |
tree | b66bb68417b97c5fbb3ce4243eab9a7889ecfb82 /src/lib/libcrypto/ec/ec_lib.c | |
parent | e8aad185bc3296229a54ff70b7d536b3acbf89c4 (diff) | |
download | openbsd-cb198f135c139c2e0ab679576187b5a4c9876304.tar.gz openbsd-cb198f135c139c2e0ab679576187b5a4c9876304.tar.bz2 openbsd-cb198f135c139c2e0ab679576187b5a4c9876304.zip |
Recommit Billy Brumley's ECC constant time patch with a fix for sparc64
from Nicola Tuveri (who spotted the omission of ecp_nist.c from the PR).
discussed with jsing
tested by jsg
Diffstat (limited to 'src/lib/libcrypto/ec/ec_lib.c')
-rw-r--r-- | src/lib/libcrypto/ec/ec_lib.c | 99 |
1 files changed, 68 insertions, 31 deletions
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c index 53d79f232c..7e0ea017f9 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.28 2018/07/15 16:27:39 tb Exp $ */ | 1 | /* $OpenBSD: ec_lib.c,v 1.29 2018/07/16 17:32:39 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 | */ |
@@ -1026,47 +1026,88 @@ EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], | |||
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | 1028 | ||
1029 | /* Functions for point multiplication. | 1029 | /* Functions for point multiplication */ |
1030 | * | ||
1031 | * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c; | ||
1032 | * otherwise we dispatch through methods. | ||
1033 | */ | ||
1034 | |||
1035 | int | 1030 | int |
1036 | EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | 1031 | EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, |
1037 | size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) | 1032 | size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) |
1038 | { | 1033 | { |
1039 | if (group->meth->mul == 0) | 1034 | /* |
1040 | /* use default */ | 1035 | * The function pointers must be set, and only support num == 0 and |
1041 | return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); | 1036 | * num == 1. |
1042 | 1037 | */ | |
1043 | return group->meth->mul(group, r, scalar, num, points, scalars, ctx); | 1038 | if (group->meth->mul_generator_ct == NULL || |
1039 | group->meth->mul_single_ct == NULL || | ||
1040 | group->meth->mul_double_nonct == NULL || | ||
1041 | num > 1) { | ||
1042 | ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
1043 | return 0; | ||
1044 | } | ||
1045 | |||
1046 | /* Either bP or aG + bP, this is sane. */ | ||
1047 | if (num == 1 && points != NULL && scalars != NULL) | ||
1048 | return EC_POINT_mul(group, r, scalar, points[0], scalars[0], | ||
1049 | ctx); | ||
1050 | |||
1051 | /* aG, this is sane */ | ||
1052 | if (scalar != NULL && points == NULL && scalars == NULL) | ||
1053 | return EC_POINT_mul(group, r, scalar, NULL, NULL, ctx); | ||
1054 | |||
1055 | /* anything else is an error */ | ||
1056 | ECerror(ERR_R_EC_LIB); | ||
1057 | return 0; | ||
1044 | } | 1058 | } |
1045 | 1059 | ||
1046 | int | 1060 | int |
1047 | EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, | 1061 | EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, |
1048 | const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) | 1062 | const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) |
1049 | { | 1063 | { |
1050 | /* just a convenient interface to EC_POINTs_mul() */ | 1064 | if (group->meth->mul_generator_ct == NULL || |
1051 | 1065 | group->meth->mul_single_ct == NULL || | |
1052 | const EC_POINT *points[1]; | 1066 | group->meth->mul_double_nonct == NULL) { |
1053 | const BIGNUM *scalars[1]; | 1067 | ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
1054 | 1068 | return 0; | |
1055 | points[0] = point; | 1069 | } |
1056 | scalars[0] = p_scalar; | 1070 | if (g_scalar != NULL && point == NULL && p_scalar == NULL) { |
1057 | 1071 | /* | |
1058 | return EC_POINTs_mul(group, r, g_scalar, | 1072 | * In this case we want to compute g_scalar * GeneratorPoint: |
1059 | (point != NULL && p_scalar != NULL), | 1073 | * this codepath is reached most prominently by (ephemeral) key |
1060 | points, scalars, ctx); | 1074 | * generation of EC cryptosystems (i.e. ECDSA keygen and sign |
1075 | * setup, ECDH keygen/first half), where the scalar is always | ||
1076 | * secret. This is why we ignore if BN_FLG_CONSTTIME is actually | ||
1077 | * set and we always call the constant time version. | ||
1078 | */ | ||
1079 | return group->meth->mul_generator_ct(group, r, g_scalar, ctx); | ||
1080 | } | ||
1081 | if (g_scalar == NULL && point != NULL && p_scalar != NULL) { | ||
1082 | /* In this case we want to compute p_scalar * GenericPoint: | ||
1083 | * this codepath is reached most prominently by the second half | ||
1084 | * of ECDH, where the secret scalar is multiplied by the peer's | ||
1085 | * public point. To protect the secret scalar, we ignore if | ||
1086 | * BN_FLG_CONSTTIME is actually set and we always call the | ||
1087 | * constant time version. | ||
1088 | */ | ||
1089 | return group->meth->mul_single_ct(group, r, p_scalar, point, | ||
1090 | ctx); | ||
1091 | } | ||
1092 | if (g_scalar != NULL && point != NULL && p_scalar != NULL) { | ||
1093 | /* | ||
1094 | * In this case we want to compute | ||
1095 | * g_scalar * GeneratorPoint + p_scalar * GenericPoint: | ||
1096 | * this codepath is reached most prominently by ECDSA signature | ||
1097 | * verification. So we call the non-ct version. | ||
1098 | */ | ||
1099 | return group->meth->mul_double_nonct(group, r, g_scalar, | ||
1100 | p_scalar, point, ctx); | ||
1101 | } | ||
1102 | |||
1103 | /* Anything else is an error. */ | ||
1104 | ECerror(ERR_R_EC_LIB); | ||
1105 | return 0; | ||
1061 | } | 1106 | } |
1062 | 1107 | ||
1063 | int | 1108 | int |
1064 | EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx) | 1109 | EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx) |
1065 | { | 1110 | { |
1066 | if (group->meth->mul == 0) | ||
1067 | /* use default */ | ||
1068 | return ec_wNAF_precompute_mult(group, ctx); | ||
1069 | |||
1070 | if (group->meth->precompute_mult != 0) | 1111 | if (group->meth->precompute_mult != 0) |
1071 | return group->meth->precompute_mult(group, ctx); | 1112 | return group->meth->precompute_mult(group, ctx); |
1072 | else | 1113 | else |
@@ -1076,10 +1117,6 @@ EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx) | |||
1076 | int | 1117 | int |
1077 | EC_GROUP_have_precompute_mult(const EC_GROUP * group) | 1118 | EC_GROUP_have_precompute_mult(const EC_GROUP * group) |
1078 | { | 1119 | { |
1079 | if (group->meth->mul == 0) | ||
1080 | /* use default */ | ||
1081 | return ec_wNAF_have_precompute_mult(group); | ||
1082 | |||
1083 | if (group->meth->have_precompute_mult != 0) | 1120 | if (group->meth->have_precompute_mult != 0) |
1084 | return group->meth->have_precompute_mult(group); | 1121 | return group->meth->have_precompute_mult(group); |
1085 | else | 1122 | else |