From 3417a4ebd56a89d317b9843c87e0006eecf7730f Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 29 Oct 2026 09:57:07 -0700 Subject: [PATCH] Add OP-TEE heap, RNG and time platform support under WOLFSSL_OPTEE --- .wolfssl_known_macro_extras | 1 + src/internal.c | 11 +++++++++++ src/tls13.c | 22 ++++++++++++++++++++++ wolfcrypt/benchmark/benchmark.c | 19 +++++++++++++++++++ wolfcrypt/src/cpuid.c | 5 ++++- wolfcrypt/src/memory.c | 10 ++++++++++ wolfcrypt/src/random.c | 14 ++++++++++++++ wolfcrypt/src/wc_port.c | 19 +++++++++++++++++++ wolfssl/wolfcrypt/settings.h | 15 +++++++++++++-- wolfssl/wolfcrypt/wc_port.h | 14 ++++++++++++++ 10 files changed, 127 insertions(+), 3 deletions(-) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 6ebc459788e..d4ee9659332 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -1152,6 +1152,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 0c54d776a0d..f33e9432e2d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -12073,6 +12073,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 f9f8b4c45a4..c6592a34892 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -19093,6 +19093,25 @@ 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); + + #ifdef BENCH_MICROSECOND + return ((double)now.seconds * 1000000.0) + + ((double)now.millis * 1000.0); + #else + return (double)now.seconds + ((double)now.millis / 1000.0); + #endif + } + #elif defined(WOLFSSL_ZEPHYR) #include diff --git a/wolfcrypt/src/cpuid.c b/wolfcrypt/src/cpuid.c index bd20dea294f..ee100fd489b 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/memory.c b/wolfcrypt/src/memory.c index 5f4c2d9c6ce..9151ccbe278 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -79,6 +79,16 @@ void *z_realloc(void *ptr, size_t size) #define realloc z_realloc #endif +#ifdef WOLFSSL_OPTEE +/* The native heap of a trusted application is libutee's. FILL_ZERO because a + * trusted application holds key material. Only the fallback below is + * redirected, so pools, WOLFSSL_NO_MALLOC and registered callbacks still + * take precedence. */ +#define malloc(s) TEE_Malloc((s), TEE_MALLOC_FILL_ZERO) /* native heap */ +#define realloc(p, s) TEE_Realloc((p), (s)) /* native heap */ +#define free(p) TEE_Free(p) /* native heap */ +#endif + #ifdef USE_WOLFSSL_MEMORY #include diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 6166209cc5b..e341644a872 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -221,6 +221,7 @@ This library contains implementation for the random number generator. #elif defined(WOLFSSL_DEOS) #elif defined(MICRIUM) #elif defined(WOLFSSL_NUCLEUS) +#elif defined(WOLFSSL_OPTEE) #elif defined(WOLFSSL_PB) #elif defined(WOLFSSL_ZEPHYR) #elif defined(WOLFSSL_TELIT_M2MB) @@ -10631,6 +10632,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 4eaa7ce7fcf..0e3bf981338 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -4924,6 +4924,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 130b87974f6..4cf00c8f08f 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -3481,13 +3481,24 @@ * a TA is single threaded. The TA toolchain is a Linux cross compiler and * still predefines __unix__, so the environment has to be named explicitly. */ #ifdef WOLFSSL_OPTEE + /* Included here so every translation unit sees the TEE API regardless of + * allocator or time options, and so compiler.h's fallthrough macro is + * visible before types.h chooses FALL_THROUGH. */ + #include #define NO_FILESYSTEM #define NO_WOLFSSL_DIR #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/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index e094c4044f7..73a9da8625f 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1755,6 +1755,20 @@ 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) + /* The TA is built -nostdinc, so this is libutils' time.h: time_t only, + * no struct tm. */ + #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 + #define USE_WOLF_TM + #elif defined(MICRIUM) #include #include