1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-08-01 10:06:53 +03:00

Merge branch 'mbedtls-2.28-restricted' into mbedtls-2.28.5rc0-pr

Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
This commit is contained in:
Minos Galanakis
2023-10-03 22:22:36 +01:00
29 changed files with 2151 additions and 1343 deletions

View File

@ -33,6 +33,7 @@
#include "mbedtls/ccm.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "mbedtls/constant_time.h"
#include <string.h>
@ -362,7 +363,6 @@ int mbedtls_ccm_star_auth_decrypt(mbedtls_ccm_context *ctx, size_t length,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
unsigned char i;
int diff;
CCM_VALIDATE_RET(ctx != NULL);
@ -379,9 +379,7 @@ int mbedtls_ccm_star_auth_decrypt(mbedtls_ccm_context *ctx, size_t length,
}
/* Check tag in "constant-time" */
for (diff = 0, i = 0; i < tag_len; i++) {
diff |= tag[i] ^ check_tag[i];
}
diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
if (diff != 0) {
mbedtls_platform_zeroize(output, length);

View File

@ -25,6 +25,7 @@
#include "mbedtls/chachapoly.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "mbedtls/constant_time.h"
#include <string.h>
@ -337,7 +338,6 @@ int mbedtls_chachapoly_auth_decrypt(mbedtls_chachapoly_context *ctx,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
size_t i;
int diff;
CHACHAPOLY_VALIDATE_RET(ctx != NULL);
CHACHAPOLY_VALIDATE_RET(nonce != NULL);
@ -353,9 +353,7 @@ int mbedtls_chachapoly_auth_decrypt(mbedtls_chachapoly_context *ctx,
}
/* Check tag in "constant-time" */
for (diff = 0, i = 0; i < sizeof(check_tag); i++) {
diff |= tag[i] ^ check_tag[i];
}
diff = mbedtls_ct_memcmp(tag, check_tag, sizeof(check_tag));
if (diff != 0) {
mbedtls_platform_zeroize(output, length);

View File

@ -30,6 +30,7 @@
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "mbedtls/constant_time.h"
#include "constant_time_internal.h"
#include <stdlib.h>
#include <string.h>
@ -748,17 +749,17 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len,
*data_len = input_len - padding_len;
/* Avoid logical || since it results in a branch */
bad |= padding_len > input_len;
bad |= padding_len == 0;
bad |= ~mbedtls_ct_size_mask_ge(input_len, padding_len);
bad |= mbedtls_ct_size_bool_eq(padding_len, 0);
/* The number of bytes checked must be independent of padding_len,
* so pick input_len, which is usually 8 or 16 (one block) */
pad_idx = input_len - padding_len;
for (i = 0; i < input_len; i++) {
bad |= (input[i] ^ padding_len) * (i >= pad_idx);
size_t mask = mbedtls_ct_size_mask_ge(i, pad_idx);
bad |= (input[i] ^ padding_len) & mask;
}
return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
return -(int) mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0);
}
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
@ -781,24 +782,29 @@ static void add_one_and_zeros_padding(unsigned char *output,
static int get_one_and_zeros_padding(unsigned char *input, size_t input_len,
size_t *data_len)
{
size_t i;
unsigned char done = 0, prev_done, bad;
unsigned int bad = 1;
if (NULL == input || NULL == data_len) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
bad = 0x80;
*data_len = 0;
for (i = input_len; i > 0; i--) {
prev_done = done;
done |= (input[i - 1] != 0);
*data_len |= (i - 1) * (done != prev_done);
bad ^= input[i - 1] * (done != prev_done);
size_t in_padding = ~0;
for (ptrdiff_t i = (ptrdiff_t) (input_len) - 1; i >= 0; i--) {
size_t is_nonzero = mbedtls_ct_uint_mask(input[i]);
size_t hit_first_nonzero = is_nonzero & in_padding;
*data_len = (*data_len & ~hit_first_nonzero) | ((size_t) i & hit_first_nonzero);
bad = mbedtls_ct_uint_if((unsigned int) hit_first_nonzero,
!mbedtls_ct_size_bool_eq(input[i], 0x80), bad);
in_padding = in_padding & ~is_nonzero;
}
return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
return -(int) mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0);
}
#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
@ -832,16 +838,17 @@ static int get_zeros_and_len_padding(unsigned char *input, size_t input_len,
*data_len = input_len - padding_len;
/* Avoid logical || since it results in a branch */
bad |= padding_len > input_len;
bad |= padding_len == 0;
bad |= mbedtls_ct_size_mask_ge(padding_len, input_len + 1);
bad |= mbedtls_ct_size_bool_eq(padding_len, 0);
/* The number of bytes checked must be independent of padding_len */
pad_idx = input_len - padding_len;
for (i = 0; i < input_len - 1; i++) {
bad |= input[i] * (i >= pad_idx);
size_t mask = mbedtls_ct_size_mask_ge(i, pad_idx);
bad |= input[i] & mask;
}
return MBEDTLS_ERR_CIPHER_INVALID_PADDING * (bad != 0);
return -(int) mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0);
}
#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
@ -872,8 +879,9 @@ static int get_zeros_padding(unsigned char *input, size_t input_len,
*data_len = 0;
for (i = input_len; i > 0; i--) {
prev_done = done;
done |= (input[i-1] != 0);
*data_len |= i * (done != prev_done);
done |= !mbedtls_ct_size_bool_eq(input[i-1], 0);
size_t mask = mbedtls_ct_size_mask(done ^ prev_done);
*data_len |= i & mask;
}
return 0;

View File

@ -80,7 +80,8 @@ unsigned mbedtls_ct_uint_mask(unsigned value)
#endif
}
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) || defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || \
defined(MBEDTLS_NIST_KW_C) || defined(MBEDTLS_CIPHER_MODE_CBC)
size_t mbedtls_ct_size_mask(size_t value)
{
@ -96,7 +97,8 @@ size_t mbedtls_ct_size_mask(size_t value)
#endif
}
#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
#endif /* defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) || defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) ||
defined(MBEDTLS_NIST_KW_C) || defined(MBEDTLS_CIPHER_MODE_CBC) */
#if defined(MBEDTLS_BIGNUM_C)
@ -116,7 +118,8 @@ mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask(mbedtls_mpi_uint value)
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || defined(MBEDTLS_NIST_KW_C) || \
defined(MBEDTLS_CIPHER_MODE_CBC)
/** Constant-flow mask generation for "less than" comparison:
* - if \p x < \p y, return all-bits 1, that is (size_t) -1
@ -151,7 +154,8 @@ size_t mbedtls_ct_size_mask_ge(size_t x,
return ~mbedtls_ct_size_mask_lt(x, y);
}
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
#endif /* defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || defined(MBEDTLS_NIST_KW_C) ||
defined(MBEDTLS_CIPHER_MODE_CBC) */
#if defined(MBEDTLS_BASE64_C)

View File

@ -45,7 +45,8 @@
*/
unsigned mbedtls_ct_uint_mask(unsigned value);
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) || defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || \
defined(MBEDTLS_NIST_KW_C) || defined(MBEDTLS_CIPHER_MODE_CBC)
/** Turn a value into a mask:
* - if \p value == 0, return the all-bits 0 mask, aka 0
@ -60,7 +61,8 @@ unsigned mbedtls_ct_uint_mask(unsigned value);
*/
size_t mbedtls_ct_size_mask(size_t value);
#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
#endif /* defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) || defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) ||
defined(MBEDTLS_NIST_KW_C) || defined(MBEDTLS_CIPHER_MODE_CBC) */
#if defined(MBEDTLS_BIGNUM_C)
@ -79,7 +81,8 @@ mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask(mbedtls_mpi_uint value);
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || defined(MBEDTLS_NIST_KW_C) || \
defined(MBEDTLS_CIPHER_MODE_CBC)
/** Constant-flow mask generation for "greater or equal" comparison:
* - if \p x >= \p y, return all-bits 1, that is (size_t) -1
@ -97,7 +100,8 @@ mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask(mbedtls_mpi_uint value);
size_t mbedtls_ct_size_mask_ge(size_t x,
size_t y);
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
#endif /* defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || defined(MBEDTLS_NIST_KW_C) ||
defined(MBEDTLS_CIPHER_MODE_CBC) */
/** Constant-flow boolean "equal" comparison:
* return x == y

View File

@ -35,6 +35,7 @@
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "mbedtls/constant_time.h"
#include <string.h>
@ -478,7 +479,6 @@ int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
size_t i;
int diff;
GCM_VALIDATE_RET(ctx != NULL);
@ -495,9 +495,7 @@ int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
}
/* Check tag in "constant-time" */
for (diff = 0, i = 0; i < tag_len; i++) {
diff |= tag[i] ^ check_tag[i];
}
diff = mbedtls_ct_memcmp(tag, check_tag, tag_len);
if (diff != 0) {
mbedtls_platform_zeroize(output, length);

View File

@ -35,6 +35,7 @@
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "mbedtls/constant_time.h"
#include "constant_time_internal.h"
#include <stdint.h>
#include <string.h>
@ -335,7 +336,7 @@ int mbedtls_nist_kw_unwrap(mbedtls_nist_kw_context *ctx,
int ret = 0;
size_t i, olen;
unsigned char A[KW_SEMIBLOCK_LENGTH];
unsigned char diff, bad_padding = 0;
unsigned char diff;
*out_len = 0;
if (out_size < in_len - KW_SEMIBLOCK_LENGTH) {
@ -420,18 +421,13 @@ int mbedtls_nist_kw_unwrap(mbedtls_nist_kw_context *ctx,
* larger than 8, because of the type wrap around.
*/
padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen;
if (padlen > 7) {
padlen &= 7;
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
}
ret = -(int) mbedtls_ct_uint_if(padlen & ~7, -MBEDTLS_ERR_CIPHER_AUTH_FAILED, -ret);
padlen &= 7;
/* Check padding in "constant-time" */
for (diff = 0, i = 0; i < KW_SEMIBLOCK_LENGTH; i++) {
if (i >= KW_SEMIBLOCK_LENGTH - padlen) {
diff |= output[*out_len - KW_SEMIBLOCK_LENGTH + i];
} else {
bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH + i];
}
size_t mask = mbedtls_ct_size_mask_ge(i, KW_SEMIBLOCK_LENGTH - padlen);
diff |= (unsigned char) (mask & output[*out_len - KW_SEMIBLOCK_LENGTH + i]);
}
if (diff != 0) {
@ -454,7 +450,6 @@ cleanup:
*out_len = 0;
}
mbedtls_platform_zeroize(&bad_padding, sizeof(bad_padding));
mbedtls_platform_zeroize(&diff, sizeof(diff));
mbedtls_platform_zeroize(A, sizeof(A));

View File

@ -172,18 +172,46 @@ exit:
#endif /* MBEDTLS_ARC4_C */
}
#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode,
mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t len,
unsigned char *output, size_t output_size,
size_t *output_len);
#endif
int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t len,
unsigned char *output)
{
size_t output_len = 0;
/* We assume caller of the function is providing a big enough output buffer
* so we pass output_size as SIZE_MAX to pass checks, However, no guarantees
* for the output size actually being correct.
*/
return mbedtls_pkcs12_pbe_ext(pbe_params, mode, cipher_type, md_type,
pwd, pwdlen, data, len, output, SIZE_MAX,
&output_len);
}
int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode,
mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t len,
unsigned char *output, size_t output_size,
size_t *output_len)
{
int ret, keylen = 0;
unsigned char key[32];
unsigned char iv[16];
const mbedtls_cipher_info_t *cipher_info;
mbedtls_cipher_context_t cipher_ctx;
size_t olen = 0;
size_t finish_olen = 0;
unsigned int padlen = 0;
if (pwd == NULL && pwdlen != 0) {
return MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA;
@ -196,6 +224,19 @@ int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
keylen = cipher_info->key_bitlen / 8;
if (mode == MBEDTLS_PKCS12_PBE_DECRYPT) {
if (output_size < len) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
}
if (mode == MBEDTLS_PKCS12_PBE_ENCRYPT) {
padlen = cipher_info->block_size - (len % cipher_info->block_size);
if (output_size < (len + padlen)) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
}
if ((ret = pkcs12_pbe_derive_key_iv(pbe_params, md_type, pwd, pwdlen,
key, keylen,
iv, cipher_info->iv_size)) != 0) {
@ -214,6 +255,25 @@ int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
goto exit;
}
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/* PKCS12 uses CBC with PKCS7 padding */
mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7;
#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
/* For historical reasons, when decrypting, this function works when
* decrypting even when support for PKCS7 padding is disabled. In this
* case, it ignores the padding, and so will never report a
* password mismatch.
*/
if (mode == MBEDTLS_PKCS12_PBE_DECRYPT) {
padding = MBEDTLS_PADDING_NONE;
}
#endif
if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) {
goto exit;
}
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
if ((ret = mbedtls_cipher_set_iv(&cipher_ctx, iv, cipher_info->iv_size)) != 0) {
goto exit;
}
@ -223,14 +283,16 @@ int mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
}
if ((ret = mbedtls_cipher_update(&cipher_ctx, data, len,
output, &olen)) != 0) {
output, output_len)) != 0) {
goto exit;
}
if ((ret = mbedtls_cipher_finish(&cipher_ctx, output + olen, &olen)) != 0) {
if ((ret = mbedtls_cipher_finish(&cipher_ctx, output + (*output_len), &finish_olen)) != 0) {
ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
}
*output_len += finish_olen;
exit:
mbedtls_platform_zeroize(key, sizeof(key));
mbedtls_platform_zeroize(iv, sizeof(iv));

View File

@ -44,6 +44,7 @@
#include "mbedtls/platform.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params,
mbedtls_asn1_buf *salt, int *iterations,
@ -109,10 +110,34 @@ static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params,
return 0;
}
#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
int mbedtls_pkcs5_pbes2_ext(const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t datalen,
unsigned char *output, size_t output_size,
size_t *output_len);
#endif
int mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t datalen,
unsigned char *output)
{
size_t output_len = 0;
/* We assume caller of the function is providing a big enough output buffer
* so we pass output_size as SIZE_MAX to pass checks, However, no guarantees
* for the output size actually being correct.
*/
return mbedtls_pkcs5_pbes2_ext(pbe_params, mode, pwd, pwdlen, data,
datalen, output, SIZE_MAX, &output_len);
}
int mbedtls_pkcs5_pbes2_ext(const mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t datalen,
unsigned char *output, size_t output_size,
size_t *output_len)
{
int ret, iterations = 0, keylen = 0;
unsigned char *p, *end;
@ -120,12 +145,12 @@ int mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
mbedtls_asn1_buf salt;
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
unsigned char key[32], iv[32];
size_t olen = 0;
const mbedtls_md_info_t *md_info;
const mbedtls_cipher_info_t *cipher_info;
mbedtls_md_context_t md_ctx;
mbedtls_cipher_type_t cipher_alg;
mbedtls_cipher_context_t cipher_ctx;
unsigned int padlen = 0;
p = pbe_params->p;
end = p + pbe_params->len;
@ -188,7 +213,21 @@ int mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
return MBEDTLS_ERR_PKCS5_INVALID_FORMAT;
}
if (mode == MBEDTLS_PKCS5_DECRYPT) {
if (output_size < datalen) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
}
if (mode == MBEDTLS_PKCS5_ENCRYPT) {
padlen = cipher_info->block_size - (datalen % cipher_info->block_size);
if (output_size < (datalen + padlen)) {
return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
}
}
mbedtls_md_init(&md_ctx);
mbedtls_cipher_init(&cipher_ctx);
memcpy(iv, enc_scheme_params.p, enc_scheme_params.len);
@ -211,8 +250,28 @@ int mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
goto exit;
}
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
/* PKCS5 uses CBC with PKCS7 padding (which is the same as
* "PKCS5 padding" except that it's typically only called PKCS5
* with 64-bit-block ciphers).
*/
mbedtls_cipher_padding_t padding = MBEDTLS_PADDING_PKCS7;
#if !defined(MBEDTLS_CIPHER_PADDING_PKCS7)
/* For historical reasons, when decrypting, this function works when
* decrypting even when support for PKCS7 padding is disabled. In this
* case, it ignores the padding, and so will never report a
* password mismatch.
*/
if (mode == MBEDTLS_DECRYPT) {
padding = MBEDTLS_PADDING_NONE;
}
#endif
if ((ret = mbedtls_cipher_set_padding_mode(&cipher_ctx, padding)) != 0) {
goto exit;
}
#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
if ((ret = mbedtls_cipher_crypt(&cipher_ctx, iv, enc_scheme_params.len,
data, datalen, output, &olen)) != 0) {
data, datalen, output, output_len)) != 0) {
ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
}

