diff options
author | tb <> | 2023-07-04 07:38:31 +0000 |
---|---|---|
committer | tb <> | 2023-07-04 07:38:31 +0000 |
commit | 127efe31f6e78fc619e5922fdb2f786aff562d44 (patch) | |
tree | 086fbae4747cedb9ba7652be2ec888d5fd4cb5db /src | |
parent | a16bf3b65a06ce3dfb501497e091210ecb1548ce (diff) | |
download | openbsd-127efe31f6e78fc619e5922fdb2f786aff562d44.tar.gz openbsd-127efe31f6e78fc619e5922fdb2f786aff562d44.tar.bz2 openbsd-127efe31f6e78fc619e5922fdb2f786aff562d44.zip |
Factor the computation of ECDSA s into a function
ossl_ecdsa_sign_sig() is already complicated enough. The math bit is
entirely self contained and does not need to obfuscate control flow
and logic.
with feedback from and ok jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/ecdsa/ecs_ossl.c | 157 |
1 files changed, 88 insertions, 69 deletions
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c index 2140f8a8e1..5b5013d631 100644 --- a/src/lib/libcrypto/ecdsa/ecs_ossl.c +++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ecs_ossl.c,v 1.61 2023/07/03 14:51:09 tb Exp $ */ | 1 | /* $OpenBSD: ecs_ossl.c,v 1.62 2023/07/04 07:38:31 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Nils Larsch for the OpenSSL project | 3 | * Written by Nils Larsch for the OpenSSL project |
4 | */ | 4 | */ |
@@ -260,6 +260,88 @@ ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *in_ctx, BIGNUM **out_kinv, | |||
260 | } | 260 | } |
261 | 261 | ||
262 | /* | 262 | /* |
263 | * FIPS 186-5, section 6.4.1, step 9: compute s = inv(k)(m + xr) mod order. | ||
264 | * In order to reduce the possibility of a side-channel attack, the following | ||
265 | * is calculated using a random blinding value b in [1, order): | ||
266 | * s = inv(b)(bm + bxr)inv(k) mod order. | ||
267 | */ | ||
268 | |||
269 | static int | ||
270 | ecdsa_compute_s(BIGNUM **out_s, const BIGNUM *m, const BIGNUM *kinv, | ||
271 | const BIGNUM *r, const BIGNUM *priv_key, const BIGNUM *order, BN_CTX *ctx) | ||
272 | { | ||
273 | BIGNUM *b, *binv, *bm, *bxr; | ||
274 | BIGNUM *s = NULL; | ||
275 | int ret = 0; | ||
276 | |||
277 | *out_s = NULL; | ||
278 | |||
279 | BN_CTX_start(ctx); | ||
280 | |||
281 | if ((b = BN_CTX_get(ctx)) == NULL) | ||
282 | goto err; | ||
283 | if ((binv = BN_CTX_get(ctx)) == NULL) | ||
284 | goto err; | ||
285 | if ((bm = BN_CTX_get(ctx)) == NULL) | ||
286 | goto err; | ||
287 | if ((bxr = BN_CTX_get(ctx)) == NULL) | ||
288 | goto err; | ||
289 | |||
290 | if ((s = BN_new()) == NULL) | ||
291 | goto err; | ||
292 | |||
293 | if (!bn_rand_interval(b, BN_value_one(), order)) { | ||
294 | ECDSAerror(ERR_R_BN_LIB); | ||
295 | goto err; | ||
296 | } | ||
297 | |||
298 | if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) { | ||
299 | ECDSAerror(ERR_R_BN_LIB); | ||
300 | goto err; | ||
301 | } | ||
302 | |||
303 | if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) { | ||
304 | ECDSAerror(ERR_R_BN_LIB); | ||
305 | goto err; | ||
306 | } | ||
307 | if (!BN_mod_mul(bxr, bxr, r, order, ctx)) { | ||
308 | ECDSAerror(ERR_R_BN_LIB); | ||
309 | goto err; | ||
310 | } | ||
311 | if (!BN_mod_mul(bm, b, m, order, ctx)) { | ||
312 | ECDSAerror(ERR_R_BN_LIB); | ||
313 | goto err; | ||
314 | } | ||
315 | if (!BN_mod_add(s, bm, bxr, order, ctx)) { | ||
316 | ECDSAerror(ERR_R_BN_LIB); | ||
317 | goto err; | ||
318 | } | ||
319 | /* s = b(m + xr)k^-1 */ | ||
320 | if (!BN_mod_mul(s, s, kinv, order, ctx)) { | ||
321 | ECDSAerror(ERR_R_BN_LIB); | ||
322 | goto err; | ||
323 | } | ||
324 | /* s = (m + xr)k^-1 */ | ||
325 | if (!BN_mod_mul(s, s, binv, order, ctx)) { | ||
326 | ECDSAerror(ERR_R_BN_LIB); | ||
327 | goto err; | ||
328 | } | ||
329 | |||
330 | if (!BN_is_zero(s)) { | ||
331 | *out_s = s; | ||
332 | s = NULL; | ||
333 | } | ||
334 | |||
335 | ret = 1; | ||
336 | |||
337 | err: | ||
338 | BN_CTX_end(ctx); | ||
339 | BN_free(s); | ||
340 | |||
341 | return ret; | ||
342 | } | ||
343 | |||
344 | /* | ||
263 | * It is too expensive to check curve parameters on every sign operation. | 345 | * It is too expensive to check curve parameters on every sign operation. |
264 | * Instead, cap the number of retries. A single retry is very unlikely, so | 346 | * Instead, cap the number of retries. A single retry is very unlikely, so |
265 | * allowing 32 retries is amply enough. | 347 | * allowing 32 retries is amply enough. |
@@ -273,7 +355,7 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, | |||
273 | const EC_GROUP *group; | 355 | const EC_GROUP *group; |
274 | BN_CTX *ctx = NULL; | 356 | BN_CTX *ctx = NULL; |
275 | BIGNUM *kinv = NULL, *r = NULL, *s = NULL; | 357 | BIGNUM *kinv = NULL, *r = NULL, *s = NULL; |
276 | BIGNUM *b, *binv, *bm, *bxr, *m; | 358 | BIGNUM *m; |
277 | const BIGNUM *order, *priv_key; | 359 | const BIGNUM *order, *priv_key; |
278 | int caller_supplied_values = 0; | 360 | int caller_supplied_values = 0; |
279 | int attempts = 0; | 361 | int attempts = 0; |
@@ -288,15 +370,6 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, | |||
288 | goto err; | 370 | goto err; |
289 | } | 371 | } |
290 | 372 | ||
291 | if ((r = BN_new()) == NULL) { | ||
292 | ECDSAerror(ERR_R_MALLOC_FAILURE); | ||
293 | goto err; | ||
294 | } | ||
295 | if ((s = BN_new()) == NULL) { | ||
296 | ECDSAerror(ERR_R_MALLOC_FAILURE); | ||
297 | goto err; | ||
298 | } | ||
299 | |||
300 | if ((ctx = BN_CTX_new()) == NULL) { | 373 | if ((ctx = BN_CTX_new()) == NULL) { |
301 | ECDSAerror(ERR_R_MALLOC_FAILURE); | 374 | ECDSAerror(ERR_R_MALLOC_FAILURE); |
302 | goto err; | 375 | goto err; |
@@ -304,14 +377,6 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, | |||
304 | 377 | ||
305 | BN_CTX_start(ctx); | 378 | BN_CTX_start(ctx); |
306 | 379 | ||
307 | if ((b = BN_CTX_get(ctx)) == NULL) | ||
308 | goto err; | ||
309 | if ((binv = BN_CTX_get(ctx)) == NULL) | ||
310 | goto err; | ||
311 | if ((bm = BN_CTX_get(ctx)) == NULL) | ||
312 | goto err; | ||
313 | if ((bxr = BN_CTX_get(ctx)) == NULL) | ||
314 | goto err; | ||
315 | if ((m = BN_CTX_get(ctx)) == NULL) | 380 | if ((m = BN_CTX_get(ctx)) == NULL) |
316 | goto err; | 381 | goto err; |
317 | 382 | ||
@@ -335,7 +400,7 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, | |||
335 | ECDSAerror(ERR_R_MALLOC_FAILURE); | 400 | ECDSAerror(ERR_R_MALLOC_FAILURE); |
336 | goto err; | 401 | goto err; |
337 | } | 402 | } |
338 | if (!bn_copy(r, in_r)) { | 403 | if ((r = BN_dup(in_r)) == NULL) { |
339 | ECDSAerror(ERR_R_MALLOC_FAILURE); | 404 | ECDSAerror(ERR_R_MALLOC_FAILURE); |
340 | goto err; | 405 | goto err; |
341 | } | 406 | } |
@@ -349,56 +414,10 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, | |||
349 | } | 414 | } |
350 | } | 415 | } |
351 | 416 | ||
352 | /* | 417 | /* If s is non-NULL, we have a valid signature. */ |
353 | * Compute: | 418 | if (!ecdsa_compute_s(&s, m, kinv, r, priv_key, order, ctx)) |
354 | * | ||
355 | * s = inv(k)(m + xr) mod order | ||
356 | * | ||
357 | * In order to reduce the possibility of a side-channel attack, | ||
358 | * the following is calculated using a blinding value: | ||
359 | * | ||
360 | * s = inv(b)(bm + bxr)inv(k) mod order | ||
361 | * | ||
362 | * where b is a random value in the range [1, order). | ||
363 | */ | ||
364 | |||
365 | if (!bn_rand_interval(b, BN_value_one(), order)) { | ||
366 | ECDSAerror(ERR_R_BN_LIB); | ||
367 | goto err; | ||
368 | } | ||
369 | |||
370 | if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) { | ||
371 | ECDSAerror(ERR_R_BN_LIB); | ||
372 | goto err; | ||
373 | } | ||
374 | |||
375 | if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) { /* bx */ | ||
376 | ECDSAerror(ERR_R_BN_LIB); | ||
377 | goto err; | ||
378 | } | ||
379 | if (!BN_mod_mul(bxr, bxr, r, order, ctx)) { /* bxr */ | ||
380 | ECDSAerror(ERR_R_BN_LIB); | ||
381 | goto err; | ||
382 | } | ||
383 | if (!BN_mod_mul(bm, b, m, order, ctx)) { /* bm */ | ||
384 | ECDSAerror(ERR_R_BN_LIB); | ||
385 | goto err; | 419 | goto err; |
386 | } | 420 | if (s != NULL) |
387 | if (!BN_mod_add(s, bm, bxr, order, ctx)) { /* s = bm + bxr */ | ||
388 | ECDSAerror(ERR_R_BN_LIB); | ||
389 | goto err; | ||
390 | } | ||
391 | if (!BN_mod_mul(s, s, kinv, order, ctx)) { /* s = b(m + xr)k^-1 */ | ||
392 | ECDSAerror(ERR_R_BN_LIB); | ||
393 | goto err; | ||
394 | } | ||
395 | if (!BN_mod_mul(s, s, binv, order, ctx)) { /* s = (m + xr)k^-1 */ | ||
396 | ECDSAerror(ERR_R_BN_LIB); | ||
397 | goto err; | ||
398 | } | ||
399 | |||
400 | /* If s is non-zero, we have a valid signature. */ | ||
401 | if (!BN_is_zero(s)) | ||
402 | break; | 421 | break; |
403 | 422 | ||
404 | if (caller_supplied_values) { | 423 | if (caller_supplied_values) { |