Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use gmtime() when neither gmtime_r nor gmtime_s are available #1927

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
ce6eebb
Use gmtime when target is not windows or posix
Aug 7, 2018
824dfb3
Add ChangeLog entry for use of gmtime
Aug 7, 2018
97f3ecb
Document dependency on gmtime, gmtime_r & gmtime_s
Aug 7, 2018
d717743
Fix check-names.sh fail with USE_GMTIME macro
Aug 8, 2018
1abb368
Make gmtime() configurable at compile-time
Aug 16, 2018
a7b9f15
Add ChangeLog entry for configurable gmtime() in platform
Aug 16, 2018
248e27c
Remove redundant statement from x509_get_current_time
Aug 16, 2018
c99b12b
Fix documentation for MBEDTLS_HAVE_DATE_TIME
Aug 21, 2018
a658d7d
Fix style for mbedtls_platform_gmtime()
Aug 21, 2018
c2f948b
Fix grammar in docs for MBEDTLS_HAVE_TIME_DATE
Sep 5, 2018
e9b10b2
Define _POSIX_C_SOURCE in threading.c before POSIX detection
Sep 5, 2018
2099606
Use gmtime_s() for IAR
Sep 5, 2018
8c9a620
Fix missing word in ChangeLog entry for gmtime()
Sep 5, 2018
ca04a01
Document shorthand gmtime macros
Sep 5, 2018
193fe89
Add missing _POSIX_C_SOURCE define in threading.h
Sep 5, 2018
3c9733a
Fix typo in comment for gmtime macro defines
Sep 5, 2018
c29c34c
Improve wording of gmtime feature in ChangeLog
Sep 5, 2018
e58088e
Clarify docs for MBEDTLS_HAVE_TIME_DATE
Sep 5, 2018
433f911
Check for IAR in gmtime macros
Sep 5, 2018
45e3020
Document that IAR gmtime_s() is auto selected
Sep 5, 2018
94b540a
Avoid redefining _POSIX_C_SOURCE
Sep 5, 2018
cfeb70c
gmtime: Remove special treatment for IAR
Sep 5, 2018
272675f
Correct documentation of mbedtls_platform_gmtime()
Sep 5, 2018
5f95c79
Remove another mentioning of IAR from config.h
Sep 5, 2018
be2e4bd
Guard decl and use of gmtime mutex by HAVE_TIME_DATE and !GMTIME_ALT
Sep 5, 2018
6a73978
Rename mbedtls_platform_gmtime() to mbedtls_platform_gmtime_r()
Sep 5, 2018
651d586
Style: Add missing period in documentation in threading.h
Sep 5, 2018
48a816f
Minor documentation improvements
Sep 5, 2018
4e67cca
Improve documentation of MBEDTLS_HAVE_TIME_DATE
Sep 5, 2018
acef292
ChangeLog: Add missing renamings gmtime -> gmtime_r
Sep 5, 2018
9a51d01
Improve documentation of MBEDTLS_HAVE_TIME_DATE
Sep 5, 2018
921b76d
Replace 'thread safe' by 'thread-safe' in the documentation
Sep 5, 2018
c946888
Fix typo in documentation of MBEDTLS_PLATFORM_GMTIME_R_ALT
Sep 5, 2018
9fbbf1c
Improve wording of documentation of MBEDTLS_PLATFORM_GMTIME_R_ALT
Sep 5, 2018
5a7fe14
Don't include platform_time.h if !MBEDTLS_HAVE_TIME
Sep 5, 2018
7dd82b4
platform_utils.{c/h} -> platform_util.{c/h}
Sep 5, 2018
c52ef40
Improve documentation of mbedtls_platform_gmtime_r()
Sep 5, 2018
6f70581
Correct POSIX version check to determine presence of gmtime_r()
Sep 6, 2018
a50fed9
Correct typo in documentation of mbedtls_platform_gmtime_r()
Sep 6, 2018
03b2bd4
Correct documentation of mbedtls_platform_gmtime_r()
Sep 6, 2018
323d801
Correct preprocessor guards determining use of gmtime()
Sep 6, 2018
f5106d5
Don't declare and define gmtime()-mutex on Windows platforms
Sep 6, 2018
d2ef254
Don't define _POSIX_C_SOURCE in header file
Sep 6, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@ mbed TLS ChangeLog (Sorted per branch, date)

= mbed TLS x.x.x branch released xxxx-xx-xx

