Skip to content

Commit 145255e

Browse files
committed
Add RSA TLS implicit rejection
1 parent 81fd36c commit 145255e

1 file changed

Lines changed: 36 additions & 20 deletions

File tree

src/wp_rsa_asym.c

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -466,28 +466,44 @@ static int wp_rsaa_decrypt(wp_RsaAsymCtx* ctx, unsigned char* out,
466466
if (ok) {
467467
byte mask;
468468
byte negMask;
469-
470-
XMEMSET(out, 0, outSize);
471-
PRIVATE_KEY_UNLOCK();
472-
rc = wc_RsaPrivateDecrypt(in, (word32)inLen, out,
473-
(word32)outSize, wp_rsa_get_key(ctx->rsa));
474-
PRIVATE_KEY_LOCK();
475-
476-
/* Constant time checking of master secret. */
477-
mask = wp_ct_byte_mask_eq(out[0], ctx->clientVersion >> 8);
478-
mask &= wp_ct_byte_mask_eq(out[1], ctx->clientVersion);
479-
if (ctx->negVersion > 0) {
480-
/* Check for negotiated version as well. */
481-
negMask = wp_ct_byte_mask_eq(out[0], ctx->negVersion >> 8);
482-
negMask &= wp_ct_byte_mask_eq(out[1], ctx->negVersion);
483-
mask |= negMask;
484-
}
485-
rc &= (int)(char)mask;
486-
487-
if (rc <= 0) {
488-
WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_RsaPrivateDecrypt TLS padding", rc);
469+
byte rand[WOLFSSL_MAX_MASTER_KEY_LENGTH];
470+
int i;
471+
472+
/* Implicit rejection: always generate random fallback
473+
* to prevent Bleichenbacher-style oracle attacks. */
474+
rc = wc_RNG_GenerateBlock(&ctx->rng, rand,
475+
WOLFSSL_MAX_MASTER_KEY_LENGTH);
476+
if (rc != 0) {
489477
ok = 0;
490478
}
479+
if (ok) {
480+
XMEMSET(out, 0, outSize);
481+
PRIVATE_KEY_UNLOCK();
482+
rc = wc_RsaPrivateDecrypt(in, (word32)inLen, out,
483+
(word32)outSize, wp_rsa_get_key(ctx->rsa));
484+
PRIVATE_KEY_LOCK();
485+
486+
/* Constant time checking of master secret. */
487+
mask = wp_ct_byte_mask_eq(out[0],
488+
ctx->clientVersion >> 8);
489+
mask &= wp_ct_byte_mask_eq(out[1], ctx->clientVersion);
490+
if (ctx->negVersion > 0) {
491+
negMask = wp_ct_byte_mask_eq(out[0],
492+
ctx->negVersion >> 8);
493+
negMask &= wp_ct_byte_mask_eq(out[1],
494+
ctx->negVersion);
495+
mask |= negMask;
496+
}
497+
/* Combine decrypt success with version check. */
498+
mask &= wp_ct_int_mask_gte(rc, 1);
499+
500+
/* Constant-time select: real result or random fallback. */
501+
for (i = 0; i < WOLFSSL_MAX_MASTER_KEY_LENGTH; i++) {
502+
out[i] = wp_ct_byte_mask_sel(mask, out[i], rand[i]);
503+
}
504+
OPENSSL_cleanse(rand, sizeof(rand));
505+
rc = WOLFSSL_MAX_MASTER_KEY_LENGTH;
506+
}
491507
}
492508
}
493509
else if (ctx->padMode == RSA_NO_PADDING) {

0 commit comments

Comments
 (0)