diff options
Diffstat (limited to 'src/lib/libcrypto/rsa/rsa_lib.c')
| -rw-r--r-- | src/lib/libcrypto/rsa/rsa_lib.c | 130 |
1 files changed, 95 insertions, 35 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_lib.c b/src/lib/libcrypto/rsa/rsa_lib.c index e4d622851e..104aa4c1f2 100644 --- a/src/lib/libcrypto/rsa/rsa_lib.c +++ b/src/lib/libcrypto/rsa/rsa_lib.c | |||
| @@ -67,7 +67,7 @@ | |||
| 67 | #include <openssl/engine.h> | 67 | #include <openssl/engine.h> |
| 68 | #endif | 68 | #endif |
| 69 | 69 | ||
| 70 | const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT; | 70 | const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT; |
| 71 | 71 | ||
| 72 | static const RSA_METHOD *default_RSA_meth=NULL; | 72 | static const RSA_METHOD *default_RSA_meth=NULL; |
| 73 | 73 | ||
| @@ -179,6 +179,7 @@ RSA *RSA_new_method(ENGINE *engine) | |||
| 179 | ret->_method_mod_p=NULL; | 179 | ret->_method_mod_p=NULL; |
| 180 | ret->_method_mod_q=NULL; | 180 | ret->_method_mod_q=NULL; |
| 181 | ret->blinding=NULL; | 181 | ret->blinding=NULL; |
| 182 | ret->mt_blinding=NULL; | ||
| 182 | ret->bignum_data=NULL; | 183 | ret->bignum_data=NULL; |
| 183 | ret->flags=ret->meth->flags; | 184 | ret->flags=ret->meth->flags; |
| 184 | CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); | 185 | CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); |
| @@ -232,6 +233,7 @@ void RSA_free(RSA *r) | |||
| 232 | if (r->dmq1 != NULL) BN_clear_free(r->dmq1); | 233 | if (r->dmq1 != NULL) BN_clear_free(r->dmq1); |
| 233 | if (r->iqmp != NULL) BN_clear_free(r->iqmp); | 234 | if (r->iqmp != NULL) BN_clear_free(r->iqmp); |
| 234 | if (r->blinding != NULL) BN_BLINDING_free(r->blinding); | 235 | if (r->blinding != NULL) BN_BLINDING_free(r->blinding); |
| 236 | if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding); | ||
| 235 | if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); | 237 | if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); |
| 236 | OPENSSL_free(r); | 238 | OPENSSL_free(r); |
| 237 | } | 239 | } |
| @@ -314,59 +316,117 @@ void RSA_blinding_off(RSA *rsa) | |||
| 314 | rsa->flags |= RSA_FLAG_NO_BLINDING; | 316 | rsa->flags |= RSA_FLAG_NO_BLINDING; |
| 315 | } | 317 | } |
| 316 | 318 | ||
| 317 | int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx) | 319 | int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) |
| 318 | { | 320 | { |
| 319 | BIGNUM *A,*Ai = NULL; | ||
| 320 | BN_CTX *ctx; | ||
| 321 | int ret=0; | 321 | int ret=0; |
| 322 | 322 | ||
| 323 | if (p_ctx == NULL) | 323 | if (rsa->blinding != NULL) |
| 324 | RSA_blinding_off(rsa); | ||
| 325 | |||
| 326 | rsa->blinding = RSA_setup_blinding(rsa, ctx); | ||
| 327 | if (rsa->blinding == NULL) | ||
| 328 | goto err; | ||
| 329 | |||
| 330 | rsa->flags |= RSA_FLAG_BLINDING; | ||
| 331 | rsa->flags &= ~RSA_FLAG_NO_BLINDING; | ||
| 332 | ret=1; | ||
| 333 | err: | ||
| 334 | return(ret); | ||
| 335 | } | ||
| 336 | |||
| 337 | static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, | ||
| 338 | const BIGNUM *q, BN_CTX *ctx) | ||
| 339 | { | ||
| 340 | BIGNUM *ret = NULL, *r0, *r1, *r2; | ||
| 341 | |||
| 342 | if (d == NULL || p == NULL || q == NULL) | ||
| 343 | return NULL; | ||
| 344 | |||
| 345 | BN_CTX_start(ctx); | ||
| 346 | r0 = BN_CTX_get(ctx); | ||
| 347 | r1 = BN_CTX_get(ctx); | ||
| 348 | r2 = BN_CTX_get(ctx); | ||
| 349 | if (r2 == NULL) | ||
| 350 | goto err; | ||
| 351 | |||
| 352 | if (!BN_sub(r1, p, BN_value_one())) goto err; | ||
| 353 | if (!BN_sub(r2, q, BN_value_one())) goto err; | ||
| 354 | if (!BN_mul(r0, r1, r2, ctx)) goto err; | ||
| 355 | |||
| 356 | ret = BN_mod_inverse(NULL, d, r0, ctx); | ||
| 357 | err: | ||
| 358 | BN_CTX_end(ctx); | ||
| 359 | return ret; | ||
| 360 | } | ||
| 361 | |||
| 362 | BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) | ||
| 363 | { | ||
| 364 | BIGNUM local_n; | ||
| 365 | BIGNUM *e,*n; | ||
| 366 | BN_CTX *ctx; | ||
| 367 | BN_BLINDING *ret = NULL; | ||
| 368 | |||
| 369 | if (in_ctx == NULL) | ||
| 324 | { | 370 | { |
| 325 | if ((ctx=BN_CTX_new()) == NULL) goto err; | 371 | if ((ctx = BN_CTX_new()) == NULL) return 0; |
| 326 | } | 372 | } |
| 327 | else | 373 | else |
| 328 | ctx=p_ctx; | 374 | ctx = in_ctx; |
| 329 | 375 | ||
| 330 | /* XXXXX: Shouldn't this be RSA_blinding_off(rsa)? */ | 376 | BN_CTX_start(ctx); |
| 331 | if (rsa->blinding != NULL) | 377 | e = BN_CTX_get(ctx); |
| 378 | if (e == NULL) | ||
| 332 | { | 379 | { |
| 333 | BN_BLINDING_free(rsa->blinding); | 380 | RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); |
| 334 | rsa->blinding = NULL; | 381 | goto err; |
| 335 | } | 382 | } |
| 336 | 383 | ||
| 337 | /* NB: similar code appears in setup_blinding (rsa_eay.c); | 384 | if (rsa->e == NULL) |
| 338 | * this should be placed in a new function of its own, but for reasons | 385 | { |
| 339 | * of binary compatibility can't */ | 386 | e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); |
| 387 | if (e == NULL) | ||
| 388 | { | ||
| 389 | RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); | ||
| 390 | goto err; | ||
| 391 | } | ||
| 392 | } | ||
| 393 | else | ||
| 394 | e = rsa->e; | ||
| 340 | 395 | ||
| 341 | BN_CTX_start(ctx); | 396 | |
| 342 | A = BN_CTX_get(ctx); | ||
| 343 | if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) | 397 | if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) |
| 344 | { | 398 | { |
| 345 | /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */ | 399 | /* if PRNG is not properly seeded, resort to secret |
| 346 | RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0); | 400 | * exponent as unpredictable seed */ |
| 347 | if (!BN_pseudo_rand_range(A,rsa->n)) goto err; | 401 | RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0); |
| 348 | } | 402 | } |
| 349 | else | 403 | |
| 404 | if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) | ||
| 350 | { | 405 | { |
| 351 | if (!BN_rand_range(A,rsa->n)) goto err; | 406 | /* Set BN_FLG_CONSTTIME flag */ |
| 407 | n = &local_n; | ||
| 408 | BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); | ||
| 352 | } | 409 | } |
| 353 | if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; | 410 | else |
| 411 | n = rsa->n; | ||
| 354 | 412 | ||
| 355 | if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) | 413 | ret = BN_BLINDING_create_param(NULL, e, n, ctx, |
| 414 | rsa->meth->bn_mod_exp, rsa->_method_mod_n); | ||
| 415 | if (ret == NULL) | ||
| 416 | { | ||
| 417 | RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); | ||
| 356 | goto err; | 418 | goto err; |
| 357 | if ((rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n)) == NULL) goto err; | 419 | } |
| 358 | /* to make things thread-safe without excessive locking, | 420 | BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id()); |
| 359 | * rsa->blinding will be used just by the current thread: */ | ||
| 360 | rsa->blinding->thread_id = CRYPTO_thread_id(); | ||
| 361 | rsa->flags |= RSA_FLAG_BLINDING; | ||
| 362 | rsa->flags &= ~RSA_FLAG_NO_BLINDING; | ||
| 363 | ret=1; | ||
| 364 | err: | 421 | err: |
| 365 | if (Ai != NULL) BN_free(Ai); | ||
| 366 | BN_CTX_end(ctx); | 422 | BN_CTX_end(ctx); |
| 367 | if (ctx != p_ctx) BN_CTX_free(ctx); | 423 | if (in_ctx == NULL) |
| 368 | return(ret); | 424 | BN_CTX_free(ctx); |
| 369 | } | 425 | if(rsa->e == NULL) |
| 426 | BN_free(e); | ||
| 427 | |||
| 428 | return ret; | ||
| 429 | } | ||
| 370 | 430 | ||
| 371 | int RSA_memory_lock(RSA *r) | 431 | int RSA_memory_lock(RSA *r) |
| 372 | { | 432 | { |
| @@ -389,7 +449,7 @@ int RSA_memory_lock(RSA *r) | |||
| 389 | j+= (*t[i])->top; | 449 | j+= (*t[i])->top; |
| 390 | if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL) | 450 | if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL) |
| 391 | { | 451 | { |
| 392 | RSAerr(RSA_F_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); | 452 | RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); |
| 393 | return(0); | 453 | return(0); |
| 394 | } | 454 | } |
| 395 | bn=(BIGNUM *)p; | 455 | bn=(BIGNUM *)p; |
