From 8c94e219f9e4a017af84b6aaa777cd12c19010d9 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 9 May 2023 10:39:03 +0100 Subject: [PATCH] Evolve mbedtls_ct_uchar_in_range_if interface Signed-off-by: Dave Rodgman --- library/base64.c | 20 ++++++++++---------- library/constant_time_internal.h | 24 +++++++++++++++++++----- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/library/base64.c b/library/base64.c index 3f13fdab0..2b623b9bc 100644 --- a/library/base64.c +++ b/library/base64.c @@ -40,11 +40,11 @@ unsigned char mbedtls_ct_base64_enc_char(unsigned char value) /* For each range of values, if value is in that range, mask digit with * the corresponding value. Since value can only be in a single range, * only at most one masking will change digit. */ - digit |= mbedtls_ct_uchar_mask_of_range(0, 25, value) & ('A' + value); - digit |= mbedtls_ct_uchar_mask_of_range(26, 51, value) & ('a' + value - 26); - digit |= mbedtls_ct_uchar_mask_of_range(52, 61, value) & ('0' + value - 52); - digit |= mbedtls_ct_uchar_mask_of_range(62, 62, value) & '+'; - digit |= mbedtls_ct_uchar_mask_of_range(63, 63, value) & '/'; + digit |= mbedtls_ct_uchar_in_range_if(0, 25, value, 'A' + value); + digit |= mbedtls_ct_uchar_in_range_if(26, 51, value, 'a' + value - 26); + digit |= mbedtls_ct_uchar_in_range_if(52, 61, value, '0' + value - 52); + digit |= mbedtls_ct_uchar_in_range_if(62, 62, value, '+'); + digit |= mbedtls_ct_uchar_in_range_if(63, 63, value, '/'); return digit; } @@ -56,11 +56,11 @@ signed char mbedtls_ct_base64_dec_value(unsigned char c) * the corresponding value. Since c can only be in a single range, * only at most one masking will change val. Set val to one plus * the desired value so that it stays 0 if c is in none of the ranges. */ - val |= mbedtls_ct_uchar_mask_of_range('A', 'Z', c) & (c - 'A' + 0 + 1); - val |= mbedtls_ct_uchar_mask_of_range('a', 'z', c) & (c - 'a' + 26 + 1); - val |= mbedtls_ct_uchar_mask_of_range('0', '9', c) & (c - '0' + 52 + 1); - val |= mbedtls_ct_uchar_mask_of_range('+', '+', c) & (c - '+' + 62 + 1); - val |= mbedtls_ct_uchar_mask_of_range('/', '/', c) & (c - '/' + 63 + 1); + val |= mbedtls_ct_uchar_in_range_if('A', 'Z', c, c - 'A' + 0 + 1); + val |= mbedtls_ct_uchar_in_range_if('a', 'z', c, c - 'a' + 26 + 1); + val |= mbedtls_ct_uchar_in_range_if('0', '9', c, c - '0' + 52 + 1); + val |= mbedtls_ct_uchar_in_range_if('+', '+', c, c - '+' + 62 + 1); + val |= mbedtls_ct_uchar_in_range_if('/', '/', c, c - '/' + 63 + 1); /* At this point, val is 0 if c is an invalid digit and v+1 if c is * a digit with the value v. */ return val - 1; diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index 4ca392526..dde6a0bfc 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -333,13 +333,27 @@ int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input, #if defined(MBEDTLS_BASE64_C) -/* Return 0xff if low <= c <= high, 0 otherwise. +/** Constant-flow char selection * - * Constant flow with respect to c. + * \param low Bottom of range + * \param high Top of range + * \param c Value to compare to range + * \param t Value to return, if in range + * + * \return \p t if \p low <= \p c <= \p high, 0 otherwise. */ -unsigned char mbedtls_ct_uchar_mask_of_range(unsigned char low, - unsigned char high, - unsigned char c); +static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low, + unsigned char high, + unsigned char c, + unsigned char t) +{ + /* low_mask is: 0 if low <= c, 0x...ff if low > c */ + unsigned low_mask = ((unsigned) c - low) >> 8; + /* high_mask is: 0 if c <= high, 0x...ff if c > high */ + unsigned high_mask = ((unsigned) high - c) >> 8; + return (unsigned char) + mbedtls_ct_uint_if(~mbedtls_ct_mpi_uint_mask(low_mask | high_mask), t, 0); +} #endif /* MBEDTLS_BASE64_C */