static BN_BLINDING *setup_blinding(RSA *rsa, BN_CTX *ctx) { const RSA_METHOD *meth; BIGNUM *A, *Ai; BN_BLINDING *ret = NULL; /* added in OpenSSL 0.9.6j and 0.9.7b */ /* NB: similar code appears in RSA_blinding_on (rsa_lib.c); * this should be placed in a new function of its own, but for reasons * of binary compatibility can't */ meth = rsa->meth; BN_CTX_start(ctx); A = BN_CTX_get(ctx); if (rsa->d != NULL && rsa->d->d != NULL) { /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */ if (!BN_pseudo_rand_range(A,rsa->n)) goto err; } else { if (!BN_rand_range(A,rsa->n)) goto err; } if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; if (!meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; ret = BN_BLINDING_new(A,Ai,rsa->n); BN_free(Ai); err: BN_CTX_end(ctx); return ret; }
int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx) { BIGNUM *A,*Ai; BN_CTX *ctx; int ret=0; if (p_ctx == NULL) { if ((ctx=BN_CTX_new()) == NULL) goto err; } else ctx=p_ctx; RSA_free_thread_blinding_ptr(rsa); BN_CTX_start(ctx); A = BN_CTX_get(ctx); if (!BN_rand(A,BN_num_bits(rsa->n)-1,1,0)) goto err; if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; RSA_set_thread_blinding_ptr(rsa, BN_BLINDING_new(A,Ai,rsa->n)); rsa->flags|=RSA_FLAG_BLINDING; BN_free(Ai); ret=1; err: BN_CTX_end(ctx); if (ctx != p_ctx) BN_CTX_free(ctx); return(ret); }
int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx) { BIGNUM *A,*Ai = NULL; BN_CTX *ctx; int ret=0; if (p_ctx == NULL) { if ((ctx=BN_CTX_new()) == NULL) goto err; } else ctx=p_ctx; /* XXXXX: Shouldn't this be RSA_blinding_off(rsa)? */ if (rsa->blinding != NULL) { BN_BLINDING_free(rsa->blinding); rsa->blinding = NULL; } /* NB: similar code appears in setup_blinding (rsa_eay.c); * this should be placed in a new function of its own, but for reasons * of binary compatibility can't */ BN_CTX_start(ctx); A = BN_CTX_get(ctx); if (rsa->d != NULL && rsa->d->d != NULL) { if (!BN_pseudo_rand_range(A,rsa->n)) goto err; } else { if (!BN_rand_range(A,rsa->n)) goto err; } if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; if (!rsa->meth->bn_mod_exp(A,A, rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; if ((rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n)) == NULL) goto err; /* to make things thread-safe without excessive locking, * rsa->blinding will be used just by the current thread: */ rsa->flags |= RSA_FLAG_BLINDING; rsa->flags &= ~RSA_FLAG_NO_BLINDING; ret=1; err: if (Ai != NULL) BN_free(Ai); BN_CTX_end(ctx); if (ctx != p_ctx) BN_CTX_free(ctx); return(ret); }
BN_BLINDING *BN_BLINDING_create_param( BN_BLINDING *b, const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont), const BN_MONT_CTX *mont) { int retry_counter = 32; BN_BLINDING *ret = NULL; if (b == NULL) { ret = BN_BLINDING_new(NULL, NULL, m); } else { ret = b; } if (ret == NULL) { goto err; } if (ret->A == NULL && (ret->A = BN_new()) == NULL) { goto err; } if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) { goto err; } if (e != NULL) { BN_free(ret->e); ret->e = BN_dup(e); } if (ret->e == NULL) { goto err; } if (bn_mod_exp != NULL) { ret->bn_mod_exp = bn_mod_exp; } if (mont != NULL) { ret->mont = mont; } do { if (!BN_rand_range(ret->A, ret->mod)) { goto err; } int no_inverse; if (BN_mod_inverse_ex(ret->Ai, &no_inverse, ret->A, ret->mod, ctx) == NULL) { /* this should almost never happen for good RSA keys */ if (no_inverse) { if (retry_counter-- == 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS); goto err; } ERR_clear_error(); } else { goto err; } } else { break; } } while (1); if (ret->bn_mod_exp != NULL && ret->mont != NULL) { if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->mont)) { goto err; } } else { if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) { goto err; } } return ret; err: if (b == NULL) { BN_BLINDING_free(ret); ret = NULL; } return ret; }
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx) { int retry_counter = 32; BN_BLINDING *ret = NULL; if (b == NULL) ret = BN_BLINDING_new(NULL, NULL, m); else ret = b; if (ret == NULL) goto err; if (ret->A == NULL && (ret->A = BN_new()) == NULL) goto err; if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) goto err; if (e != NULL) { if (ret->e != NULL) BN_free(ret->e); ret->e = BN_dup(e); } if (ret->e == NULL) goto err; if (bn_mod_exp != NULL) ret->bn_mod_exp = bn_mod_exp; if (m_ctx != NULL) ret->m_ctx = m_ctx; do { if (!BN_rand_range(ret->A, ret->mod)) goto err; if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) { /* * this should almost never happen for good RSA keys */ unsigned long error = ERR_peek_last_error(); if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) { if (retry_counter-- == 0) { BNerr(BN_F_BN_BLINDING_CREATE_PARAM, BN_R_TOO_MANY_ITERATIONS); goto err; } ERR_clear_error(); } else goto err; } else break; } while (1); if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { if (!ret->bn_mod_exp (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) goto err; } else { if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) goto err; } return ret; err: if (b == NULL && ret != NULL) { BN_BLINDING_free(ret); ret = NULL; } return ret; }
/* rsa_blinding_get returns a BN_BLINDING to use with |rsa|. It does this by * allocating one of the cached BN_BLINDING objects in |rsa->blindings|. If * none are free, the cache will be extended by a extra element and the new * BN_BLINDING is returned. * * On success, the index of the assigned BN_BLINDING is written to * |*index_used| and must be passed to |rsa_blinding_release| when finished. */ static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, BN_CTX *ctx) { assert(ctx != NULL); assert(rsa->mont_n != NULL); BN_BLINDING *ret = NULL; BN_BLINDING **new_blindings; uint8_t *new_blindings_inuse; char overflow = 0; CRYPTO_MUTEX_lock_write(&rsa->lock); unsigned i; for (i = 0; i < rsa->num_blindings; i++) { if (rsa->blindings_inuse[i] == 0) { rsa->blindings_inuse[i] = 1; ret = rsa->blindings[i]; *index_used = i; break; } } if (ret != NULL) { CRYPTO_MUTEX_unlock_write(&rsa->lock); return ret; } overflow = rsa->num_blindings >= MAX_BLINDINGS_PER_RSA; /* We didn't find a free BN_BLINDING to use so increase the length of * the arrays by one and use the newly created element. */ CRYPTO_MUTEX_unlock_write(&rsa->lock); ret = BN_BLINDING_new(); if (ret == NULL) { return NULL; } if (overflow) { /* We cannot add any more cached BN_BLINDINGs so we use |ret| * and mark it for destruction in |rsa_blinding_release|. */ *index_used = MAX_BLINDINGS_PER_RSA; return ret; } CRYPTO_MUTEX_lock_write(&rsa->lock); new_blindings = OPENSSL_malloc(sizeof(BN_BLINDING *) * (rsa->num_blindings + 1)); if (new_blindings == NULL) { goto err1; } memcpy(new_blindings, rsa->blindings, sizeof(BN_BLINDING *) * rsa->num_blindings); new_blindings[rsa->num_blindings] = ret; new_blindings_inuse = OPENSSL_malloc(rsa->num_blindings + 1); if (new_blindings_inuse == NULL) { goto err2; } memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings); new_blindings_inuse[rsa->num_blindings] = 1; *index_used = rsa->num_blindings; OPENSSL_free(rsa->blindings); rsa->blindings = new_blindings; OPENSSL_free(rsa->blindings_inuse); rsa->blindings_inuse = new_blindings_inuse; rsa->num_blindings++; CRYPTO_MUTEX_unlock_write(&rsa->lock); return ret; err2: OPENSSL_free(new_blindings); err1: CRYPTO_MUTEX_unlock_write(&rsa->lock); BN_BLINDING_free(ret); return NULL; }