Merge pull request #3624 from daxtens/timeless

RFC: Fix builds with MBEDTLS_HAVE_TIME disabled and test
diff --git a/ChangeLog.d/timeless.txt b/ChangeLog.d/timeless.txt
new file mode 100644
index 0000000..84f07d6
--- /dev/null
+++ b/ChangeLog.d/timeless.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix compile errors when MBEDTLS_HAVE_TIME is not defined. Add tests
+     to catch bad uses of time.h.
diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h
index 11a9ca1..a598434 100644
--- a/include/mbedtls/platform.h
+++ b/include/mbedtls/platform.h
@@ -62,7 +62,9 @@
 #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
 #include <stdio.h>
 #include <stdlib.h>
+#if defined(MBEDTLS_HAVE_TIME)
 #include <time.h>
+#endif
 #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
 #if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
 #define MBEDTLS_PLATFORM_STD_SNPRINTF   mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use.  */
diff --git a/library/net_sockets.c b/library/net_sockets.c
index 17a9e4a..d1700f3 100644
--- a/library/net_sockets.c
+++ b/library/net_sockets.c
@@ -107,7 +107,9 @@
 
 #include <stdio.h>
 
+#if defined(MBEDTLS_HAVE_TIME)
 #include <time.h>
+#endif
 
 #include <stdint.h>
 
diff --git a/library/timing.c b/library/timing.c
index 8a02c00..d66e11e 100644
--- a/library/timing.c
+++ b/library/timing.c
@@ -45,15 +45,15 @@
 
 #include <unistd.h>
 #include <sys/types.h>
-#include <sys/time.h>
 #include <signal.h>
+#if defined(MBEDTLS_HAVE_TIME)
 #include <time.h>
-
+#include <sys/time.h>
 struct _hr_time
 {
     struct timeval start;
 };
-
+#endif
 #endif /* _WIN32 && !EFIX64 && !EFI32 */
 
 /**
@@ -75,6 +75,7 @@
  *                 get_timer(0) }` the value time1+time2 is only approximately
  *                 the delay since the first reset.
  */
+#if defined(MBEDTLS_HAVE_TIME)
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 
 unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
@@ -157,6 +158,26 @@
 
     return( 0 );
 }
+#else
+int mbedtls_timing_get_delay( void *data )
+{
+    (void) data;
+    return( 0 );
+}
 
+void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms )
+{
+    (void) data;
+    (void) int_ms;
+    (void) fin_ms;
+}
+
+unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
+{
+    (void) val;
+    (void) reset;
+    return( 0 );
+}
+#endif /* MBEDTLS_HAVE_TIME */
 #endif /* !MBEDTLS_TIMING_ALT */
 #endif /* MBEDTLS_TIMING_C */
diff --git a/library/x509_crl.c b/library/x509_crl.c
index e6efdca..0cd996d 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -52,11 +52,13 @@
 #define mbedtls_snprintf   snprintf
 #endif
 
+#if defined(MBEDTLS_HAVE_TIME)
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 #include <windows.h>
 #else
 #include <time.h>
 #endif
+#endif
 
 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
 #include <stdio.h>
diff --git a/library/x509_crt.c b/library/x509_crt.c
index d19502c..b38dff08 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -63,11 +63,13 @@
 #include "mbedtls/threading.h"
 #endif
 
+#if defined(MBEDTLS_HAVE_TIME)
 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 #include <windows.h>
 #else
 #include <time.h>
 #endif
+#endif
 
 #if defined(MBEDTLS_FS_IO)
 #include <stdio.h>
diff --git a/programs/fuzz/common.c b/programs/fuzz/common.c
index 4d58402..c554bc6 100644
--- a/programs/fuzz/common.c
+++ b/programs/fuzz/common.c
@@ -5,11 +5,13 @@
 #include <stdlib.h>
 #include "mbedtls/ctr_drbg.h"
 
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
 mbedtls_time_t dummy_constant_time( mbedtls_time_t* time )
 {
     (void) time;
     return 0x5af2a056;
 }
