diff options
Diffstat (limited to 'src/lib/libcrypto')
| -rw-r--r-- | src/lib/libcrypto/ecdsa/ecs_ossl.c | 79 | 
1 files changed, 65 insertions, 14 deletions
| diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c index 0f594aa86e..3939d7c8c1 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.11 2018/06/13 15:05:04 jsing Exp $ */ | 1 | /* $OpenBSD: ecs_ossl.c,v 1.12 2018/06/14 18:51:01 tb Exp $ */ | 
| 2 | /* | 2 | /* | 
| 3 | * Written by Nils Larsch for the OpenSSL project | 3 | * Written by Nils Larsch for the OpenSSL project | 
| 4 | */ | 4 | */ | 
| @@ -221,14 +221,14 @@ static ECDSA_SIG * | |||
| 221 | ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | 221 | ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | 
| 222 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) | 222 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) | 
| 223 | { | 223 | { | 
| 224 | int ok = 0, i; | 224 | BIGNUM *b = NULL, *binv = NULL, *bm = NULL, *bxr = NULL; | 
| 225 | BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; | 225 | BIGNUM *kinv = NULL, *m = NULL, *order = NULL, *range = NULL, *s; | 
| 226 | const BIGNUM *ckinv; | 226 | const BIGNUM *ckinv, *priv_key; | 
| 227 | BN_CTX *ctx = NULL; | 227 | BN_CTX *ctx = NULL; | 
| 228 | const EC_GROUP *group; | 228 | const EC_GROUP *group; | 
| 229 | ECDSA_SIG *ret; | 229 | ECDSA_SIG *ret; | 
| 230 | ECDSA_DATA *ecdsa; | 230 | ECDSA_DATA *ecdsa; | 
| 231 | const BIGNUM *priv_key; | 231 | int ok = 0, i; | 
| 232 | 232 | ||
| 233 | ecdsa = ecdsa_check(eckey); | 233 | ecdsa = ecdsa_check(eckey); | 
| 234 | group = EC_KEY_get0_group(eckey); | 234 | group = EC_KEY_get0_group(eckey); | 
| @@ -247,7 +247,9 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
| 247 | s = ret->s; | 247 | s = ret->s; | 
| 248 | 248 | ||
| 249 | if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || | 249 | if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || | 
| 250 | (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { | 250 | (range = BN_new()) == NULL || (b = BN_new()) == NULL || | 
| 251 | (binv = BN_new()) == NULL || (bm = BN_new()) == NULL || | ||
| 252 | (bxr = BN_new()) == NULL || (m = BN_new()) == NULL) { | ||
| 251 | ECDSAerror(ERR_R_MALLOC_FAILURE); | 253 | ECDSAerror(ERR_R_MALLOC_FAILURE); | 
| 252 | goto err; | 254 | goto err; | 
| 253 | } | 255 | } | 
| @@ -286,11 +288,53 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
| 286 | } | 288 | } | 
| 287 | } | 289 | } | 
| 288 | 290 | ||
| 289 | if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { | 291 | /* | 
| 292 | * Compute s = inv(k)(m + xr) mod order. | ||
| 293 | * | ||
| 294 | * In order to reduce the possibility of a side-channel attack, | ||
| 295 | * the following is calculated using a blinding value: | ||
| 296 | * | ||
| 297 | * s = inv(k)inv(b)(bm + bxr) mod order | ||
| 298 | * | ||
| 299 | * where b is a random value in the range [1, order-1]. | ||
| 300 | */ | ||
| 301 | |||
| 302 | /* Generate b in range [1, order-1]. */ | ||
| 303 | if (!BN_sub(range, order, BN_value_one())) { | ||
| 304 | ECDSAerror(ERR_R_BN_LIB); | ||
| 305 | goto err; | ||
| 306 | } | ||
| 307 | if (!BN_rand_range(b, range)) { | ||
| 308 | ECDSAerror(ERR_R_BN_LIB); | ||
| 309 | goto err; | ||
| 310 | } | ||
| 311 | if (!BN_add(b, b, BN_value_one())) { | ||
| 312 | ECDSAerror(ERR_R_BN_LIB); | ||
| 313 | goto err; | ||
| 314 | } | ||
| 315 | |||
| 316 | if (BN_mod_inverse_ct(binv, b, order, ctx) == NULL) { | ||
| 317 | ECDSAerror(ERR_R_BN_LIB); | ||
| 318 | goto err; | ||
| 319 | } | ||
| 320 | |||
| 321 | if (!BN_mod_mul(bxr, b, priv_key, order, ctx)) { /* bx */ | ||
| 290 | ECDSAerror(ERR_R_BN_LIB); | 322 | ECDSAerror(ERR_R_BN_LIB); | 
| 291 | goto err; | 323 | goto err; | 
| 292 | } | 324 | } | 
| 293 | if (!BN_mod_add(s, tmp, m, order, ctx)) { | 325 | if (!BN_mod_mul(bxr, bxr, ret->r, order, ctx)) { /* bxr */ | 
| 326 | ECDSAerror(ERR_R_BN_LIB); | ||
| 327 | goto err; | ||
| 328 | } | ||
| 329 | if (!BN_mod_mul(bm, b, m, order, ctx)) { /* bm */ | ||
| 330 | ECDSAerror(ERR_R_BN_LIB); | ||
| 331 | goto err; | ||
| 332 | } | ||
| 333 | if (!BN_mod_add(s, bm, bxr, order, ctx)) { /* s = bm + bxr */ | ||
| 334 | ECDSAerror(ERR_R_BN_LIB); | ||
| 335 | goto err; | ||
| 336 | } | ||
| 337 | if (!BN_mod_mul(s, s, binv, order, ctx)) { /* s = m + xr */ | ||
| 294 | ECDSAerror(ERR_R_BN_LIB); | 338 | ECDSAerror(ERR_R_BN_LIB); | 
| 295 | goto err; | 339 | goto err; | 
| 296 | } | 340 | } | 
| @@ -298,9 +342,12 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
| 298 | ECDSAerror(ERR_R_BN_LIB); | 342 | ECDSAerror(ERR_R_BN_LIB); | 
| 299 | goto err; | 343 | goto err; | 
| 300 | } | 344 | } | 
| 345 | |||
| 301 | if (BN_is_zero(s)) { | 346 | if (BN_is_zero(s)) { | 
| 302 | /* if kinv and r have been supplied by the caller | 347 | /* | 
| 303 | * don't to generate new kinv and r values */ | 348 | * If kinv and r have been supplied by the caller, | 
| 349 | * don't generate new kinv and r values | ||
| 350 | */ | ||
| 304 | if (in_kinv != NULL && in_r != NULL) { | 351 | if (in_kinv != NULL && in_r != NULL) { | 
| 305 | ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES); | 352 | ECDSAerror(ECDSA_R_NEED_NEW_SETUP_VALUES); | 
| 306 | goto err; | 353 | goto err; | 
| @@ -318,10 +365,14 @@ err: | |||
| 318 | ret = NULL; | 365 | ret = NULL; | 
| 319 | } | 366 | } | 
| 320 | BN_CTX_free(ctx); | 367 | BN_CTX_free(ctx); | 
| 368 | BN_clear_free(b); | ||
| 369 | BN_clear_free(binv); | ||
| 370 | BN_clear_free(bm); | ||
| 371 | BN_clear_free(bxr); | ||
| 372 | BN_clear_free(kinv); | ||
| 321 | BN_clear_free(m); | 373 | BN_clear_free(m); | 
| 322 | BN_clear_free(tmp); | ||
| 323 | BN_free(order); | 374 | BN_free(order); | 
| 324 | BN_clear_free(kinv); | 375 | BN_free(range); | 
| 325 | return ret; | 376 | return ret; | 
| 326 | } | 377 | } | 
| 327 | 378 | ||
