Merge pull request #1077 from daverodgman/better-ct-2.28

2.28 backport - Use CT module more consistently
This commit is contained in:
Dave Rodgman 2023-09-25 11:50:16 +01:00 committed by GitHub
commit 0ab94d1239
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 61 additions and 56 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) {
ret = -(int) mbedtls_ct_uint_if(padlen & ~7, -MBEDTLS_ERR_CIPHER_AUTH_FAILED, -ret);
padlen &= 7;
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
}
/* 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

@ -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) */