API Changes
* Extend the platform module with an abstraction mbedtls_platform_gmtime_r()
whose implementation should behave as a thread-safe version of gmtime().
This allows users to configure such an implementation at compile time when
the target system cannot be deduced automatically, by setting the option
MBEDTLS_PLATFORM_GMTIME_R_ALT. At this stage Mbed TLS is only able to
automatically select implementations for Windows and POSIX C libraries.

Bugfix
* Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if
MBEDTLS_ARC4_C and MBEDTLS_CIPHER_NULL_CIPHER weren't also defined. #1890
* Fix build failures on platforms where only gmtime() is available but
neither gmtime_r() nor gmtime_s() are present. Fixes #1907.

= mbed TLS 2.12.0 branch released 2018-07-25

Expand Down
30 changes: 29 additions & 1 deletion include/mbedtls/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,21 @@
/**
* \def MBEDTLS_HAVE_TIME_DATE
*
* System has time.h and time(), gmtime() and the clock is correct.
* System has time.h, time(), and an implementation for
* mbedtls_platform_gmtime_r() (see below).
* The time needs to be correct (not necesarily very accurate, but at least
* the date should be correct). This is used to verify the validity period of
* X.509 certificates.
*
* Comment if your system does not have a correct clock.
*
* \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that
* behaves similarly to the gmtime_r() function from the C standard. Refer to
* the documentation for mbedtls_platform_gmtime_r() for more information.
*
* \note It is possible to configure an implementation for
* mbedtls_platform_gmtime_r() at compile-time by using the macro
* MBEDTLS_PLATFORM_GMTIME_R_ALT.
*/
#define MBEDTLS_HAVE_TIME_DATE

Expand Down Expand Up @@ -3083,6 +3092,25 @@
*/
//#define MBEDTLS_PLATFORM_ZEROIZE_ALT

/**
* Uncomment the macro to let Mbed TLS use your alternate implementation of
* mbedtls_platform_gmtime_r(). This replaces the default implementation in
* platform_util.c.
*
* gmtime() is not a thread-safe function as defined in the C standard. The
* library will try to use safer implementations of this function, such as
* gmtime_r() when available. However, if Mbed TLS cannot identify the target
* system, the implementation of mbedtls_platform_gmtime_r() will default to
* using the standard gmtime(). In this case, calls from the library to
* gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex
* if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the
* library are also guarded with this mutex to avoid race conditions. However,
* if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will
* unconditionally use the implementation for mbedtls_platform_gmtime_r()
* supplied at compile time.
*/
//#define MBEDTLS_PLATFORM_GMTIME_R_ALT

/* \} name SECTION: Customisation configuration options */

/* Target and application specific configurations */
Expand Down
41 changes: 41 additions & 0 deletions include/mbedtls/platform_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,17 @@
#ifndef MBEDTLS_PLATFORM_UTIL_H
#define MBEDTLS_PLATFORM_UTIL_H

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#include <stddef.h>
#if defined(MBEDTLS_HAVE_TIME_DATE)
#include "mbedtls/platform_time.h"
#include <time.h>
#endif /* MBEDTLS_HAVE_TIME_DATE */

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -55,6 +65,37 @@ extern "C" {
*/
void mbedtls_platform_zeroize( void *buf, size_t len );

#if defined(MBEDTLS_HAVE_TIME_DATE)
/**
* \brief Platform-specific implementation of gmtime_r()
*
* The function is a thread-safe abstraction that behaves
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd at least put an asterisk after "thread-safe", that points to the explanation below, regarding the necessity of respecting of the critical section that we define. "Thread-safe" is an extremely strict term, and race conditions are difficult to detect and debug, so I think we may consider being extra careful about the multi-threading related wording here.

* similarly to the gmtime_r() function from Unix/POSIX.
*
* Mbed TLS will try to identify the underlying platform and
* make use of an appropriate underlying implementation (e.g.
* gmtime_r() for POSIX and gmtime_s() for Windows). If this is
* not possible, then gmtime() will be used. In this case, calls
* from the library to gmtime() will be guarded by the mutex
* mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is
* enabled. It is recommended that calls from outside the library
* are also guarded by this mutex.
*
* If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will
* unconditionally use the alternative implementation for
* mbedtls_platform_gmtime_r() supplied by the user at compile time.
*
* \param tt Pointer to an object containing time (in seconds) since the
* epoch to be converted
* \param tm_buf Pointer to an object where the results will be stored
*
* \return Pointer to an object of type struct tm on success, otherwise
* NULL
*/
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the Unix/POSIX gmtime_r, which is widely available in practice but not standard C. Since we're introducing a new API, maybe we should instead pick gmtime_s, which is standard C since C11, even though it isn't widely available? It doesn't matter much since the conversion between gmtime_r and gmtime_s is very simple.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stuck to gmtime_r for now to not deviate too far from the state of the previous approvals - I have no strong opinion on using gmtime_s vs. gmtime_r.

struct tm *tm_buf );
#endif /* MBEDTLS_HAVE_TIME_DATE */