View File

@ -1351,7 +1351,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t ilen, i, pad_len;
unsigned char *p, bad, pad_done;
unsigned char *p, pad_done;
int bad;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
unsigned int hlen;
@ -1439,9 +1440,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
p += hlen; /* Skip seed */
/* Check lHash */
for (i = 0; i < hlen; i++) {
bad |= lhash[i] ^ *p++;
}
bad |= mbedtls_ct_memcmp(lhash, p, hlen);
p += hlen;
/* Get zero-padding len, but always read till end of buffer
* (minus one, for the 01 byte) */

View File

@ -1149,6 +1149,14 @@ int mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl,
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
if (mode == MBEDTLS_MODE_STREAM) {
if (rec->data_len < transform->maclen) {
MBEDTLS_SSL_DEBUG_MSG(1,
("Record too short for MAC:"
" %" MBEDTLS_PRINTF_SIZET " < %" MBEDTLS_PRINTF_SIZET,
rec->data_len, transform->maclen));
return MBEDTLS_ERR_SSL_INVALID_MAC;
}
padlen = 0;
if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_dec,
transform->iv_dec,
@ -1561,7 +1569,7 @@ hmac_failed_etm_enabled:
unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 };
unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 };
/* If the initial value of padlen was such that
/* For CBC+MAC, If the initial value of padlen was such that
* data_len < maclen + padlen + 1, then padlen
* got reset to 1, and the initial check
* data_len >= minlen + maclen + 1
@ -1573,6 +1581,9 @@ hmac_failed_etm_enabled:
* subtracted either padlen + 1 (if the padding was correct)
* or 0 (if the padding was incorrect) since then,
* hence data_len >= maclen in any case.
*
* For stream ciphers, we checked above that
* data_len >= maclen.
*/
rec->data_len -= transform->maclen;
ssl_extract_add_data_from_record(add_data, &add_data_len, rec,