static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f, BIGNUM *r, BN_CTX *ctx) { if (local) return BN_BLINDING_invert_ex(f, NULL, b, ctx); else { int ret; CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); ret = BN_BLINDING_invert_ex(f, r, b, ctx); CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); return ret; } }
static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, BN_CTX *ctx) { /* For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex * will use the unblinding factor stored in BN_BLINDING. * If BN_BLINDING is shared between threads, unblind must be non-null: * BN_BLINDING_invert_ex will then use the local unblinding factor, * and will only read the modulus from BN_BLINDING. * In both cases it's safe to access the blinding without a lock. */ return BN_BLINDING_invert_ex(f, unblind, b, ctx); }
int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) { return BN_BLINDING_invert_ex(n, NULL, b, ctx); }
int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { BIGNUM *f, *result; BN_CTX *ctx = NULL; unsigned blinding_index = 0; BN_BLINDING *blinding = NULL; int ret = 0; ctx = BN_CTX_new(); if (ctx == NULL) { goto err; } BN_CTX_start(ctx); f = BN_CTX_get(ctx); result = BN_CTX_get(ctx); if (f == NULL || result == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } if (BN_bin2bn(in, len, f) == NULL) { goto err; } if (BN_ucmp(f, rsa->n) >= 0) { /* Usually the padding functions would catch this. */ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_blinding_get(rsa, &blinding_index, ctx); if (blinding == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) { goto err; } } if ((rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->mod_exp(result, f, rsa, ctx)) { goto err; } } else { BIGNUM local_d; BIGNUM *d = NULL; BN_init(&local_d); d = &local_d; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) { if (BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) == NULL) { goto err; } } if (!rsa->meth->bn_mod_exp(result, f, d, rsa->n, ctx, rsa->mont_n)) { goto err; } } if (blinding) { if (!BN_BLINDING_invert_ex(result, NULL, blinding, ctx)) { goto err; } } if (!BN_bn2bin_padded(out, len, result)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); goto err; } ret = 1; err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (blinding != NULL) { rsa_blinding_release(rsa, blinding, blinding_index); } return ret; }