#ifdef __cplusplus
}
#endif
Expand Down
11 changes: 11 additions & 0 deletions include/mbedtls/threading.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex );
#if defined(MBEDTLS_FS_IO)
extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
#endif

#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
/* This mutex may or may not be used in the default definition of
* mbedtls_platform_gmtime_r(), but in order to determine that,
* we need to check POSIX features, hence modify _POSIX_C_SOURCE.
* With the current approach, this declaration is orphaned, lacking
* an accompanying definition, in case mbedtls_platform_gmtime_r()
* doesn't need it, but that's not a problem. */
extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */

#endif /* MBEDTLS_THREADING_C */

#ifdef __cplusplus
Expand Down
68 changes: 68 additions & 0 deletions library/platform_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,22 @@
* This file is part of Mbed TLS (https://tls.mbed.org)
*/

/*
* Ensure gmtime_r is available even with -std=c99; must be defined before
* config.h, which pulls in glibc's features.h. Harmless on other platforms.
*/
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 200112L
#endif

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#include "mbedtls/platform_util.h"
#include "mbedtls/threading.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be surrounded by #if defined(MBEDTLS_THREADING_C)?

Copy link

@hanno-becker hanno-becker Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, but then we should also guard it by the other flags determining whether we call back to our default mbedtls_platform_gmtime_r() implementation. I'm inclined to leave it as is for readability.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this include is not used otherwise, but I'll leave the decision up to you.


#include <stddef.h>
#include <string.h>
Expand Down Expand Up @@ -65,3 +74,62 @@ void mbedtls_platform_zeroize( void *buf, size_t len )
memset_func( buf, 0, len );
}
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */

#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
#include <time.h>
#if !defined(_WIN32) && (defined(unix) || \
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
defined(__MACH__)))
#include <unistd.h>
#endif /* !_WIN32 && (unix || __unix || __unix__ ||
* (__APPLE__ && __MACH__)) */

#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
/*
* This is a convenience shorthand macro to avoid checking the long
* preprocessor conditions above. Ideally, we could expose this macro in
* platform_util.h and simply use it in platform_util.c, threading.c and
* threading.h. However, this macro is not part of the Mbed TLS public API, so
* we keep it private by only defining it in this file
*/
#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two complex defines one after another here. if A { if B { x } } effectively means if A & B { x }. Why are they separated?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree these are complex, but I believe this was removed with d2ef254

#define PLATFORM_UTIL_USE_GMTIME
#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */

#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */

struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
struct tm *tm_buf )
{
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL );
#elif !defined(PLATFORM_UTIL_USE_GMTIME)
return( gmtime_r( tt, tm_buf ) );
#else
struct tm *lt;

#if defined(MBEDTLS_THREADING_C)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this check for defined(MBEDTLS_THREADING_C) necessary? The reason gmtime() was originally removed by @NWilson is because it's not thread safe, and if we're putting gmtime() back in, it needs to be threadsafe, and having locks shouldn't be optional.

Better in my view, to remove them and add to check_config.h a dependency on MBEDTLS_THREADING_C if MBEDTLS_HAVE_TIME_DATE is defined, for platforms that don't have gmtime().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While in principle I agree with this view. Forcing MBEDTLS_HAVE_TIME_DATE to depend on MBEDTLS_THREADING_C changes the API. Also, consider that not every platform that uses MBEDTLS_HAVE_TIME_DATE will be multithreaded.

Copy link
Contributor

@mpg mpg Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the code is fine as it is: as Andres said, gmtime() is perfectly fine for single-threaded platforms, and for multi-threaded platforms, there are already plenty of reasons why they need to define MBEDTLS_THREADING_C anyway, so this change is not introducing any new requirement. We never promised to work in threaded environments without MBEDTLS_THREADING_C.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed my mind on this, because we do run on some single threaded systems that don't have gmtime_r(), but gmtime() is available. I think it's fine as it is.

