Skip to content

Commit

Permalink
Fix race in rsa implementation.
Browse files Browse the repository at this point in the history
We should initialize `ctx->RP` and `ctx->RQ`
when we initialize rsa context not during key
signition, because key signition can be called
on different CPUs for one ctx, which lead to race.

Closes #1779, #1892
  • Loading branch information
EvgeniiMekhanik committed Jun 16, 2023
1 parent 9e974c1 commit 74ad2de
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
17 changes: 11 additions & 6 deletions tls/bignum.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@
/* Maximum sliding window size in bits used for modular exponentiation. */
#define MPI_W_SZ 6

void
ttls_mpi_precompute_RR(TlsMpi *X, const TlsMpi *N)
{
ttls_mpi_alloc(X, N->used * 2 + 2);
ttls_mpi_lset(X, 1);
ttls_mpi_shift_l(X, X, N->used * 2 * BIL);
ttls_mpi_mod_mpi(X, X, N);
}

/**
* Allocate an MPI on the stack and initialize it with the required limbs in
* one shot.
Expand Down Expand Up @@ -1228,12 +1237,8 @@ ttls_mpi_exp_mod(TlsMpi *X, const TlsMpi *A, const TlsMpi *E, const TlsMpi *N,
* If 1st call, pre-compute R^2 mod N
*/
BUG_ON(!RR);
if (unlikely(ttls_mpi_empty(RR))) {
ttls_mpi_alloc(RR, N->used * 2 + 2);
ttls_mpi_lset(RR, 1);
ttls_mpi_shift_l(RR, RR, N->used * 2 * BIL);
ttls_mpi_mod_mpi(RR, RR, N);
}
if (unlikely(ttls_mpi_empty(RR)))
ttls_mpi_precompute_RR(RR, N);

/* W[1] = A * R^2 * R^-1 mod N = A * R mod N */
if (ttls_mpi_cmp_mpi(A, N) >= 0)
Expand Down
1 change: 1 addition & 0 deletions tls/bignum.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ int ttls_mpi_exp_mod(TlsMpi *X, const TlsMpi *A, const TlsMpi *E,
const TlsMpi *N, TlsMpi *_RR);
void ttls_mpi_inv_mod(TlsMpi *X, const TlsMpi *A, const TlsMpi *N);
void ttls_mpi_gcd(TlsMpi *G, const TlsMpi *A, const TlsMpi *B);
void ttls_mpi_precompute_RR(TlsMpi *X, const TlsMpi *N);

static inline bool
ttls_mpi_empty(const TlsMpi *X)
Expand Down
22 changes: 19 additions & 3 deletions tls/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,13 @@ ttls_rsa_deduce_private_exponent(TlsMpi const *P, TlsMpi const *Q,
* @DP - Output variable for D modulo P-1;
* @DQ - Output variable for D modulo Q-1;
* @QP - Output variable for the modular inverse of Q modulo P.
* @RP - Output variable for the R^2 modulo P
* @RQ - Output variable for the R^2 modulo Q
*/
int
static int
ttls_rsa_deduce_crt(const TlsMpi *P, const TlsMpi *Q, const TlsMpi *D,
TlsMpi *DP, TlsMpi *DQ, TlsMpi *QP)
TlsMpi *DP, TlsMpi *DQ, TlsMpi *QP,
TlsMpi *RP, TlsMpi *RQ)
{
TlsMpi *K = ttls_mpi_alloc_stack_init(max(P->used, Q->used));

Expand All @@ -435,6 +438,12 @@ ttls_rsa_deduce_crt(const TlsMpi *P, const TlsMpi *Q, const TlsMpi *D,
if (QP)
ttls_mpi_inv_mod(QP, Q, P);

if (RP)
ttls_mpi_precompute_RR(RP, P);

if (RQ)
ttls_mpi_precompute_RR(RQ, Q);

return 0;
}

Expand Down Expand Up @@ -492,6 +501,13 @@ rsa_check_context(const TlsRSACtx *ctx, int is_priv)
return(TTLS_ERR_RSA_BAD_INPUT_DATA);
}

if (is_priv &&
(ttls_mpi_cmp_int(&ctx->RP, 0) <= 0 ||
ttls_mpi_cmp_int(&ctx->RQ, 0) <= 0))
{
return TTLS_ERR_RSA_BAD_INPUT_DATA;
}

/* It wouldn't lead to an error if it wasn't satisfied,
* but check for QP >= 1 nonetheless. */
if (is_priv &&
Expand Down Expand Up @@ -726,7 +742,7 @@ ttls_rsa_complete(TlsRSACtx *ctx)
*/
if (is_priv) {
r = ttls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D, &ctx->DP,
&ctx->DQ, &ctx->QP);
&ctx->DQ, &ctx->QP, &ctx->RP, &ctx->RQ);
if (r)
return TTLS_ERR_RSA_BAD_INPUT_DATA + r;
}
Expand Down

0 comments on commit 74ad2de

Please sign in to comment.