+#endif
 
 void dummy_init()
 {
diff --git a/programs/fuzz/common.h b/programs/fuzz/common.h
index 5586c06..7bb7b87 100644
--- a/programs/fuzz/common.h
+++ b/programs/fuzz/common.h
@@ -1,4 +1,9 @@
+#include "mbedtls/build_info.h"
+
+#if defined(MBEDTLS_HAVE_TIME)
 #include "mbedtls/platform_time.h"
+#endif
+#include <stddef.h>
 #include <stdint.h>
 
 typedef struct fuzzBufferOffset
@@ -8,7 +13,9 @@
     size_t Offset;
 } fuzzBufferOffset_t;
 
+#if defined(MBEDTLS_HAVE_TIME)
 mbedtls_time_t dummy_constant_time( mbedtls_time_t* time );
+#endif
 void dummy_init();
 
 int dummy_send( void *ctx, const unsigned char *buf, size_t len );
diff --git a/programs/ssl/ssl_context_info.c b/programs/ssl/ssl_context_info.c
index 62c3cc5..19054eb 100644
--- a/programs/ssl/ssl_context_info.c
+++ b/programs/ssl/ssl_context_info.c
@@ -42,7 +42,9 @@
 #include <stdint.h>
 #include <stdarg.h>
 #include <string.h>
+#if defined(MBEDTLS_HAVE_TIME)
 #include <time.h>
+#endif
 #include "mbedtls/ssl.h"
 #include "mbedtls/error.h"
 #include "mbedtls/base64.h"
@@ -307,10 +309,11 @@
 /*
  *  Print the value of time_t in format e.g. 2020-01-23 13:05:59
  */
-void print_time( const time_t *time )
+void print_time( const uint64_t *time )
 {
+#if defined(MBEDTLS_HAVE_TIME)
     char buf[20];
-    struct tm *t = gmtime( time );
+    struct tm *t = gmtime( (time_t*) time );
     static const char format[] = "%Y-%m-%d %H:%M:%S";
     if( NULL != t )
     {
@@ -321,6 +324,10 @@
     {
         printf( "unknown\n" );
     }
+#else
+    (void) time;
+    printf( "not supported\n" );
+#endif
 }
 
 /*
@@ -608,7 +615,7 @@
                 ( (uint64_t) ssl[7] );
         ssl += 8;
         printf( "\tstart time     : " );
-        print_time( (time_t*) &start );
+        print_time( &start );
     }
 
     CHECK_SSL_END( 2 );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 802078c..02919b4 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -317,10 +317,16 @@
 
 #if defined(MBEDTLS_SSL_CACHE_C)
 #define USAGE_CACHE                                             \
-    "    cache_max=%%d        default: cache default (50)\n"    \
+    "    cache_max=%%d        default: cache default (50)\n"
+#if defined(MBEDTLS_HAVE_TIME)
+#define USAGE_CACHE_TIME \
     "    cache_timeout=%%d    default: cache default (1d)\n"
 #else
+#define USAGE_CACHE_TIME ""
+#endif
+#else
 #define USAGE_CACHE ""
+#define USAGE_CACHE_TIME ""
 #endif /* MBEDTLS_SSL_CACHE_C */
 
 #if defined(SNI_OPTION)
@@ -509,6 +515,7 @@
     USAGE_NSS_KEYLOG                                        \
     USAGE_NSS_KEYLOG_FILE                                   \
     USAGE_CACHE                                             \
+    USAGE_CACHE_TIME                                        \
     USAGE_MAX_FRAG_LEN                                      \
     USAGE_ALPN                                              \
     USAGE_EMS                                               \
@@ -619,7 +626,9 @@
     int ticket_timeout;         /* session ticket lifetime                  */
     int ticket_aead;            /* session ticket protection                */
     int cache_max;              /* max number of session cache entries      */
-    int cache_timeout;          /* expiration delay of session cache entries */
+#if defined(MBEDTLS_HAVE_TIME)
+    int cache_timeout;          /* expiration delay of session cache entries*/
+#endif
     char *sni;                  /* string describing sni information        */
     const char *curves;         /* list of supported elliptic curves        */
     const char *sig_algs;       /* supported TLS 1.3 signature algorithms   */
@@ -1581,7 +1590,9 @@
     opt.ticket_timeout      = DFL_TICKET_TIMEOUT;
     opt.ticket_aead         = DFL_TICKET_AEAD;
     opt.cache_max           = DFL_CACHE_MAX;
+#if defined(MBEDTLS_HAVE_TIME)
     opt.cache_timeout       = DFL_CACHE_TIMEOUT;
+#endif
     opt.sni                 = DFL_SNI;
     opt.alpn_string         = DFL_ALPN_STRING;
     opt.curves              = DFL_CURVES;
@@ -1977,12 +1988,14 @@
             if( opt.cache_max < 0 )
                 goto usage;
         }