if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
return( NULL );
#endif /* MBEDTLS_THREADING_C */

lt = gmtime( tt );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What shall we do if the platform doesn't support gmtime(), as in the case of armcc?

/Maybe/ we should assume if MBEDTLS_HAVE_TIME_DATE is enabled, that at least one of gmtime_r(), gmtime_s(), or gmtime() are present, and if for Mbed OS there's no gmtime() present, we'll just have to provide one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR already accommodates for those situations

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, for armcc we would define MBEDTLS_HAVE_TIME_DATE but require a custom mbedtls_platform_gmtime() through MBEDTLS_PLATFORM_GMTIME_ALT, is that right @andresag01 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Andres, I think the documentation for HAVE_TIME_DATE is already explicit enough about the requirement that one of the time functions (including the platform-provided one if any) needs to be available and working.


if( lt != NULL )
{
memcpy( tm_buf, lt, sizeof( struct tm ) );
}

#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 )
return( NULL );
#endif /* MBEDTLS_THREADING_C */

return( ( lt == NULL ) ? NULL : tm_buf );
#endif /* _WIN32 && !EFIX64 && !EFI32 */
}
#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */
47 changes: 47 additions & 0 deletions library/threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
* This file is part of mbed TLS (https://tls.mbed.org)
*/

/*
* Ensure gmtime_r is available even with -std=c99; must be defined before
* config.h, which pulls in glibc's features.h. Harmless on other platforms.
*/
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 200112L
#endif

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
Expand All @@ -29,6 +37,36 @@

#include "mbedtls/threading.h"

#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)

#if !defined(_WIN32) && (defined(unix) || \
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
defined(__MACH__)))
#include <unistd.h>
#endif /* !_WIN32 && (unix || __unix || __unix__ ||
* (__APPLE__ && __MACH__)) */

#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
/*
* This is a convenience shorthand macro to avoid checking the long
* preprocessor conditions above. Ideally, we could expose this macro in
* platform_util.h and simply use it in platform_util.c, threading.c and
* threading.h. However, this macro is not part of the Mbed TLS public API, so
* we keep it private by only defining it in this file
*/

#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
#define THREADING_USE_GMTIME
#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */

#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */

#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */

#if defined(MBEDTLS_THREADING_PTHREAD)
static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
{
Expand Down Expand Up @@ -114,6 +152,9 @@ void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t *
#if defined(MBEDTLS_FS_IO)
mbedtls_mutex_init( &mbedtls_threading_readdir_mutex );
#endif
#if defined(THREADING_USE_GMTIME)
mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex );
#endif
}

/*
Expand All @@ -124,6 +165,9 @@ void mbedtls_threading_free_alt( void )
#if defined(MBEDTLS_FS_IO)
mbedtls_mutex_free( &mbedtls_threading_readdir_mutex );
#endif
#if defined(THREADING_USE_GMTIME)
mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex );
#endif
}
#endif /* MBEDTLS_THREADING_ALT */

Expand All @@ -136,5 +180,8 @@ void mbedtls_threading_free_alt( void )
#if defined(MBEDTLS_FS_IO)
mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT;
#endif
#if defined(THREADING_USE_GMTIME)
mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT;
#endif

#endif /* MBEDTLS_THREADING_C */
11 changes: 2 additions & 9 deletions library/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
*/

/* Ensure gmtime_r is available even with -std=c99; must be included before
* config.h, which pulls in glibc's features.h. Harmless on other platforms. */
#define _POSIX_C_SOURCE 200112L

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
Expand Down Expand Up @@ -67,6 +63,7 @@
#include "mbedtls/platform_time.h"
#endif
#if defined(MBEDTLS_HAVE_TIME_DATE)
#include "mbedtls/platform_util.h"
#include <time.h>
#endif

Expand Down Expand Up @@ -901,11 +898,7 @@ static int x509_get_current_time( mbedtls_x509_time *now )
int ret = 0;

tt = mbedtls_time( NULL );
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
lt = gmtime_s( &tm_buf, &tt ) == 0 ? &tm_buf : NULL;
#else
lt = gmtime_r( &tt, &tm_buf );
#endif
lt = mbedtls_platform_gmtime_r( &tt, &tm_buf );

if( lt == NULL )
ret = -1;
Expand Down