Detect Year 2038 Rollover #362

Open
opened 2025-07-07 19:44:01 -05:00 by dpkristensen · 8 comments
dpkristensen commented 2025-07-07 19:44:01 -05:00 (Migrated from github.com)

Suggested enhancement

In include/mbedtls/platform_time.h when MBEDTLS_PLATFORM_TIME_TYPE_MACRO is undefined, generate a build error when sizeof(time_t) == 4.

Justification

TF-PSA-Crypto needs this because the year 2038 is coming up quickly and there are some implementations out there where there may be a potential rollover. In many cases (certainly most GCC compilers) time() will return a value based on the POSIX epoch, which will roll over in the year 2038. There are some cases where this wouldn't be a problem, such as:

  • time library functions are overridden to use a different epoch later than 2038.
  • The user has already accounted for this and defined an override for it.

Many modern implementations of GCC use a 64-bit time_t, but there are still some out there which are quite old and are using mbedtls. I am working with a system which still has code from the 90's using GCC 4.2.1 for M68K which uses a 32-bit time_t and suffers from the rollover problem. The board vendor supplied GCC, integration code, platform framework, and other code all together. The filesystem is a very old proprietary closed-source binary that has link-time references to time(); so changing the compiler to use a 64-bit timestamp would make it impossible to link.

This ticket isn't about my woes, though. I only stumbled upon this problem during code inspection, and there are likely other users out there who are not aware of this impact. Based on my initial analysis, it looks like there might be some impact when 2025 becomes 55 years in the future, from the perspective of 1970.

I think that customers who are already overriding time functions to use a different epoch are probably capable of setting MBEDTLS_PLATFORM_TIME_TYPE_MACRO appropriately as an integration change, and the other customers it affects using compilers with 32-bit time_t implementations probably need to know that something unexpected could happen.

### Suggested enhancement In include/mbedtls/platform_time.h when MBEDTLS_PLATFORM_TIME_TYPE_MACRO is undefined, generate a build error when sizeof(time_t) == 4. ### Justification TF-PSA-Crypto needs this because the year 2038 is coming up quickly and there are some implementations out there where there may be a potential rollover. In many cases (certainly most GCC compilers) time() will return a value based on the POSIX epoch, which will roll over in the year 2038. There are some cases where this wouldn't be a problem, such as: * time library functions are overridden to use a different epoch later than 2038. * The user has already accounted for this and defined an override for it. Many modern implementations of GCC use a 64-bit time_t, but there are still some out there which are quite old and are using mbedtls. I am working with a system which still has code from the 90's using GCC 4.2.1 for M68K which uses a 32-bit time_t and suffers from the rollover problem. The board vendor supplied GCC, integration code, platform framework, and other code all together. The filesystem is a very old proprietary closed-source binary that has link-time references to time(); so changing the compiler to use a 64-bit timestamp would make it impossible to link. This ticket isn't about my woes, though. I only stumbled upon this problem during code inspection, and there are likely other users out there who are not aware of this impact. Based on my initial analysis, it looks like there might be some impact when 2025 becomes 55 years in the future, from the perspective of 1970. I think that customers who are already overriding time functions to use a different epoch are probably capable of setting MBEDTLS_PLATFORM_TIME_TYPE_MACRO appropriately as an integration change, and the other customers it affects using compilers with 32-bit time_t implementations probably need to know that something unexpected could happen.
minosgalanakis commented 2025-07-10 07:12:22 -05:00 (Migrated from github.com)

Thank you very much for your report and suggestion!

We’re considering your proposal to require an explicit step when a 32-bit time_t is detected.

Could you please clarify what you mean by:

“…there might be some impact when 2025 becomes 55 years in the future, from the perspective of 1970.”

Specifically, how did you arrive at the 55-year window and its potential impacts?

Thank you very much for your report and suggestion! We’re considering your proposal to require an explicit step when a 32-bit time_t is detected. Could you please clarify what you mean by: > “…there might be some impact when 2025 becomes 55 years in the future, from the perspective of 1970.” Specifically, how did you arrive at the 55-year window and its potential impacts?
dpkristensen commented 2025-07-10 23:52:59 -05:00 (Migrated from github.com)

