Upstream-Status: Backport Signed-off-by: yzhu1 --- a/nss/lib/ssl/ssl3con.c +++ b/nss/lib/ssl/ssl3con.c @@ -10509,7 +10509,7 @@ ssl_RemoveSSLv3CBCPadding(sslBuffer *pla /* SSLv3 padding bytes are random and cannot be checked. */ t = plaintext->len; t -= paddingLength+overhead; - /* If len >= padding_length+overhead then the MSB of t is zero. */ + /* If len >= paddingLength+overhead then the MSB of t is zero. */ good = DUPLICATE_MSB_TO_ALL(~t); /* SSLv3 requires that the padding is minimal. */ t = blockSize - (paddingLength+1); @@ -10742,7 +10742,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip } } - good = (unsigned)-1; + good = ~0U; minLength = crSpec->mac_size; if (cipher_def->type == type_block) { /* CBC records have a padding length byte at the end. */ @@ -10756,14 +10756,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip /* We can perform this test in variable time because the record's total * length and the ciphersuite are both public knowledge. */ if (cText->buf->len < minLength) { - SSL_DBG(("%d: SSL3[%d]: HandleRecord, record too small.", - SSL_GETPID(), ss->fd)); - /* must not hold spec lock when calling SSL3_SendAlert. */ - ssl_ReleaseSpecReadLock(ss); - SSL3_SendAlert(ss, alert_fatal, bad_record_mac); - /* always log mac error, in case attacker can read server logs. */ - PORT_SetError(SSL_ERROR_BAD_MAC_READ); - return SECFailure; + goto decrypt_loser; } if (cipher_def->type == type_block && @@ -10831,11 +10824,18 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip return SECFailure; } + if (cipher_def->type == type_block && + ((cText->buf->len - ivLen) % cipher_def->block_size) != 0) { + goto decrypt_loser; + } + /* decrypt from cText buf to plaintext. */ rv = crSpec->decode( crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len, plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen); - good &= SECStatusToMask(rv); + if (rv != SECSuccess) { + goto decrypt_loser; + } PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len)); @@ -10843,7 +10843,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip /* If it's a block cipher, check and strip the padding. */ if (cipher_def->type == type_block) { - const unsigned int blockSize = cipher_def->iv_size; + const unsigned int blockSize = cipher_def->block_size; const unsigned int macSize = crSpec->mac_size; if (crSpec->version <= SSL_LIBRARY_VERSION_3_0) { @@ -10899,10 +10899,11 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip } if (good == 0) { +decrypt_loser: /* must not hold spec lock when calling SSL3_SendAlert. */ ssl_ReleaseSpecReadLock(ss); - SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd)); + SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd)); if (!IS_DTLS(ss)) { SSL3_SendAlert(ss, alert_fatal, bad_record_mac);