+static BN_BLINDING *setup_blinding(RSA *rsa, BN_CTX *ctx)
+ {
+ 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 */
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
+ {
+ /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */
+ RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0);
+ 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;
+ ret = BN_BLINDING_new(A,Ai,rsa->n);
+ BN_free(Ai);
+err:
+ BN_CTX_end(ctx);
+ return ret;
+ }
+