In the POSIX time system, a negative absolute timestamp is undefined (ISO C returns -1 as an error code from time(), and POSIX follows this too). So timestamps before 1970 could be interpreted mathematically as a negative offset from 1970 or an invalid time.

2025 is just a sample data point. 2025 - 1970 = 55. If a certificate was issued with a valid date beginning this year, it would be invalid if the system thought it was currently 1970 or before.

In the POSIX time system, a negative absolute timestamp is undefined (ISO C returns -1 as an error code from time(), and POSIX follows this too). So timestamps before 1970 could be interpreted mathematically as a negative offset from 1970 or an invalid time. 2025 is just a sample data point. 2025 - 1970 = 55. If a certificate was issued with a valid date beginning this year, it would be invalid if the system thought it was currently 1970 or before.
dpkristensen commented 2025-07-10 23:59:07 -05:00 (Migrated from github.com)

Also difftime() should return a NULL pointer when one of the input times is invalid.

Also difftime() should return a NULL pointer when one of the input times is invalid.
dpkristensen commented 2025-07-11 06:57:24 -05:00 (Migrated from github.com)

Also a colleague of mine provided some additional references for documented cases that affects devices out in the wild already:

Also a colleague of mine provided some additional references for documented cases that affects devices out in the wild already: * ESP-IDF v4 or lower: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/system_time.html#unix-time-2038-overflow * glibc 32 bits defaults: https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html#index-_005fTIME_005fBITS
rsaxvc commented 2025-07-11 07:09:02 -05:00 (Migrated from github.com)

Several SDKs I've worked with came with a patched toolchain, which adds an organizational dependency if 64-bit time_t is the preferred solution.

Given that the default glibc time_t for multiple 32-bit systems including Arm is still 32-bit, the latency in discovering the actual impact, and the lifetimes of some embedded products, I absolutely agree a build time warning should help by providing more time to remediate early.

Several SDKs I've worked with came with a patched toolchain, which adds an organizational dependency if 64-bit time_t is the preferred solution. Given that the default glibc time_t for multiple 32-bit systems including Arm [is still 32-bit](https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html#index-_005fTIME_005fBITS), the latency in discovering the actual impact, and the lifetimes of some embedded products, I absolutely agree a build time warning should help by providing more time to remediate early.
gilles-peskine-arm commented 2025-07-11 07:47:58 -05:00 (Migrated from github.com)

We're going to consider this for TF-PSA-Crypto 1.0 (for the sake of X.509, really, but the time abstraction is provided by TF-PSA-Crypto for historical reasons).

We're going to consider this for TF-PSA-Crypto 1.0 (for the sake of X.509, really, but the time abstraction is provided by TF-PSA-Crypto for historical reasons).
dpkristensen commented 2025-07-11 09:12:51 -05:00 (Migrated from github.com)

@gilles-peskine-arm you are correct that it shouldn't be the responsibility of the test framework. The time handling was moved out of mbedtls, so it seems the responsibility has shifted. I have opened an issue with PSA Crypto as the PSA API should be responsible for providing a time source suitable for cryptographic needs.

@gilles-peskine-arm you are correct that it shouldn't be the responsibility of the test framework. The time handling was moved out of mbedtls, so it seems the responsibility has shifted. I have opened an issue with PSA Crypto as the PSA API should be responsible for providing a time source suitable for cryptographic needs.
gilles-peskine-arm commented 2025-07-11 09:24:57 -05:00 (Migrated from github.com)

PSA crypto does not concern itself with time. It's only about cryptographic primitives and key management, not about PKI. If we were designing a product from scratch, I'd expect the “what date/time is it?” abstraction would go alongside the X.509 library.

The reasons why the time abstraction is in TF-PSA-Crypto are historical: it's part of the main platform abstraction (excluding threading and net) which we don't have time to split right now, and it's used in the crypto benchmark program.

PSA crypto does not concern itself with time. It's only about cryptographic primitives and key management, not about PKI. If we were designing a product from scratch, I'd expect the “what date/time is it?” abstraction would go alongside the X.509 library. The reasons why the time abstraction is in TF-PSA-Crypto are historical: it's part of the main platform abstraction (excluding threading and net) which we don't have time to split right now, and it's used in the crypto benchmark program.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-Mbed-TLS/TF-PSA-Crypto#362
No description provided.