summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2023-07-04 07:38:31 +0000
committertb <>2023-07-04 07:38:31 +0000
commit127efe31f6e78fc619e5922fdb2f786aff562d44 (patch)
tree086fbae4747cedb9ba7652be2ec888d5fd4cb5db /src
parenta16bf3b65a06ce3dfb501497e091210ecb1548ce (diff)
downloadopenbsd-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.c157
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
269static int
270ecdsa_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) {