Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/rsa/blinding.c')
-rw-r--r--crypto/rsa/blinding.c299
1 files changed, 72 insertions, 227 deletions
diff --git a/crypto/rsa/blinding.c b/crypto/rsa/blinding.c
index e6b987d9..d9d90c2b 100644
--- a/crypto/rsa/blinding.c
+++ b/crypto/rsa/blinding.c
@@ -120,53 +120,35 @@
#define BN_BLINDING_COUNTER 32
struct bn_blinding_st {
- BIGNUM *A;
- BIGNUM *Ai;
- BIGNUM *e;
- BIGNUM *mod;
- int counter;
- /* mont is the Montgomery context used for this |BN_BLINDING|. It is not
- * owned and must outlive this structure. */
- const BN_MONT_CTX *mont;
- int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont);
+ BIGNUM *A; /* The base blinding factor, Montgomery-encoded. */
+ BIGNUM *Ai; /* The inverse of the blinding factor, Montgomery-encoded. */
+ unsigned counter;
};
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) {
- BN_BLINDING *ret = NULL;
+static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont, BN_CTX *ctx);
- ret = (BN_BLINDING*) OPENSSL_malloc(sizeof(BN_BLINDING));
+BN_BLINDING *BN_BLINDING_new(void) {
+ BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING));
if (ret == NULL) {
OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(BN_BLINDING));
- if (A != NULL) {
- ret->A = BN_dup(A);
- if (ret->A == NULL) {
- goto err;
- }
- }
- if (Ai != NULL) {
- ret->Ai = BN_dup(Ai);
- if (ret->Ai == NULL) {
- goto err;
- }
- }
- /* save a copy of mod in the BN_BLINDING structure */
- ret->mod = BN_dup(mod);
- if (ret->mod == NULL) {
+ ret->A = BN_new();
+ if (ret->A == NULL) {
goto err;
}
- if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) {
- BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
+ ret->Ai = BN_new();
+ if (ret->Ai == NULL) {
+ goto err;
}
- /* Set the counter to the special value -1
- * to indicate that this is never-used fresh blinding
- * that does not need updating before first use. */
- ret->counter = -1;
+ /* The blinding values need to be created before this blinding can be used. */
+ ret->counter = BN_BLINDING_COUNTER - 1;
+
return ret;
err:
@@ -181,242 +163,105 @@ void BN_BLINDING_free(BN_BLINDING *r) {
BN_free(r->A);
BN_free(r->Ai);
- BN_free(r->e);
- BN_free(r->mod);
OPENSSL_free(r);
}
-int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) {
- int ret = 0;
-
- if (b->A == NULL || b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
- goto err;
- }
-
- if (b->counter == -1) {
- b->counter = 0;
- }
-
- if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL) {
+static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont, BN_CTX *ctx) {
+ if (++b->counter == BN_BLINDING_COUNTER) {
/* re-create blinding parameters */
- if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) {
+ if (!bn_blinding_create_param(b, e, mont, ctx)) {
goto err;
}
+ b->counter = 0;
} else {
- if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) {
- goto err;
- }
- if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx)) {
+ if (!BN_mod_mul_montgomery(b->A, b->A, b->A, mont, ctx) ||
+ !BN_mod_mul_montgomery(b->Ai, b->Ai, b->Ai, mont, ctx)) {
goto err;
}
}
- ret = 1;
+ return 1;
err:
- if (b->counter == BN_BLINDING_COUNTER) {
- b->counter = 0;
- }
- return ret;
-}
-
-int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) {
- int ret = 1;
+ /* |A| and |Ai| may be in an inconsistent state so they both need to be
+ * replaced the next time this blinding is used. Note that this is only
+ * sufficient because support for |BN_BLINDING_NO_UPDATE| and
+ * |BN_BLINDING_NO_RECREATE| was previously dropped. */
+ b->counter = BN_BLINDING_COUNTER - 1;
- if (b->A == NULL || b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
- return 0;
- }
+ return 0;
+}
- if (b->counter == -1) {
- /* Fresh blinding, doesn't need updating. */
- b->counter = 0;
- } else if (!BN_BLINDING_update(b, ctx)) {
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont, BN_CTX *ctx) {
+ /* |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
+ * cancels one Montgomery factor, so the resulting value of |n| is unencoded.
+ */
+ if (!bn_blinding_update(b, e, mont, ctx) ||
+ !BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) {
return 0;
}
- if (!BN_mod_mul(n, n, b->A, b->mod, ctx)) {
- ret = 0;
- }
-
- return ret;
+ return 1;
}
-int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_CTX *ctx) {
- if (b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
- return 0;
- }
- return BN_mod_mul(n, n, b->Ai, b->mod, ctx);
+int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont,
+ BN_CTX *ctx) {
+ /* |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
+ * cancels one Montgomery factor, so the resulting value of |n| is unencoded.
+ */
+ return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx);
}
-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) {
+static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
+ const BN_MONT_CTX *mont, BN_CTX *ctx) {
+ BIGNUM mont_N_consttime;
+ BN_init(&mont_N_consttime);
+ BN_with_flags(&mont_N_consttime, &mont->N, BN_FLG_CONSTTIME);
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;
+ if (!BN_rand_range(b->A, &mont->N)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ /* |BN_from_montgomery| + |BN_mod_inverse_no_branch| is equivalent to, but
+ * more efficient than, |BN_mod_inverse_no_branch| + |BN_to_montgomery|. */
+ if (!BN_from_montgomery(b->Ai, b->A, mont, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
int no_inverse;
- if (BN_mod_inverse_ex(ret->Ai, &no_inverse, ret->A, ret->mod, ctx) == NULL) {
+ if (BN_mod_inverse_ex(b->Ai, &no_inverse, b->Ai, &mont_N_consttime, 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;
+ return 0;
}
ERR_clear_error();
} else {
- goto err;
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
} 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;
-}
-
-static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
- const BIGNUM *q, BN_CTX *ctx) {
- BIGNUM *ret = NULL, *r0, *r1, *r2;
-
- if (d == NULL || p == NULL || q == NULL) {
- return NULL;
- }
-
- BN_CTX_start(ctx);
- r0 = BN_CTX_get(ctx);
- r1 = BN_CTX_get(ctx);
- r2 = BN_CTX_get(ctx);
- if (r2 == NULL) {
- goto err;
- }
-
- if (!BN_sub(r1, p, BN_value_one())) {
- goto err;
- }
- if (!BN_sub(r2, q, BN_value_one())) {
- goto err;
- }
- if (!BN_mul(r0, r1, r2, ctx)) {
- goto err;
- }
-
- ret = BN_mod_inverse(NULL, d, r0, ctx);
-
-err:
- BN_CTX_end(ctx);
- return ret;
-}
-
-BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) {
- BIGNUM local_n;
- BIGNUM *e, *n;
- BN_CTX *ctx;
- BN_BLINDING *ret = NULL;
- BN_MONT_CTX *mont_ctx = NULL;
-
- if (in_ctx == NULL) {
- ctx = BN_CTX_new();
- if (ctx == NULL) {
- return 0;
- }
- } else {
- ctx = in_ctx;
- }
-
- if (rsa->e == NULL) {
- e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
- if (e == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
- goto err;
- }
- } else {
- e = rsa->e;
- }
-
- n = &local_n;
- BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
-
- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) {
- mont_ctx = BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx);
- if (mont_ctx == NULL) {
- goto err;
- }
- }
-
- ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp,
- mont_ctx);
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
- goto err;
+ if (!BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
-err:
- if (in_ctx == NULL) {
- BN_CTX_free(ctx);
- }
- if (rsa->e == NULL) {
- BN_free(e);
+ if (!BN_to_montgomery(b->A, b->A, mont, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
- return ret;
+ return 1;
}