100 | 100 |
OPENSSL_free(pre);
|
101 | 101 |
}
|
102 | 102 |
|
|
103 |
#define EC_POINT_set_flags(P, flags) do { \
|
|
104 |
BN_set_flags((P)->X, (flags)); \
|
|
105 |
BN_set_flags((P)->Y, (flags)); \
|
|
106 |
BN_set_flags((P)->Z, (flags)); \
|
|
107 |
} while(0)
|
|
108 |
|
|
109 |
/*
|
|
110 |
* This functions computes (in constant time) a point multiplication over the
|
|
111 |
* EC group.
|
|
112 |
*
|
|
113 |
* It performs either a fixed scalar point multiplication
|
|
114 |
* (scalar * generator)
|
|
115 |
* when point is NULL, or a generic scalar point multiplication
|
|
116 |
* (scalar * point)
|
|
117 |
* when point is not NULL.
|
|
118 |
*
|
|
119 |
* scalar should be in the range [0,n) otherwise all constant time bets are off.
|
|
120 |
*
|
|
121 |
* NB: This says nothing about EC_POINT_add and EC_POINT_dbl,
|
|
122 |
* which of course are not constant time themselves.
|
|
123 |
*
|
|
124 |
* The product is stored in r.
|
|
125 |
*
|
|
126 |
* Returns 1 on success, 0 otherwise.
|
|
127 |
*/
|
|
128 |
static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|
129 |
const EC_POINT *point, BN_CTX *ctx)
|
|
130 |
{
|
|
131 |
int i, order_bits, group_top, kbit, pbit, Z_is_one, ret;
|
|
132 |
ret = 0;
|
|
133 |
EC_POINT *s = NULL;
|
|
134 |
BIGNUM *k = NULL;
|
|
135 |
BIGNUM *lambda = NULL;
|
|
136 |
BN_CTX *new_ctx = NULL;
|
|
137 |
|
|
138 |
if (ctx == NULL)
|
|
139 |
if ((ctx = new_ctx = BN_CTX_secure_new()) == NULL)
|
|
140 |
return 0;
|
|
141 |
|
|
142 |
if ((group->order == NULL) || (group->field == NULL))
|
|
143 |
goto err;
|
|
144 |
|
|
145 |
order_bits = BN_num_bits(group->order);
|
|
146 |
|
|
147 |
s = EC_POINT_new(group);
|
|
148 |
if (s == NULL)
|
|
149 |
goto err;
|
|
150 |
|
|
151 |
if (point == NULL) {
|
|
152 |
if (group->generator == NULL)
|
|
153 |
goto err;
|
|
154 |
if (!EC_POINT_copy(s, group->generator))
|
|
155 |
goto err;
|
|
156 |
} else {
|
|
157 |
if (!EC_POINT_copy(s, point))
|
|
158 |
goto err;
|
|
159 |
}
|
|
160 |
|
|
161 |
EC_POINT_set_flags(s, BN_FLG_CONSTTIME);
|
|
162 |
|
|
163 |
BN_CTX_start(ctx);
|
|
164 |
lambda = BN_CTX_get(ctx);
|
|
165 |
k = BN_CTX_get(ctx);
|
|
166 |
if (k == NULL)
|
|
167 |
goto err;
|
|
168 |
|
|
169 |
/*
|
|
170 |
* Group orders are often on a word boundary.
|
|
171 |
* So when we pad the scalar, some timing diff might
|
|
172 |
* pop if it needs to be expanded due to carries.
|
|
173 |
* So expand ahead of time.
|
|
174 |
*/
|
|
175 |
group_top = bn_get_top(group->order);
|
|
176 |
if ((bn_wexpand(k, group_top + 1) == NULL)
|
|
177 |
|| (bn_wexpand(lambda, group_top + 1) == NULL))
|
|
178 |
goto err;
|
|
179 |
|
|
180 |
if (!BN_copy(k, scalar))
|
|
181 |
goto err;
|
|
182 |
|
|
183 |
BN_set_flags(k, BN_FLG_CONSTTIME);
|
|
184 |
|
|
185 |
if ((BN_num_bits(k) > order_bits) || (BN_is_negative(k))) {
|
|
186 |
/*
|
|
187 |
* this is an unusual input, and we don't guarantee
|
|
188 |
* constant-timeness
|
|
189 |
*/
|
|
190 |
if(!BN_nnmod(k, k, group->order, ctx))
|
|
191 |
goto err;
|
|
192 |
}
|
|
193 |
|
|
194 |
if (!BN_add(lambda, k, group->order))
|
|
195 |
goto err;
|
|
196 |
BN_set_flags(lambda, BN_FLG_CONSTTIME);
|
|
197 |
if (!BN_add(k, lambda, group->order))
|
|
198 |
goto err;
|
|
199 |
/*
|
|
200 |
* lambda := scalar + order
|
|
201 |
* k := scalar + 2*order
|
|
202 |
*/
|
|
203 |
kbit = BN_is_bit_set(lambda, order_bits);
|
|
204 |
BN_consttime_swap(kbit, k, lambda, group_top + 1);
|
|
205 |
|
|
206 |
group_top = bn_get_top(group->field);
|
|
207 |
if ((bn_wexpand(s->X, group_top) == NULL)
|
|
208 |
|| (bn_wexpand(s->Y, group_top) == NULL)
|
|
209 |
|| (bn_wexpand(s->Z, group_top) == NULL)
|
|
210 |
|| (bn_wexpand(r->X, group_top) == NULL)
|
|
211 |
|| (bn_wexpand(r->Y, group_top) == NULL)
|
|
212 |
|| (bn_wexpand(r->Z, group_top) == NULL))
|
|
213 |
goto err;
|
|
214 |
|
|
215 |
/* top bit is a 1, in a fixed pos */
|
|
216 |
if (!EC_POINT_copy(r, s))
|
|
217 |
goto err;
|
|
218 |
|
|
219 |
EC_POINT_set_flags(r, BN_FLG_CONSTTIME);
|
|
220 |
|
|
221 |
if (!EC_POINT_dbl(group, s, s, ctx))
|
|
222 |
goto err;
|
|
223 |
|
|
224 |
pbit = 0;
|
|
225 |
|
|
226 |
#define EC_POINT_CSWAP(c, a, b, w, t) do { \
|
|
227 |
BN_consttime_swap(c, (a)->X, (b)->X, w); \
|
|
228 |
BN_consttime_swap(c, (a)->Y, (b)->Y, w); \
|
|
229 |
BN_consttime_swap(c, (a)->Z, (b)->Z, w); \
|
|
230 |
t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
|
|
231 |
(a)->Z_is_one ^= (t); \
|
|
232 |
(b)->Z_is_one ^= (t); \
|
|
233 |
} while(0)
|
|
234 |
|
|
235 |
for (i = order_bits - 1; i >= 0; i--) {
|
|
236 |
kbit = BN_is_bit_set(k, i) ^ pbit;
|
|
237 |
EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
|
|
238 |
if (!EC_POINT_add(group, s, r, s, ctx))
|
|
239 |
goto err;
|
|
240 |
if (!EC_POINT_dbl(group, r, r, ctx))
|
|
241 |
goto err;
|
|
242 |
/*
|
|
243 |
* pbit logic merges this cswap with that of the
|
|
244 |
* next iteration
|
|
245 |
*/
|
|
246 |
pbit ^= kbit;
|
|
247 |
}
|
|
248 |
/* one final cswap to move the right value into r */
|
|
249 |
EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
|
|
250 |
#undef EC_POINT_CSWAP
|
|
251 |
|
|
252 |
ret = 1;
|
|
253 |
|
|
254 |
err:
|
|
255 |
EC_POINT_free(s);
|
|
256 |
BN_CTX_end(ctx);
|
|
257 |
BN_CTX_free(new_ctx);
|
|
258 |
|
|
259 |
return ret;
|
|
260 |
}
|
|
261 |
#undef EC_POINT_set_flags
|
|
262 |
|
103 | 263 |
/*
|
104 | 264 |
* TODO: table should be optimised for the wNAF-based implementation,
|
105 | 265 |
* sometimes smaller windows will give better performance (thus the
|
|
125 | 285 |
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
126 | 286 |
BN_CTX *ctx)
|
127 | 287 |
{
|
|
288 |
if ((scalar != NULL) && (num == 0)) {
|
|
289 |
/* In this case we want to compute scalar * GeneratorPoint:
|
|
290 |
* this codepath is reached most prominently by (ephemeral) key
|
|
291 |
* generation of EC cryptosystems (i.e. ECDSA keygen and sign setup,
|
|
292 |
* ECDH keygen/first half), where the scalar is always secret.
|
|
293 |
* This is why we ignore if BN_FLG_CONSTTIME is actually set and we
|
|
294 |
* always call the constant time version.
|
|
295 |
*/
|
|
296 |
return ec_mul_consttime(group, r, scalar, NULL, ctx);
|
|
297 |
}
|
|
298 |
|
|
299 |
if ((scalar == NULL) && (num == 1)) {
|
|
300 |
/* In this case we want to compute scalar * GenericPoint:
|
|
301 |
* this codepath is reached most prominently by the second half of
|
|
302 |
* ECDH, where the secret scalar is multiplied by the peer's public
|
|
303 |
* point.
|
|
304 |
* To protect the secret scalar, we ignore if BN_FLG_CONSTTIME is
|
|
305 |
* actually set and we always call the constant time version.
|
|
306 |
*/
|
|
307 |
return ec_mul_consttime(group, r, scalars[0], points[0], ctx);
|
|
308 |
}
|
|
309 |
|
128 | 310 |
BN_CTX *new_ctx = NULL;
|
129 | 311 |
const EC_POINT *generator = NULL;
|
130 | 312 |
EC_POINT *tmp = NULL;
|