From c280520999caa75ae40bb0391a5ec7b5a10cd5de Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 11 Sep 2023 18:25:16 +0100 Subject: [PATCH 01/13] Eliminate duplicate ct memcmp Signed-off-by: Dave Rodgman --- library/ccm.c | 6 ++---- library/chachapoly.c | 6 ++---- library/gcm.c | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/library/ccm.c b/library/ccm.c index 2d2695e97..79a04a275 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -33,6 +33,7 @@ #include "mbedtls/ccm.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" +#include "mbedtls/constant_time.h" #include @@ -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); diff --git a/library/chachapoly.c b/library/chachapoly.c index ceb429287..547ffb2ed 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -25,6 +25,7 @@ #include "mbedtls/chachapoly.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" +#include "mbedtls/constant_time.h" #include @@ -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); diff --git a/library/gcm.c b/library/gcm.c index 0c958c729..71e7b2e9b 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -35,6 +35,7 @@ #include "mbedtls/platform.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" +#include "mbedtls/constant_time.h" #include @@ -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); From 954a2da1e49fdf8e3c0fdb9cac28727e6ee46a3a Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 14:10:35 +0100 Subject: [PATCH 02/13] Use mbedtls_ct_memcmp in mbedtls_rsa_rsaes_oaep_decrypt Signed-off-by: Dave Rodgman --- library/rsa.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index f44b2c38b..01d0eb09d 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -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) */ From 40dc3b3727a9b8036832b13c811782a84ac9b751 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 14:23:29 +0100 Subject: [PATCH 03/13] CT fixes in nist_kw Signed-off-by: Dave Rodgman --- library/nist_kw.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/library/nist_kw.c b/library/nist_kw.c index 5817bf4f4..c7fb09391 100644 --- a/library/nist_kw.c +++ b/library/nist_kw.c @@ -35,6 +35,7 @@ #include "mbedtls/platform_util.h" #include "mbedtls/error.h" #include "mbedtls/constant_time.h" +#include "constant_time_internal.h" #include #include @@ -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)); From 9f3f73d212c8be36de67168e89460336e91c1abb Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 14:29:45 +0100 Subject: [PATCH 04/13] CT fix for get_pkcs_padding Signed-off-by: Dave Rodgman --- library/cipher.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index 4b715d489..6d7cb0a41 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -30,6 +30,7 @@ #include "mbedtls/platform_util.h" #include "mbedtls/error.h" #include "mbedtls/constant_time.h" +#include "constant_time_internal.h" #include #include @@ -755,10 +756,10 @@ static int get_pkcs_padding(unsigned char *input, size_t input_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 */ From df254f6bb6d4c56aadfb16768458f5bc5fcda82f Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 14:46:12 +0100 Subject: [PATCH 05/13] CT fix for get_one_and_zeros_padding Signed-off-by: Dave Rodgman --- library/cipher.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index 6d7cb0a41..90145a587 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -782,24 +782,28 @@ 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(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 */ From 51773aa68b497d7f3411e8370803927b4e997b3b Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 14:51:21 +0100 Subject: [PATCH 06/13] CT fix for get_zeros_and_len_padding Signed-off-by: Dave Rodgman --- library/cipher.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index 90145a587..6853fb82b 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -837,16 +837,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); + unsigned int 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 */ From c1a17f5458d283aea82aef5f5e2353bc37eed060 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 14:54:29 +0100 Subject: [PATCH 07/13] CT fix for get_zeros_padding Signed-off-by: Dave Rodgman --- library/cipher.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/cipher.c b/library/cipher.c index 6853fb82b..5470dcfac 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -879,7 +879,8 @@ static int get_zeros_padding(unsigned char *input, size_t input_len, for (i = input_len; i > 0; i--) { prev_done = done; done |= (input[i-1] != 0); - *data_len |= i * (done != prev_done); + size_t mask = mbedtls_ct_size_mask(done ^ prev_done); + *data_len |= i & mask; } return 0; From 1d52368e85f534816ae13cc37aa7970acde1b303 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 16:26:49 +0100 Subject: [PATCH 08/13] build fixes Signed-off-by: Dave Rodgman --- library/cipher.c | 5 +++-- library/constant_time.c | 6 ++++-- library/constant_time_internal.h | 6 ++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index 5470dcfac..2fba75834 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -798,7 +798,8 @@ static int get_one_and_zeros_padding(unsigned char *input, size_t input_len, *data_len = (*data_len & ~hit_first_nonzero) | ((size_t) i & hit_first_nonzero); - bad = mbedtls_ct_uint_if(hit_first_nonzero, !mbedtls_ct_size_bool_eq(input[i], 0x80), bad); + 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; } @@ -843,7 +844,7 @@ static int get_zeros_and_len_padding(unsigned char *input, size_t input_len, /* 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++) { - unsigned int mask = mbedtls_ct_size_mask_ge(i, pad_idx); + size_t mask = mbedtls_ct_size_mask_ge(i, pad_idx); bad |= input[i] & mask; } diff --git a/library/constant_time.c b/library/constant_time.c index c0f53bbe7..2a9f67426 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -116,7 +116,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_WITH_PADDING) /** Constant-flow mask generation for "less than" comparison: * - if \p x < \p y, return all-bits 1, that is (size_t) -1 @@ -151,7 +152,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_WITH_PADDING) */ #if defined(MBEDTLS_BASE64_C) diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index 402cf148b..9d93733bc 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -79,7 +79,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_WITH_PADDING) /** 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 +98,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_WITH_PADDING) */ /** Constant-flow boolean "equal" comparison: * return x == y From 1924adbf99473fc04bd2dc6273b80259d520b078 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 17:22:00 +0100 Subject: [PATCH 09/13] Fix macro guards for mbedtls_ct_size_mask Signed-off-by: Dave Rodgman --- library/constant_time.c | 10 ++++++---- library/constant_time_internal.h | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index 2a9f67426..2307ed53b 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -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) @@ -117,7 +119,7 @@ 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) || defined(MBEDTLS_NIST_KW_C) || \ - defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + 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 @@ -153,7 +155,7 @@ size_t mbedtls_ct_size_mask_ge(size_t x, } #endif /* defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || defined(MBEDTLS_NIST_KW_C) || - defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) */ + defined(MBEDTLS_CIPHER_MODE_CBC) */ #if defined(MBEDTLS_BASE64_C) diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index 9d93733bc..5b6223d65 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -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_WITH_PADDING) /** 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_WITH_PADDING) */ #if defined(MBEDTLS_BIGNUM_C) @@ -80,7 +82,7 @@ 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) || defined(MBEDTLS_NIST_KW_C) || \ - defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + 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 @@ -99,7 +101,7 @@ size_t mbedtls_ct_size_mask_ge(size_t x, size_t y); #endif /* defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || defined(MBEDTLS_NIST_KW_C) || - defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) */ + defined(MBEDTLS_CIPHER_MODE_CBC) */ /** Constant-flow boolean "equal" comparison: * return x == y From e0ad9a4707e5ad64c34a4c6c288ada0252377e5f Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 19:23:58 +0100 Subject: [PATCH 10/13] Misc CT robustness improvements Signed-off-by: Dave Rodgman --- library/cipher.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index 2fba75834..e5598de42 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -749,8 +749,8 @@ 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) */ @@ -879,7 +879,7 @@ 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); + done |= !mbedtls_ct_size_bool_eq(input[i-1], 0); size_t mask = mbedtls_ct_size_mask(done ^ prev_done); *data_len |= i & mask; } From caa942569f5ed054f77f36b5d0130daeee36d91c Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 19:24:14 +0100 Subject: [PATCH 11/13] Improve return value handling Signed-off-by: Dave Rodgman --- library/cipher.c | 6 +++--- library/nist_kw.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index e5598de42..06199919a 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -759,7 +759,7 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len, size_t mask = mbedtls_ct_size_mask_ge(i, pad_idx); bad |= (input[i] ^ padding_len) & mask; } - return (int) mbedtls_ct_uint_if(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); + return -mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); } #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ @@ -804,7 +804,7 @@ static int get_one_and_zeros_padding(unsigned char *input, size_t input_len, in_padding = in_padding & ~is_nonzero; } - return (int) mbedtls_ct_uint_if(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); + return -mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); } #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ @@ -848,7 +848,7 @@ static int get_zeros_and_len_padding(unsigned char *input, size_t input_len, bad |= input[i] & mask; } - return (int) mbedtls_ct_uint_if(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); + return -mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); } #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ diff --git a/library/nist_kw.c b/library/nist_kw.c index c7fb09391..f2fd82e6b 100644 --- a/library/nist_kw.c +++ b/library/nist_kw.c @@ -421,7 +421,7 @@ 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; - ret = (int) mbedtls_ct_uint_if(padlen & ~7, MBEDTLS_ERR_CIPHER_AUTH_FAILED, ret); + ret = -mbedtls_ct_uint_if(padlen & ~7, -MBEDTLS_ERR_CIPHER_AUTH_FAILED, -ret); padlen &= 7; /* Check padding in "constant-time" */ From 5ea6bb06a7532d88fcb09e1e54d6321eec137914 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 20:14:15 +0100 Subject: [PATCH 12/13] Add cast for MSVC Signed-off-by: Dave Rodgman --- library/cipher.c | 6 +++--- library/nist_kw.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index 06199919a..09ca686d8 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -759,7 +759,7 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len, size_t mask = mbedtls_ct_size_mask_ge(i, pad_idx); bad |= (input[i] ^ padding_len) & mask; } - return -mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); + return -(int) mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); } #endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ @@ -804,7 +804,7 @@ static int get_one_and_zeros_padding(unsigned char *input, size_t input_len, in_padding = in_padding & ~is_nonzero; } - return -mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); + return -(int) mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); } #endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ @@ -848,7 +848,7 @@ static int get_zeros_and_len_padding(unsigned char *input, size_t input_len, bad |= input[i] & mask; } - return -mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); + return -(int) mbedtls_ct_uint_if(bad, -MBEDTLS_ERR_CIPHER_INVALID_PADDING, 0); } #endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ diff --git a/library/nist_kw.c b/library/nist_kw.c index f2fd82e6b..4ff5e41b4 100644 --- a/library/nist_kw.c +++ b/library/nist_kw.c @@ -421,7 +421,7 @@ 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; - ret = -mbedtls_ct_uint_if(padlen & ~7, -MBEDTLS_ERR_CIPHER_AUTH_FAILED, -ret); + ret = -(int) mbedtls_ct_uint_if(padlen & ~7, -MBEDTLS_ERR_CIPHER_AUTH_FAILED, -ret); padlen &= 7; /* Check padding in "constant-time" */ From 6063d82f044fa2710f67b9681a2b6a4557ee46bb Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 20 Sep 2023 21:54:15 +0100 Subject: [PATCH 13/13] Correct macro guards in constant_time_internal.h Signed-off-by: Dave Rodgman --- library/constant_time_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index 5b6223d65..0ba8a7a0b 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -46,7 +46,7 @@ unsigned mbedtls_ct_uint_mask(unsigned value); #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_WITH_PADDING) + 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 @@ -62,7 +62,7 @@ unsigned mbedtls_ct_uint_mask(unsigned value); size_t mbedtls_ct_size_mask(size_t value); #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_WITH_PADDING) */ + defined(MBEDTLS_NIST_KW_C) || defined(MBEDTLS_CIPHER_MODE_CBC) */ #if defined(MBEDTLS_BIGNUM_C)