From 0ee9683987396f6c02016a7f455c57968a3db339 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 9 May 2023 09:49:01 +0100 Subject: [PATCH] Move mbedtls_ct_base64_(enc|dec)_char into base64.c Signed-off-by: Dave Rodgman --- include/mbedtls/base64.h | 29 ++++++++++++++++++++++ library/base64.c | 33 +++++++++++++++++++++++++ library/constant_time.c | 36 ---------------------------- library/constant_time_internal.h | 41 ++++++++++---------------------- 4 files changed, 74 insertions(+), 65 deletions(-) diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h index 635be713d8..e82c270eab 100644 --- a/include/mbedtls/base64.h +++ b/include/mbedtls/base64.h @@ -87,6 +87,35 @@ int mbedtls_base64_self_test(int verbose); #endif /* MBEDTLS_SELF_TEST */ +#if defined(MBEDTLS_TEST_HOOKS) + +/** Given a value in the range 0..63, return the corresponding Base64 digit. + * + * The implementation assumes that letters are consecutive (e.g. ASCII + * but not EBCDIC). + * + * \param value A value in the range 0..63. + * + * \return A base64 digit converted from \p value. + */ +unsigned char mbedtls_ct_base64_enc_char(unsigned char value); + +/** Given a Base64 digit, return its value. + * + * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'), + * return -1. + * + * The implementation assumes that letters are consecutive (e.g. ASCII + * but not EBCDIC). + * + * \param c A base64 digit. + * + * \return The value of the base64 digit \p c. + */ +signed char mbedtls_ct_base64_dec_value(unsigned char c); + +#endif /* MBEDTLS_TEST_HOOKS */ + #ifdef __cplusplus } #endif diff --git a/library/base64.c b/library/base64.c index 3eb9e7cc55..3f13fdab06 100644 --- a/library/base64.c +++ b/library/base64.c @@ -33,6 +33,39 @@ #include "mbedtls/platform.h" #endif /* MBEDTLS_SELF_TEST */ +MBEDTLS_STATIC_TESTABLE +unsigned char mbedtls_ct_base64_enc_char(unsigned char value) +{ + unsigned char digit = 0; + /* 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) & '/'; + return digit; +} + +MBEDTLS_STATIC_TESTABLE +signed char mbedtls_ct_base64_dec_value(unsigned char c) +{ + unsigned char val = 0; + /* For each range of digits, if c is in that range, mask val with + * 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); + /* 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; +} + /* * Encode a buffer into base64 format */ diff --git a/library/constant_time.c b/library/constant_time.c index c823b78894..1f6c2ca020 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -212,7 +212,6 @@ size_t mbedtls_ct_size_mask_ge(size_t x, * * Constant flow with respect to c. */ -MBEDTLS_STATIC_TESTABLE unsigned char mbedtls_ct_uchar_mask_of_range(unsigned char low, unsigned char high, unsigned char c) @@ -344,41 +343,6 @@ void mbedtls_ct_mpi_uint_cond_assign(size_t n, #endif /* MBEDTLS_BIGNUM_C */ -#if defined(MBEDTLS_BASE64_C) - -unsigned char mbedtls_ct_base64_enc_char(unsigned char value) -{ - unsigned char digit = 0; - /* 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) & '/'; - return digit; -} - -signed char mbedtls_ct_base64_dec_value(unsigned char c) -{ - unsigned char val = 0; - /* For each range of digits, if c is in that range, mask val with - * 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); - /* 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; -} - -#endif /* MBEDTLS_BASE64_C */ - #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) /** Shift some data towards the left inside a buffer. diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index c4a32c7f02..4ca3925260 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -185,35 +185,6 @@ void mbedtls_ct_mpi_uint_cond_assign(size_t n, #endif /* MBEDTLS_BIGNUM_C */ -#if defined(MBEDTLS_BASE64_C) - -/** Given a value in the range 0..63, return the corresponding Base64 digit. - * - * The implementation assumes that letters are consecutive (e.g. ASCII - * but not EBCDIC). - * - * \param value A value in the range 0..63. - * - * \return A base64 digit converted from \p value. - */ -unsigned char mbedtls_ct_base64_enc_char(unsigned char value); - -/** Given a Base64 digit, return its value. - * - * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'), - * return -1. - * - * The implementation assumes that letters are consecutive (e.g. ASCII - * but not EBCDIC). - * - * \param c A base64 digit. - * - * \return The value of the base64 digit \p c. - */ -signed char mbedtls_ct_base64_dec_value(unsigned char c); - -#endif /* MBEDTLS_BASE64_C */ - #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) /** Conditional memcpy without branches. @@ -360,4 +331,16 @@ int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input, #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */ +#if defined(MBEDTLS_BASE64_C) + +/* Return 0xff if low <= c <= high, 0 otherwise. + * + * Constant flow with respect to c. + */ +unsigned char mbedtls_ct_uchar_mask_of_range(unsigned char low, + unsigned char high, + unsigned char c); + +#endif /* MBEDTLS_BASE64_C */ + #endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */