diff options
-rw-r--r-- | src/lib/libcrypto/ec/ecp_oct.c | 110 |
1 files changed, 48 insertions, 62 deletions
diff --git a/src/lib/libcrypto/ec/ecp_oct.c b/src/lib/libcrypto/ec/ecp_oct.c index 6daab41870..85467a4143 100644 --- a/src/lib/libcrypto/ec/ecp_oct.c +++ b/src/lib/libcrypto/ec/ecp_oct.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ecp_oct.c,v 1.31 2024/10/31 05:47:37 tb Exp $ */ | 1 | /* $OpenBSD: ecp_oct.c,v 1.32 2024/11/02 09:21:04 tb Exp $ */ |
2 | /* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> | 2 | /* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> |
3 | * for the OpenSSL project. | 3 | * for the OpenSSL project. |
4 | * Includes code written by Bodo Moeller for the OpenSSL project. | 4 | * Includes code written by Bodo Moeller for the OpenSSL project. |
@@ -72,21 +72,17 @@ | |||
72 | 72 | ||
73 | int | 73 | int |
74 | ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, | 74 | ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, |
75 | EC_POINT *point, const BIGNUM *x_, int y_bit, BN_CTX *ctx) | 75 | EC_POINT *point, const BIGNUM *in_x, int y_bit, BN_CTX *ctx) |
76 | { | 76 | { |
77 | BIGNUM *tmp1, *tmp2, *x, *y; | 77 | const BIGNUM *p = &group->field, *a = &group->a, *b = &group->b; |
78 | BIGNUM *w, *x, *y; | ||
78 | int ret = 0; | 79 | int ret = 0; |
79 | 80 | ||
80 | /* clear error queue */ | ||
81 | ERR_clear_error(); | ||
82 | |||
83 | y_bit = (y_bit != 0); | 81 | y_bit = (y_bit != 0); |
84 | 82 | ||
85 | BN_CTX_start(ctx); | 83 | BN_CTX_start(ctx); |
86 | 84 | ||
87 | if ((tmp1 = BN_CTX_get(ctx)) == NULL) | 85 | if ((w = BN_CTX_get(ctx)) == NULL) |
88 | goto err; | ||
89 | if ((tmp2 = BN_CTX_get(ctx)) == NULL) | ||
90 | goto err; | 86 | goto err; |
91 | if ((x = BN_CTX_get(ctx)) == NULL) | 87 | if ((x = BN_CTX_get(ctx)) == NULL) |
92 | goto err; | 88 | goto err; |
@@ -94,83 +90,73 @@ ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, | |||
94 | goto err; | 90 | goto err; |
95 | 91 | ||
96 | /* | 92 | /* |
97 | * Recover y. We have a Weierstrass equation y^2 = x^3 + a*x + b, so | 93 | * Weierstrass equation: y^2 = x^3 + ax + b, so y is one of the |
98 | * y is one of the square roots of x^3 + a*x + b. | 94 | * square roots of x^3 + ax + b. The y-bit indicates which one. |
99 | */ | 95 | */ |
100 | 96 | ||
101 | /* tmp1 := x^3 */ | 97 | /* XXX - should we not insist on 0 <= x < p instead? */ |
102 | if (!BN_nnmod(x, x_, &group->field, ctx)) | 98 | if (!BN_nnmod(x, in_x, p, ctx)) |
103 | goto err; | 99 | goto err; |
104 | if (group->meth->field_decode == NULL) { | 100 | |
105 | /* field_{sqr,mul} work on standard representation */ | 101 | if (group->meth->field_encode != NULL) { |
106 | if (!group->meth->field_sqr(group, tmp2, x_, ctx)) | 102 | if (!group->meth->field_encode(group, x, x, ctx)) |
107 | goto err; | ||
108 | if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) | ||
109 | goto err; | ||
110 | } else { | ||
111 | if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) | ||
112 | goto err; | ||
113 | if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) | ||
114 | goto err; | 103 | goto err; |
115 | } | 104 | } |
116 | 105 | ||
117 | /* tmp1 := tmp1 + a*x */ | 106 | /* y = x^3 */ |
107 | if (!group->meth->field_sqr(group, y, x, ctx)) | ||
108 | goto err; | ||
109 | if (!group->meth->field_mul(group, y, y, x, ctx)) | ||
110 | goto err; | ||
111 | |||
112 | /* y += ax */ | ||
118 | if (group->a_is_minus3) { | 113 | if (group->a_is_minus3) { |
119 | if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) | 114 | if (!BN_mod_lshift1_quick(w, x, p)) |
120 | goto err; | 115 | goto err; |
121 | if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) | 116 | if (!BN_mod_add_quick(w, w, x, p)) |
122 | goto err; | 117 | goto err; |
123 | if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) | 118 | if (!BN_mod_sub_quick(y, y, w, p)) |
124 | goto err; | 119 | goto err; |
125 | } else { | 120 | } else { |
126 | if (group->meth->field_decode) { | 121 | if (!group->meth->field_mul(group, w, a, x, ctx)) |
127 | if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) | 122 | goto err; |
128 | goto err; | 123 | if (!BN_mod_add_quick(y, y, w, p)) |
129 | if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) | ||
130 | goto err; | ||
131 | } else { | ||
132 | /* field_mul works on standard representation */ | ||
133 | if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) | ||
134 | goto err; | ||
135 | } | ||
136 | |||
137 | if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) | ||
138 | goto err; | 124 | goto err; |
139 | } | 125 | } |
140 | 126 | ||
141 | /* tmp1 := tmp1 + b */ | 127 | /* y += b */ |
128 | if (!BN_mod_add_quick(y, y, b, p)) | ||
129 | goto err; | ||
130 | |||
142 | if (group->meth->field_decode != NULL) { | 131 | if (group->meth->field_decode != NULL) { |
143 | if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) | 132 | if (!group->meth->field_decode(group, x, x, ctx)) |
144 | goto err; | 133 | goto err; |
145 | if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) | 134 | if (!group->meth->field_decode(group, y, y, ctx)) |
146 | goto err; | ||
147 | } else { | ||
148 | if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) | ||
149 | goto err; | 135 | goto err; |
150 | } | 136 | } |
151 | 137 | ||
152 | if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { | 138 | if (!BN_mod_sqrt(y, y, p, ctx)) { |
153 | unsigned long err = ERR_peek_last_error(); | 139 | ECerror(EC_R_INVALID_COMPRESSED_POINT); |
140 | goto err; | ||
141 | } | ||
142 | |||
143 | if (y_bit == BN_is_odd(y)) | ||
144 | goto done; | ||
154 | 145 | ||
155 | if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { | 146 | if (BN_is_zero(y)) { |
156 | ERR_clear_error(); | 147 | ECerror(EC_R_INVALID_COMPRESSION_BIT); |
157 | ECerror(EC_R_INVALID_COMPRESSED_POINT); | ||
158 | } else | ||
159 | ECerror(ERR_R_BN_LIB); | ||
160 | goto err; | 148 | goto err; |
161 | } | 149 | } |
150 | if (!BN_usub(y, &group->field, y)) | ||
151 | goto err; | ||
152 | |||
162 | if (y_bit != BN_is_odd(y)) { | 153 | if (y_bit != BN_is_odd(y)) { |
163 | if (BN_is_zero(y)) { | 154 | /* Can only happen if p is even and should not be reachable. */ |
164 | ECerror(EC_R_INVALID_COMPRESSION_BIT); | 155 | ECerror(ERR_R_INTERNAL_ERROR); |
165 | goto err; | 156 | goto err; |
166 | } | ||
167 | if (!BN_usub(y, &group->field, y)) | ||
168 | goto err; | ||
169 | if (y_bit != BN_is_odd(y)) { | ||
170 | ECerror(ERR_R_INTERNAL_ERROR); | ||
171 | goto err; | ||
172 | } | ||
173 | } | 157 | } |
158 | |||
159 | done: | ||
174 | if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx)) | 160 | if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx)) |
175 | goto err; | 161 | goto err; |
176 | 162 | ||