From 7464f37e7b3c0cfec090d1ddee7347bddce088c3 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 15 Nov 2021 16:03:24 +0100 Subject: [PATCH 1/9] Rename functions to have suitable name Signed-off-by: Gabor Mezei --- library/base64.c | 48 ++++++++++++------------- library/base64_invasive.h | 10 +++--- tests/suites/test_suite_base64.function | 6 ++-- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/library/base64.c b/library/base64.c index a516c1d4a..b7e2e3937 100644 --- a/library/base64.c +++ b/library/base64.c @@ -43,9 +43,9 @@ * Constant flow with respect to c. */ MBEDTLS_STATIC_TESTABLE -unsigned char mbedtls_base64_mask_of_range( unsigned char low, - unsigned char high, - unsigned char c ) +unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low, + unsigned char high, + unsigned char c ) { /* low_mask is: 0 if low <= c, 0x...ff if low > c */ unsigned low_mask = ( (unsigned) c - low ) >> 8; @@ -59,17 +59,17 @@ unsigned char mbedtls_base64_mask_of_range( unsigned char low, * but not EBCDIC). */ MBEDTLS_STATIC_TESTABLE -unsigned char mbedtls_base64_enc_char( unsigned char val ) +unsigned char mbedtls_ct_base64_enc_char( unsigned char val ) { unsigned char digit = 0; /* For each range of values, if val is in that range, mask digit with * the corresponding value. Since val can only be in a single range, * only at most one masking will change digit. */ - digit |= mbedtls_base64_mask_of_range( 0, 25, val ) & ( 'A' + val ); - digit |= mbedtls_base64_mask_of_range( 26, 51, val ) & ( 'a' + val - 26 ); - digit |= mbedtls_base64_mask_of_range( 52, 61, val ) & ( '0' + val - 52 ); - digit |= mbedtls_base64_mask_of_range( 62, 62, val ) & '+'; - digit |= mbedtls_base64_mask_of_range( 63, 63, val ) & '/'; + digit |= mbedtls_ct_uchar_mask_of_range( 0, 25, val ) & ( 'A' + val ); + digit |= mbedtls_ct_uchar_mask_of_range( 26, 51, val ) & ( 'a' + val - 26 ); + digit |= mbedtls_ct_uchar_mask_of_range( 52, 61, val ) & ( '0' + val - 52 ); + digit |= mbedtls_ct_uchar_mask_of_range( 62, 62, val ) & '+'; + digit |= mbedtls_ct_uchar_mask_of_range( 63, 63, val ) & '/'; return( digit ); } @@ -113,12 +113,12 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, C2 = *src++; C3 = *src++; - *p++ = mbedtls_base64_enc_char( ( C1 >> 2 ) & 0x3F ); - *p++ = mbedtls_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) + *p++ = mbedtls_ct_base64_enc_char( ( C1 >> 2 ) & 0x3F ); + *p++ = mbedtls_ct_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ); - *p++ = mbedtls_base64_enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) + *p++ = mbedtls_ct_base64_enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ); - *p++ = mbedtls_base64_enc_char( C3 & 0x3F ); + *p++ = mbedtls_ct_base64_enc_char( C3 & 0x3F ); } if( i < slen ) @@ -126,12 +126,12 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, C1 = *src++; C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; - *p++ = mbedtls_base64_enc_char( ( C1 >> 2 ) & 0x3F ); - *p++ = mbedtls_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) + *p++ = mbedtls_ct_base64_enc_char( ( C1 >> 2 ) & 0x3F ); + *p++ = mbedtls_ct_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ); if( ( i + 1 ) < slen ) - *p++ = mbedtls_base64_enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F ); + *p++ = mbedtls_ct_base64_enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F ); else *p++ = '='; *p++ = '='; @@ -155,18 +155,18 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, * access. */ MBEDTLS_STATIC_TESTABLE -signed char mbedtls_base64_dec_value( unsigned char c ) +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_base64_mask_of_range( 'A', 'Z', c ) & ( c - 'A' + 0 + 1 ); - val |= mbedtls_base64_mask_of_range( 'a', 'z', c ) & ( c - 'a' + 26 + 1 ); - val |= mbedtls_base64_mask_of_range( '0', '9', c ) & ( c - '0' + 52 + 1 ); - val |= mbedtls_base64_mask_of_range( '+', '+', c ) & ( c - '+' + 62 + 1 ); - val |= mbedtls_base64_mask_of_range( '/', '/', c ) & ( c - '/' + 63 + 1 ); + 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 ); @@ -224,7 +224,7 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, { if( equals != 0 ) return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - if( mbedtls_base64_dec_value( src[i] ) < 0 ) + if( mbedtls_ct_base64_dec_value( src[i] ) < 0 ) return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); } n++; @@ -259,7 +259,7 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, if( *src == '=' ) ++equals; else - x |= mbedtls_base64_dec_value( *src ); + x |= mbedtls_ct_base64_dec_value( *src ); if( ++accumulated_digits == 4 ) { diff --git a/library/base64_invasive.h b/library/base64_invasive.h index ed5f7cb82..fcb833155 100644 --- a/library/base64_invasive.h +++ b/library/base64_invasive.h @@ -33,15 +33,15 @@ * * Constant flow with respect to c. */ -unsigned char mbedtls_base64_mask_of_range( unsigned char low, - unsigned char high, - unsigned char c ); +unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low, + unsigned char high, + unsigned char c ); /* Given a value in the range 0..63, return the corresponding Base64 digit. * * Operates in constant time (no branches or memory access depending on val). */ -unsigned char mbedtls_base64_enc_char( unsigned char val ); +unsigned char mbedtls_ct_base64_enc_char( unsigned char val ); /* Given a Base64 digit, return its value. * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'), @@ -49,7 +49,7 @@ unsigned char mbedtls_base64_enc_char( unsigned char val ); * * Operates in constant time (no branches or memory access depending on c). */ -signed char mbedtls_base64_dec_value( unsigned char c ); +signed char mbedtls_ct_base64_dec_value( unsigned char c ); #endif /* MBEDTLS_TEST_HOOKS */ #endif /* MBEDTLS_BASE64_INVASIVE_H */ diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function index 67fbb6750..d332047a6 100644 --- a/tests/suites/test_suite_base64.function +++ b/tests/suites/test_suite_base64.function @@ -24,7 +24,7 @@ void mask_of_range( int low_arg, int high_arg ) { mbedtls_test_set_step( c ); TEST_CF_SECRET( &c, sizeof( c ) ); - unsigned char m = mbedtls_base64_mask_of_range( low, high, c ); + unsigned char m = mbedtls_ct_uchar_mask_of_range( low, high, c ); TEST_CF_PUBLIC( &c, sizeof( c ) ); TEST_CF_PUBLIC( &m, sizeof( m ) ); if( low <= c && c <= high ) @@ -42,7 +42,7 @@ void enc_chars( ) { mbedtls_test_set_step( value ); TEST_CF_SECRET( &value, sizeof( value ) ); - unsigned char digit = mbedtls_base64_enc_char( value ); + unsigned char digit = mbedtls_ct_base64_enc_char( value ); TEST_CF_PUBLIC( &value, sizeof( value ) ); TEST_CF_PUBLIC( &digit, sizeof( digit ) ); TEST_EQUAL( digit, base64_digits[value] ); @@ -66,7 +66,7 @@ void dec_chars( ) else expected = p - base64_digits; TEST_CF_SECRET( &c, sizeof( c ) ); - signed char actual = mbedtls_base64_dec_value( c ); + signed char actual = mbedtls_ct_base64_dec_value( c ); TEST_CF_PUBLIC( &c, sizeof( c ) ); TEST_CF_PUBLIC( &actual, sizeof( actual ) ); TEST_EQUAL( actual, expected ); From 46f79c388d8025e1352eefa37642e827337aead3 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 15 Nov 2021 16:13:01 +0100 Subject: [PATCH 2/9] Move mbedtls_ct_uchar_mask_of_range function to the constant-time module Signed-off-by: Gabor Mezei --- library/base64.c | 16 --------- library/constant_time.c | 23 +++++++++++++ library/constant_time_invasive.h | 44 +++++++++++++++++++++++++ tests/suites/test_suite_base64.function | 2 ++ 4 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 library/constant_time_invasive.h diff --git a/library/base64.c b/library/base64.c index b7e2e3937..2c4df8338 100644 --- a/library/base64.c +++ b/library/base64.c @@ -38,22 +38,6 @@ #define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ -/* Return 0xff if low <= c <= high, 0 otherwise. - * - * 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 ) -{ - /* 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( ~( low_mask | high_mask ) & 0xff ); -} - /* 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). diff --git a/library/constant_time.c b/library/constant_time.c index b0e5ddec7..890041504 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -40,6 +40,10 @@ #include "mbedtls/rsa.h" #endif +#if defined(MBEDTLS_BASE64_C) +#include "constant_time_invasive.h" +#endif + #include int mbedtls_ct_memcmp( const void *a, @@ -150,6 +154,25 @@ size_t mbedtls_ct_size_mask_ge( size_t x, #endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ +#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 ) +{ + /* 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( ~( low_mask | high_mask ) & 0xff ); +} + +#endif /* MBEDTLS_BASE64_C */ + unsigned mbedtls_ct_size_bool_eq( size_t x, size_t y ) { diff --git a/library/constant_time_invasive.h b/library/constant_time_invasive.h new file mode 100644 index 000000000..9008f5d43 --- /dev/null +++ b/library/constant_time_invasive.h @@ -0,0 +1,44 @@ +/** + * \file constant_time_invasive.h + * + * \brief Constant-time module: interfaces for invasive testing only. + * + * The interfaces in this file are intended for testing purposes only. + * They SHOULD NOT be made available in library integrations except when + * building the library for testing. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_CONSTANT_TIME_INVASIVE_H +#define MBEDTLS_CONSTANT_TIME_INVASIVE_H + +#include "common.h" + +#if defined(MBEDTLS_TEST_HOOKS) + +/* 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_TEST_HOOKS */ + +#endif /* MBEDTLS_CONSTANT_TIME_INVASIVE_H */ diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function index d332047a6..89982047f 100644 --- a/tests/suites/test_suite_base64.function +++ b/tests/suites/test_suite_base64.function @@ -1,6 +1,8 @@ /* BEGIN_HEADER */ #include "mbedtls/base64.h" #include "base64_invasive.h" +#include "constant_time_internal.h" +#include "constant_time_invasive.h" #include #if defined(MBEDTLS_TEST_HOOKS) From 200708d30a5bb1d185902d82be206c8230f7c2aa Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 15 Nov 2021 16:18:54 +0100 Subject: [PATCH 3/9] Move mbedtls_ct_base64_enc_char function to the constant-time module Signed-off-by: Gabor Mezei --- library/base64.c | 20 +------------------- library/constant_time.c | 22 ++++++++++++++++++++++ library/constant_time_internal.h | 6 ++++++ 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/library/base64.c b/library/base64.c index 2c4df8338..f1a605501 100644 --- a/library/base64.c +++ b/library/base64.c @@ -23,6 +23,7 @@ #include "mbedtls/base64.h" #include "base64_invasive.h" +#include "constant_time_internal.h" #include @@ -38,25 +39,6 @@ #define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ -/* 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). - */ -MBEDTLS_STATIC_TESTABLE -unsigned char mbedtls_ct_base64_enc_char( unsigned char val ) -{ - unsigned char digit = 0; - /* For each range of values, if val is in that range, mask digit with - * the corresponding value. Since val can only be in a single range, - * only at most one masking will change digit. */ - digit |= mbedtls_ct_uchar_mask_of_range( 0, 25, val ) & ( 'A' + val ); - digit |= mbedtls_ct_uchar_mask_of_range( 26, 51, val ) & ( 'a' + val - 26 ); - digit |= mbedtls_ct_uchar_mask_of_range( 52, 61, val ) & ( '0' + val - 52 ); - digit |= mbedtls_ct_uchar_mask_of_range( 62, 62, val ) & '+'; - digit |= mbedtls_ct_uchar_mask_of_range( 63, 63, val ) & '/'; - return( digit ); -} - /* * Encode a buffer into base64 format */ diff --git a/library/constant_time.c b/library/constant_time.c index 890041504..cdaa7fad9 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -324,6 +324,28 @@ 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). + */ +unsigned char mbedtls_ct_base64_enc_char( unsigned char val ) +{ + unsigned char digit = 0; + /* For each range of values, if val is in that range, mask digit with + * the corresponding value. Since val can only be in a single range, + * only at most one masking will change digit. */ + digit |= mbedtls_ct_uchar_mask_of_range( 0, 25, val ) & ( 'A' + val ); + digit |= mbedtls_ct_uchar_mask_of_range( 26, 51, val ) & ( 'a' + val - 26 ); + digit |= mbedtls_ct_uchar_mask_of_range( 52, 61, val ) & ( '0' + val - 52 ); + digit |= mbedtls_ct_uchar_mask_of_range( 62, 62, val ) & '+'; + digit |= mbedtls_ct_uchar_mask_of_range( 63, 63, val ) & '/'; + return( digit ); +} + +#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 69cd09209..f0286221a 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -167,6 +167,12 @@ 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 val ); + +#endif /* MBEDTLS_BASE64_C */ + #if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) /** Conditional memcpy without branches. From 3d4dba84b71ff669ac81e2f1520f0ef2ad486765 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 15 Nov 2021 16:22:37 +0100 Subject: [PATCH 4/9] Move mbedtls_ct_base64_dec_value function to the constant-time module Signed-off-by: Gabor Mezei --- library/base64.c | 29 ----------------------------- library/constant_time.c | 28 ++++++++++++++++++++++++++++ library/constant_time_internal.h | 2 ++ 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/library/base64.c b/library/base64.c index f1a605501..b2e6dabcb 100644 --- a/library/base64.c +++ b/library/base64.c @@ -109,35 +109,6 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, return( 0 ); } -/* 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). - * - * The implementation is constant-flow (no branch or memory access depending - * on the value of c) unless the compiler inlines and optimizes a specific - * access. - */ -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 ); -} - /* * Decode a base64-formatted buffer */ diff --git a/library/constant_time.c b/library/constant_time.c index cdaa7fad9..5bf594fdd 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -344,6 +344,34 @@ unsigned char mbedtls_ct_base64_enc_char( unsigned char val ) return( digit ); } +/* 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). + * + * The implementation is constant-flow (no branch or memory access depending + * on the value of c) unless the compiler inlines and optimizes a specific + * access. + */ +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) diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index f0286221a..90d1ac673 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -171,6 +171,8 @@ void mbedtls_ct_mpi_uint_cond_assign( size_t n, unsigned char mbedtls_ct_base64_enc_char( unsigned char val ); +signed char mbedtls_ct_base64_dec_value( unsigned char c ); + #endif /* MBEDTLS_BASE64_C */ #if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) From f554ce21b8e9c2686d95a9bd785b632e7aa50404 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Thu, 18 Nov 2021 16:57:00 +0100 Subject: [PATCH 5/9] Delete base64_invasive.h due to functions are moved to the constant-time module Signed-off-by: Gabor Mezei --- library/base64.c | 1 - library/base64_invasive.h | 55 ------------------------- tests/suites/test_suite_base64.function | 1 - 3 files changed, 57 deletions(-) delete mode 100644 library/base64_invasive.h diff --git a/library/base64.c b/library/base64.c index b2e6dabcb..83daa0bcc 100644 --- a/library/base64.c +++ b/library/base64.c @@ -22,7 +22,6 @@ #if defined(MBEDTLS_BASE64_C) #include "mbedtls/base64.h" -#include "base64_invasive.h" #include "constant_time_internal.h" #include diff --git a/library/base64_invasive.h b/library/base64_invasive.h deleted file mode 100644 index fcb833155..000000000 --- a/library/base64_invasive.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \file base_invasive.h - * - * \brief Base64 module: interfaces for invasive testing only. - * - * The interfaces in this file are intended for testing purposes only. - * They SHOULD NOT be made available in library integrations except when - * building the library for testing. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBEDTLS_BASE64_INVASIVE_H -#define MBEDTLS_BASE64_INVASIVE_H - -#include "common.h" - -#if defined(MBEDTLS_TEST_HOOKS) -/* 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 ); - -/* Given a value in the range 0..63, return the corresponding Base64 digit. - * - * Operates in constant time (no branches or memory access depending on val). - */ -unsigned char mbedtls_ct_base64_enc_char( unsigned char val ); - -/* Given a Base64 digit, return its value. - * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'), - * return -1. - * - * Operates in constant time (no branches or memory access depending on c). - */ -signed char mbedtls_ct_base64_dec_value( unsigned char c ); -#endif /* MBEDTLS_TEST_HOOKS */ - -#endif /* MBEDTLS_BASE64_INVASIVE_H */ diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function index 89982047f..7baa3d501 100644 --- a/tests/suites/test_suite_base64.function +++ b/tests/suites/test_suite_base64.function @@ -1,6 +1,5 @@ /* BEGIN_HEADER */ #include "mbedtls/base64.h" -#include "base64_invasive.h" #include "constant_time_internal.h" #include "constant_time_invasive.h" #include From df29332d4bb3cce05ce84447e4f42d47f9b62fec Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Fri, 26 Nov 2021 17:20:36 +0100 Subject: [PATCH 6/9] Make mbedtls_ct_uchar_mask_of_range function static Signed-off-by: Gabor Mezei --- library/constant_time.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/constant_time.c b/library/constant_time.c index 5bf594fdd..6fa69bb2c 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -160,6 +160,7 @@ 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 ) From 46ca2f76c4bda5eed8b59f0a324fbfad0083cdc6 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 24 Nov 2021 15:51:39 +0100 Subject: [PATCH 7/9] Unify function parameters Signed-off-by: Gabor Mezei --- library/constant_time.c | 16 ++++++++-------- library/constant_time_internal.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index 6fa69bb2c..cd699a55a 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -331,17 +331,17 @@ void mbedtls_ct_mpi_uint_cond_assign( size_t n, * The implementation assumes that letters are consecutive (e.g. ASCII * but not EBCDIC). */ -unsigned char mbedtls_ct_base64_enc_char( unsigned char val ) +unsigned char mbedtls_ct_base64_enc_char( unsigned char value ) { unsigned char digit = 0; - /* For each range of values, if val is in that range, mask digit with - * the corresponding value. Since val can only be in a single range, + /* 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, val ) & ( 'A' + val ); - digit |= mbedtls_ct_uchar_mask_of_range( 26, 51, val ) & ( 'a' + val - 26 ); - digit |= mbedtls_ct_uchar_mask_of_range( 52, 61, val ) & ( '0' + val - 52 ); - digit |= mbedtls_ct_uchar_mask_of_range( 62, 62, val ) & '+'; - digit |= mbedtls_ct_uchar_mask_of_range( 63, 63, val ) & '/'; + 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 ); } diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index 90d1ac673..a13e7b2c0 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -169,7 +169,7 @@ void mbedtls_ct_mpi_uint_cond_assign( size_t n, #if defined(MBEDTLS_BASE64_C) -unsigned char mbedtls_ct_base64_enc_char( unsigned char val ); +unsigned char mbedtls_ct_base64_enc_char( unsigned char value ); signed char mbedtls_ct_base64_dec_value( unsigned char c ); From 3a755f511f279bc93fe0d508dee8f01794bb7e0f Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 24 Nov 2021 16:26:33 +0100 Subject: [PATCH 8/9] Add documentation for the functions Signed-off-by: Gabor Mezei --- library/constant_time.c | 15 --------------- library/constant_time_internal.h | 21 +++++++++++++++++++++ library/constant_time_invasive.h | 11 +++++++++-- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/library/constant_time.c b/library/constant_time.c index cd699a55a..18f1b20da 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -327,10 +327,6 @@ void mbedtls_ct_mpi_uint_cond_assign( size_t n, #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). - */ unsigned char mbedtls_ct_base64_enc_char( unsigned char value ) { unsigned char digit = 0; @@ -345,17 +341,6 @@ unsigned char mbedtls_ct_base64_enc_char( unsigned char value ) return( digit ); } -/* 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). - * - * The implementation is constant-flow (no branch or memory access depending - * on the value of c) unless the compiler inlines and optimizes a specific - * access. - */ signed char mbedtls_ct_base64_dec_value( unsigned char c ) { unsigned char val = 0; diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h index a13e7b2c0..bbb3a9067 100644 --- a/library/constant_time_internal.h +++ b/library/constant_time_internal.h @@ -169,8 +169,29 @@ void mbedtls_ct_mpi_uint_cond_assign( size_t n, #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 */ diff --git a/library/constant_time_invasive.h b/library/constant_time_invasive.h index 9008f5d43..4620ca137 100644 --- a/library/constant_time_invasive.h +++ b/library/constant_time_invasive.h @@ -31,9 +31,16 @@ #if defined(MBEDTLS_TEST_HOOKS) -/* Return 0xff if low <= c <= high, 0 otherwise. +/** Turn a value into a mask: + * - if \p low <= \p c <= \p high, + * return the all-bits 1 mask, aka (unsigned) -1 + * - otherwise, return the all-bits 0 mask, aka 0 * - * Constant flow with respect to c. + * \param low The value to analyze. + * \param high The value to analyze. + * \param c The value to analyze. + * + * \return All-bits-one if \p low <= \p c <= \p high, otherwise zero. */ unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low, unsigned char high, From 00e08a3a2169a9c1c0ec3c7aaab751875d21c3a5 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Thu, 9 Dec 2021 10:05:48 +0100 Subject: [PATCH 9/9] Update generated files Signed-off-by: Gabor Mezei --- visualc/VS2010/mbedTLS.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 08972c3f8..88ffe1b2e 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -256,10 +256,10 @@ - +