diff --git a/library/cipher.c b/library/cipher.c index 546cace55..a53609e4e 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -29,6 +29,7 @@ #include "cipher_wrap.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" +#include "constant_time.h" #include #include @@ -74,27 +75,6 @@ #define CIPHER_VALIDATE( cond ) \ MBEDTLS_INTERNAL_VALIDATE( cond ) -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) -/* Compare the contents of two buffers in constant time. - * Returns 0 if the contents are bitwise identical, otherwise returns - * a non-zero value. - * This is currently only used by GCM and ChaCha20+Poly1305. - */ -static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, - size_t len ) -{ - const unsigned char *p1 = (const unsigned char*) v1; - const unsigned char *p2 = (const unsigned char*) v2; - size_t i; - unsigned char diff; - - for( diff = 0, i = 0; i < len; i++ ) - diff |= p1[i] ^ p2[i]; - - return( (int)diff ); -} -#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ - static int supported_init = 0; const int *mbedtls_cipher_list( void ) diff --git a/library/constant_time.c b/library/constant_time.c index 9f0229bd5..cb156bc9b 100644 --- a/library/constant_time.c +++ b/library/constant_time.c @@ -18,3 +18,77 @@ */ #include "common.h" +#include "constant_time.h" + +/* constant-time buffer comparison */ +int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ) +{ + size_t i; + volatile const unsigned char *A = (volatile const unsigned char *) a; + volatile const unsigned char *B = (volatile const unsigned char *) b; + volatile unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + { + /* Read volatile data in order before computing diff. + * This avoids IAR compiler warning: + * 'the order of volatile accesses is undefined ..' */ + unsigned char x = A[i], y = B[i]; + diff |= x ^ y; + } + + return( diff ); +} + +/* Compare the contents of two buffers in constant time. + * Returns 0 if the contents are bitwise identical, otherwise returns + * a non-zero value. + * This is currently only used by GCM and ChaCha20+Poly1305. + */ +int mbedtls_constant_time_memcmp( const void *v1, const void *v2, + size_t len ) +{ + const unsigned char *p1 = (const unsigned char*) v1; + const unsigned char *p2 = (const unsigned char*) v2; + size_t i; + unsigned char diff; + + for( diff = 0, i = 0; i < len; i++ ) + diff |= p1[i] ^ p2[i]; + + return( (int)diff ); +} + +/* constant-time buffer comparison */ +unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n ) +{ + size_t i; + volatile const unsigned char *A = (volatile const unsigned char *) a; + volatile const unsigned char *B = (volatile const unsigned char *) b; + volatile unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + { + /* Read volatile data in order before computing diff. + * This avoids IAR compiler warning: + * 'the order of volatile accesses is undefined ..' */ + unsigned char x = A[i], y = B[i]; + diff |= x ^ y; + } + + return( diff ); +} + +/* constant-time buffer comparison */ +int mbedtls_safer_memcmp( const void *a, const void *b, size_t n ) +{ + size_t i; + const unsigned char *A = (const unsigned char *) a; + const unsigned char *B = (const unsigned char *) b; + unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + diff |= A[i] ^ B[i]; + + return( diff ); +} diff --git a/library/constant_time.h b/library/constant_time.h new file mode 100644 index 000000000..e14232b8b --- /dev/null +++ b/library/constant_time.h @@ -0,0 +1,30 @@ +/** + * Constant-time functions + * + * 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. + */ + +#include "common.h" + +#include + +int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ); + +int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len ); + +unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n ); + +int mbedtls_safer_memcmp( const void *a, const void *b, size_t n ); diff --git a/library/nist_kw.c b/library/nist_kw.c index 5054ca206..aaed42a18 100644 --- a/library/nist_kw.c +++ b/library/nist_kw.c @@ -34,6 +34,7 @@ #include "mbedtls/nist_kw.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" +#include "constant_time.h" #include #include @@ -52,26 +53,6 @@ #define KW_SEMIBLOCK_LENGTH 8 #define MIN_SEMIBLOCKS_COUNT 3 -/* constant-time buffer comparison */ -static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - volatile const unsigned char *A = (volatile const unsigned char *) a; - volatile const unsigned char *B = (volatile const unsigned char *) b; - volatile unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - { - /* Read volatile data in order before computing diff. - * This avoids IAR compiler warning: - * 'the order of volatile accesses is undefined ..' */ - unsigned char x = A[i], y = B[i]; - diff |= x ^ y; - } - - return( diff ); -} - /*! The 64-bit default integrity check value (ICV) for KW mode. */ static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}; /*! The 32-bit default integrity check value (ICV) for KWP mode. */ diff --git a/library/rsa.c b/library/rsa.c index 9c110378c..f1b8489ee 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -44,6 +44,7 @@ #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" +#include "constant_time.h" #include @@ -72,22 +73,6 @@ #define RSA_VALIDATE( cond ) \ MBEDTLS_INTERNAL_VALIDATE( cond ) -#if defined(MBEDTLS_PKCS1_V15) -/* constant-time buffer comparison */ -static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - const unsigned char *A = (const unsigned char *) a; - const unsigned char *B = (const unsigned char *) b; - unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - diff |= A[i] ^ B[i]; - - return( diff ); -} -#endif /* MBEDTLS_PKCS1_V15 */ - int mbedtls_rsa_import( mbedtls_rsa_context *ctx, const mbedtls_mpi *N, const mbedtls_mpi *P, const mbedtls_mpi *Q, diff --git a/library/ssl_cli.c b/library/ssl_cli.c index e0a1c24ec..3ef318c96 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -33,6 +33,7 @@ #include "ssl_misc.h" #include "mbedtls/debug.h" #include "mbedtls/error.h" +#include "constant_time.h" #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/psa_util.h" diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c index 40b8913b8..5936d3598 100644 --- a/library/ssl_cookie.c +++ b/library/ssl_cookie.c @@ -36,6 +36,7 @@ #include "ssl_misc.h" #include "mbedtls/error.h" #include "mbedtls/platform_util.h" +#include "constant_time.h" #include diff --git a/library/ssl_misc.h b/library/ssl_misc.h index c8e2f4c88..856dd1e16 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1179,26 +1179,6 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ); int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src ); -/* constant-time buffer comparison */ -static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ) -{ - size_t i; - volatile const unsigned char *A = (volatile const unsigned char *) a; - volatile const unsigned char *B = (volatile const unsigned char *) b; - volatile unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - { - /* Read volatile data in order before computing diff. - * This avoids IAR compiler warning: - * 'the order of volatile accesses is undefined ..' */ - unsigned char x = A[i], y = B[i]; - diff |= x ^ y; - } - - return( diff ); -} - #if defined(MBEDTLS_SSL_PROTO_TLS1_2) /* The hash buffer must have at least MBEDTLS_MD_MAX_SIZE bytes of length. */ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 34b28b1cb..168f18621 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -40,6 +40,7 @@ #include "mbedtls/error.h" #include "mbedtls/platform_util.h" #include "mbedtls/version.h" +#include "constant_time.h" #include "ssl_invasive.h" diff --git a/library/ssl_srv.c b/library/ssl_srv.c index d82ec0471..716fa7de1 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -34,6 +34,7 @@ #include "mbedtls/debug.h" #include "mbedtls/error.h" #include "mbedtls/platform_util.h" +#include "constant_time.h" #include diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 923c671a7..c5ffa4dbb 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -39,6 +39,7 @@ #include "mbedtls/error.h" #include "mbedtls/platform_util.h" #include "mbedtls/version.h" +#include "constant_time.h" #include