+#if defined(MBEDTLS_HAVE_TIME)
         else if( strcmp( p, "cache_timeout" ) == 0 )
         {
             opt.cache_timeout = atoi( q );
             if( opt.cache_timeout < 0 )
                 goto usage;
         }
+#endif
         else if( strcmp( p, "cookies" ) == 0 )
         {
             opt.cookies = atoi( q );
@@ -2755,8 +2768,10 @@
     if( opt.cache_max != -1 )
         mbedtls_ssl_cache_set_max_entries( &cache, opt.cache_max );
 
+#if defined(MBEDTLS_HAVE_TIME)
     if( opt.cache_timeout != -1 )
         mbedtls_ssl_cache_set_timeout( &cache, opt.cache_timeout );
+#endif
 
     mbedtls_ssl_conf_session_cache( &conf, &cache,
                                    mbedtls_ssl_cache_get,
diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c
index 04e127a..a28a477 100644
--- a/programs/ssl/ssl_test_lib.c
+++ b/programs/ssl/ssl_test_lib.c
@@ -46,11 +46,13 @@
     fflush( (FILE *) ctx  );
 }
 
+#if defined(MBEDTLS_HAVE_TIME)
 mbedtls_time_t dummy_constant_time( mbedtls_time_t* time )
 {
     (void) time;
     return 0x5af2a056;
 }
+#endif
 
 #if !defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
 static int dummy_entropy( void *data, unsigned char *output, size_t len )
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
index ff02492..b3c4cfa 100644
--- a/programs/ssl/ssl_test_lib.h
+++ b/programs/ssl/ssl_test_lib.h
@@ -129,7 +129,9 @@
                const char *file, int line,
                const char *str );
 
+#if defined(MBEDTLS_HAVE_TIME)
 mbedtls_time_t dummy_constant_time( mbedtls_time_t* time );
+#endif
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 /* If MBEDTLS_TEST_USE_PSA_CRYPTO_RNG is defined, the SSL test programs will use
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index d3faad9..569f147 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -30,10 +30,10 @@
 #define mbedtls_free       free
 #endif
 
-#if !defined(MBEDTLS_TIMING_C)
+#if !defined(MBEDTLS_HAVE_TIME)
 int main( void )
 {
-    mbedtls_printf("MBEDTLS_TIMING_C not defined.\n");
+    mbedtls_printf("MBEDTLS_HAVE_TIME not defined.\n");
     mbedtls_exit( 0 );
 }
 #else
@@ -41,8 +41,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include "mbedtls/timing.h"
-
 #include "mbedtls/md5.h"
 #include "mbedtls/ripemd160.h"
 #include "mbedtls/sha1.h"
@@ -1304,4 +1302,4 @@
     mbedtls_exit( 0 );
 }
 
-#endif /* MBEDTLS_TIMING_C */
+#endif /* MBEDTLS_HAVE_TIME */
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index 6546e8f..bc78fab 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -32,9 +32,11 @@
 #else
 #include <stdio.h>
 #include <stdlib.h>
+#if defined(MBEDTLS_HAVE_TIME)
 #include <time.h>
 #define mbedtls_time            time
 #define mbedtls_time_t          time_t
+#endif
 #define mbedtls_printf          printf
 #define mbedtls_calloc          calloc
 #define mbedtls_free            free
@@ -71,7 +73,9 @@
 #endif
 #endif /* _MSC_VER */
 #else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
+#if defined(MBEDTLS_HAVE_TIME)
 #include <sys/time.h>
+#endif
 #include <sys/types.h>
 #include <unistd.h>
 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
@@ -821,6 +825,7 @@
 
     get_options( argc, argv );
 
