diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 899a2f9cf5c..ddd42722c2d 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -1147,6 +1147,7 @@ WOLFSSL_OLD_TIMINGPADVERIFY WOLFSSL_OLD_UNSUPPORTED_EXTENSION WOLFSSL_OPENSSL_NO_BUILD_DATE WOLFSSL_OPTEE +WOLFSSL_OPTEE_ASN_TIME WOLFSSL_OPTIONS_IGNORE_SYS WOLFSSL_PASSTHRU_ERR WOLFSSL_PB diff --git a/src/internal.c b/src/internal.c index b7749f7ae81..4303fc744bf 100644 --- a/src/internal.c +++ b/src/internal.c @@ -11998,6 +11998,17 @@ ProtocolVersion MakeDTLSv1_3(void) } #endif +#elif defined(WOLFSSL_OPTEE) + word32 LowResTimer(void) + { + TEE_Time now; + + /* Monotonic within the TA, and not the normal world's clock. */ + TEE_GetSystemTime(&now); + + return (word32)now.seconds; + } + #elif defined(TIME_OVERRIDES) #if !defined(NO_ASN) && !defined(NO_ASN_TIME) /* use same asn time overrides unless user wants tick override above */ diff --git a/src/tls13.c b/src/tls13.c index 7cf731a3d2f..b7b2420bcfe 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2117,6 +2117,17 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store) } #endif +#elif defined(WOLFSSL_OPTEE) + word32 TimeNowInMilliseconds(void) + { + TEE_Time now; + + /* Monotonic within the TA, and not the normal world's clock. */ + TEE_GetSystemTime(&now); + + return (word32)((now.seconds * 1000) + now.millis); + } + #elif defined(TIME_OVERRIDES) #if !defined(NO_ASN) && !defined(NO_ASN_TIME) word32 TimeNowInMilliseconds(void) @@ -2400,6 +2411,17 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store) } #endif +#elif defined(WOLFSSL_OPTEE) + sword64 TimeNowInMilliseconds(void) + { + TEE_Time now; + + /* Monotonic within the TA, and not the normal world's clock. */ + TEE_GetSystemTime(&now); + + return ((sword64)now.seconds * 1000) + (sword64)now.millis; + } + #elif defined(TIME_OVERRIDES) #if !defined(NO_ASN) && !defined(NO_ASN_TIME) sword64 TimeNowInMilliseconds(void) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 0833afb7921..ec4b104b74d 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -19013,6 +19013,20 @@ void bench_mldsaKeySign(byte level) return ret; #endif } +#elif defined(WOLFSSL_OPTEE) + + double current_time(int reset) + { + TEE_Time now; + + (void)reset; + + /* Millisecond granularity, so short operations need iterations. */ + TEE_GetSystemTime(&now); + + return (double)now.seconds + ((double)now.millis / 1000.0); + } + #elif defined(WOLFSSL_ZEPHYR) #include diff --git a/wolfcrypt/src/cpuid.c b/wolfcrypt/src/cpuid.c index d4ceb4c9d9f..df47a611935 100644 --- a/wolfcrypt/src/cpuid.c +++ b/wolfcrypt/src/cpuid.c @@ -333,7 +333,10 @@ (&cpuid_flags, &old_cpuid_flags, new_cpuid_flags); } } -#elif defined(__linux__) +/* A trusted application is cross compiled with a Linux toolchain that + * predefines __linux__, but libutee has no getauxval, so it takes the + * compiled-in flags below instead. */ +#elif defined(__linux__) && !defined(WOLFSSL_OPTEE) /* https://community.arm.com/arm-community-blogs/b/operating-systems-blog/ * posts/runtime-detection-of-cpu-features-on-an-armv8-a-cpu */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 23b7eb2b744..3e64bf62907 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -221,6 +221,9 @@ This library contains implementation for the random number generator. #elif defined(WOLFSSL_DEOS) #elif defined(MICRIUM) #elif defined(WOLFSSL_NUCLEUS) +#elif defined(WOLFSSL_OPTEE) + /* for TEE_GenerateRandom */ + #include #elif defined(WOLFSSL_PB) #elif defined(WOLFSSL_ZEPHYR) #elif defined(WOLFSSL_TELIT_M2MB) @@ -10626,6 +10629,19 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } +#elif defined(WOLFSSL_OPTEE) + + /* Seeds the DRBG rather than replacing it; a build wanting the TEE RNG + * directly can still set CUSTOM_RAND_GENERATE_BLOCK. */ + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + (void)os; + + TEE_GenerateRandom(output, (size_t)sz); + + return 0; + } + #elif defined(WOLFSSL_PB) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 20263890bc1..33497227fe9 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -4940,6 +4940,25 @@ time_t fsl_time(time_t* t) } #endif +/* Matches the XTIME mapping's gate in wc_port.h, so this is not built when + * that mapping is excluded. */ +#if defined(WOLFSSL_OPTEE) && !defined(NO_ASN_TIME) + +time_t optee_time(time_t* timer) +{ + TEE_Time reeTime; + + /* Normal-world clock, so not a trusted time source. See wc_port.h. */ + TEE_GetREETime(&reeTime); + + if (timer != NULL) + *timer = (time_t)reeTime.seconds; + + return (time_t)reeTime.seconds; +} + +#endif /* WOLFSSL_OPTEE && !NO_ASN_TIME */ + #if defined(MICRIUM) time_t micrium_time(time_t* timer) diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 0400501fcb6..b25f56b5b04 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -3525,8 +3525,15 @@ #define NO_WRITEV #define NO_MAIN_DRIVER #define SINGLE_THREADED - #define NO_ASN_TIME /* no wall clock in a TA */ - #define USER_TICKS + /* The only wall clock a trusted application can reach belongs to the + * normal world, so certificate dates are off by default. A project that + * accepts that clock defines WOLFSSL_OPTEE_ASN_TIME, which turns on XTIME + * from TEE_GetREETime and the TEE_GetSystemTime timers. USER_TICKS is not + * set either way, since those timers are supplied here; a project may + * still define it to override them. */ + #ifndef WOLFSSL_OPTEE_ASN_TIME + #define NO_ASN_TIME + #endif #endif /* WOLFSSL_OPTEE */ /* FreeScale MMCAU hardware crypto has 4 byte alignment. diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index b4b67cd1f33..c500df58244 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -833,6 +833,22 @@ enum { #endif #define XREALLOC(p, n, h, t) m2mb_os_realloc((p), (n)) +#elif defined(WOLFSSL_OPTEE) + /* libutee rather than a C library, so no std heap. FILL_ZERO because a + * trusted application holds key material. */ + #include + #define XMALLOC(s, h, t) ((void)(h), (void)(t), \ + TEE_Malloc((size_t)(s), TEE_MALLOC_FILL_ZERO)) + #ifdef WOLFSSL_XFREE_NO_NULLNESS_CHECK + #define XFREE(p, h, t) do { (void)(h); (void)(t); \ + TEE_Free(p); } while (0) + #else + #define XFREE(p, h, t) do { void* xp = (p); (void)(h); (void)(t); \ + if (xp != NULL) TEE_Free(xp); } while (0) + #endif + #define XREALLOC(p, n, h, t) ((void)(h), (void)(t), \ + TEE_Realloc((p), (size_t)(n))) + #elif defined(NO_WOLFSSL_MEMORY) #ifdef WOLFSSL_NO_MALLOC /* this platform does not support heap use */ diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index d61ee49f6cb..0dbb0d1f38c 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1772,6 +1772,18 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); extern time_t deos_time(time_t* timer); #define XTIME(t1) deos_time((t1)) #endif +#elif defined(WOLFSSL_OPTEE) + #include + #include + /* The normal world owns this clock, so it is attacker influenced: fit + * for freshness, not for certificate validity. Hence NO_ASN_TIME in the + * WOLFSSL_OPTEE settings block. */ + #ifndef XTIME + extern time_t optee_time(time_t* timer); + #define XTIME(t1) optee_time((t1)) + #endif + #define WOLFSSL_GMTIME + #elif defined(MICRIUM) #include #include