+#if defined(MBEDTLS_HAVE_TIME)
     /*
      * Decisions to drop/delay/duplicate packets are pseudo-random: dropping
      * exactly 1 in N packets would lead to problems when a flight has exactly
@@ -831,11 +836,12 @@
      */
     if( opt.seed == 0 )
     {
-        opt.seed = (unsigned int) time( NULL );
+        opt.seed = (unsigned int) mbedtls_time( NULL );
         mbedtls_printf( "  . Pseudo-random seed: %u\n", opt.seed );
     }
 
     srand( opt.seed );
+#endif /* MBEDTLS_HAVE_TIME */
 
     /*
      * 0. "Connect" to the server
diff --git a/scripts/data_files/query_config.fmt b/scripts/data_files/query_config.fmt
index 8b0057c..fa124f0 100644
--- a/scripts/data_files/query_config.fmt
+++ b/scripts/data_files/query_config.fmt
@@ -67,7 +67,9 @@
 #include "mbedtls/pk.h"
 #include "mbedtls/pkcs12.h"
 #include "mbedtls/pkcs5.h"
+#if defined(MBEDTLS_HAVE_TIME)
 #include "mbedtls/platform_time.h"
+#endif
 #include "mbedtls/platform_util.h"
 #include "mbedtls/poly1305.h"
 #include "mbedtls/ripemd160.h"
diff --git a/tests/configs/config-wrapper-malloc-0-null.h b/tests/configs/config-wrapper-malloc-0-null.h
index e7bdbeb..b065c2d 100644
--- a/tests/configs/config-wrapper-malloc-0-null.h
+++ b/tests/configs/config-wrapper-malloc-0-null.h
@@ -21,6 +21,8 @@
 #include "mbedtls/mbedtls_config.h"
 
 #include <stdlib.h>
+
+#ifndef MBEDTLS_PLATFORM_STD_CALLOC
 static inline void *custom_calloc( size_t nmemb, size_t size )
 {
     if( nmemb == 0 || size == 0 )
@@ -30,3 +32,4 @@
 
 #define MBEDTLS_PLATFORM_MEMORY
 #define MBEDTLS_PLATFORM_STD_CALLOC custom_calloc
+#endif
diff --git a/tests/include/baremetal-override/time.h b/tests/include/baremetal-override/time.h
new file mode 100644
index 0000000..40eed2d
--- /dev/null
+++ b/tests/include/baremetal-override/time.h
@@ -0,0 +1,18 @@
+/*
+ *  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.
+ */
+
+#error "time.h included in a configuration without MBEDTLS_HAVE_TIME"
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index b162d30..3aab764 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1435,9 +1435,24 @@
 component_build_crypto_baremetal () {
   msg "build: make, crypto only, baremetal config"
   scripts/config.py crypto_baremetal
-  make CFLAGS='-O1 -Werror'
+  make CFLAGS="-O1 -Werror -I$PWD/tests/include/baremetal-override/"
   are_empty_libraries library/libmbedx509.* library/libmbedtls.*
 }
+support_build_crypto_baremetal () {
+    support_build_baremetal "$@"
+}
+
+component_build_baremetal () {
+  msg "build: make, baremetal config"
+  scripts/config.py baremetal
+  make CFLAGS="-O1 -Werror -I$PWD/tests/include/baremetal-override/"
+}
+support_build_baremetal () {
+    # Older Glibc versions include time.h from other headers such as stdlib.h,
+    # which makes the no-time.h-in-baremetal check fail. Ubuntu 16.04 has this
+    # problem, Ubuntu 18.04 is ok.
+    ! grep -q -F time.h /usr/include/x86_64-linux-gnu/sys/types.h
+}
 
 component_test_depends_curves () {
     msg "test/build: curves.pl (gcc)" # ~ 4 min
diff --git a/tests/suites/test_suite_timing.data b/tests/suites/test_suite_timing.data
index de89239..a45ed0e 100644
--- a/tests/suites/test_suite_timing.data
+++ b/tests/suites/test_suite_timing.data
@@ -1,8 +1,11 @@
 Timing: get timer
+depends_on:MBEDTLS_HAVE_TIME
 timing_get_timer:
 
 Timing: delay 0ms
+depends_on:MBEDTLS_HAVE_TIME
 timing_delay:0:
 
 Timing: delay 100ms
+depends_on:MBEDTLS_HAVE_TIME
 timing_delay:100: