From ef451d316cfb73e5fdccba9891044e187d8cf738 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 26 Aug 2022 12:29:51 +1000 Subject: [PATCH 1/2] Make time in milliseconds 64-bits Allow for longer session ticket lives. --- src/internal.c | 12 ++ src/ssl.c | 13 ++ src/tls.c | 28 +++- src/tls13.c | 338 +++++++++++++++++++++++++++++++++++++++++++-- wolfssl/internal.h | 31 ++++- 5 files changed, 402 insertions(+), 20 deletions(-) diff --git a/src/internal.c b/src/internal.c index 7098d3380..949604867 100644 --- a/src/internal.c +++ b/src/internal.c @@ -33462,6 +33462,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } else { #ifdef WOLFSSL_TLS13 + #ifndef WOLFSSL_32BIT_MILLI_TIME + sword64 now = TimeNowInMilliseconds(); + #endif + /* Client adds to ticket age to obfuscate. */ ret = wc_RNG_GenerateBlock(ssl->rng, it->ageAdd, sizeof(it->ageAdd)); @@ -33471,7 +33475,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } ato32(it->ageAdd, &ssl->session->ticketAdd); c16toa(ssl->session->namedGroup, it->namedGroup); + #ifdef WOLFSSL_32BIT_MILLI_TIME c32toa(TimeNowInMilliseconds(), it->timestamp); + #else + c32toa((word32)(now / 1000), it->timestamp); + c32toa((word32)(now % 1000), it->timestampmilli); + #endif /* Resumption master secret. */ XMEMCPY(it->msecret, ssl->session->masterSecret, SECRET_LEN); XMEMCPY(&it->ticketNonce, &ssl->session->ticketNonce, @@ -33735,6 +33744,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef WOLFSSL_TLS13 /* Restore information to renegotiate. */ ato32(it->timestamp, &ssl->session->ticketSeen); + #ifndef WOLFSSL_32BIT_MILLI_TIME + ato32(it->timestampmilli, &ssl->session->ticketSeenMilli); + #endif ato32(it->ageAdd, &ssl->session->ticketAdd); ssl->session->cipherSuite0 = it->suite[0]; ssl->session->cipherSuite = it->suite[1]; diff --git a/src/ssl.c b/src/ssl.c index 70edba2b8..b615396b9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25361,8 +25361,13 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) #endif #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #ifdef WOLFSSL_TLS13 +#ifdef WOLFSSL_32BIT_MILLI_TIME /* ticketSeen | ticketAdd */ size += OPAQUE32_LEN + OPAQUE32_LEN; +#else + /* ticketSeen | ticketSeenMilli | ticketAdd */ + size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE32_LEN; +#endif /* ticketNonce */ size += OPAQUE8_LEN + sess->ticketNonce.len; #endif @@ -25436,6 +25441,10 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) #ifdef WOLFSSL_TLS13 c32toa(sess->ticketSeen, data + idx); idx += OPAQUE32_LEN; +#ifndef WOLFSSL_32BIT_MILLI_TIME + c32toa(sess->ticketSeenMilli, data + idx); + idx += OPAQUE32_LEN; +#endif c32toa(sess->ticketAdd, data + idx); idx += OPAQUE32_LEN; data[idx++] = sess->ticketNonce.len; @@ -25632,6 +25641,10 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess, } ato32(data + idx, &s->ticketSeen); idx += OPAQUE32_LEN; +#ifndef WOLFSSL_32BIT_MILLI_TIME + ato32(data + idx, &s->ticketSeenMilli); + idx += OPAQUE32_LEN; +#endif ato32(data + idx, &s->ticketAdd); idx += OPAQUE32_LEN; if (i - idx < OPAQUE8_LEN) { diff --git a/src/tls.c b/src/tls.c index bc3ad363f..4c1db4109 100644 --- a/src/tls.c +++ b/src/tls.c @@ -11507,7 +11507,11 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) #if defined(HAVE_SESSION_TICKET) if (ssl->options.resuming && ssl->session->ticketLen > 0) { WOLFSSL_SESSION* sess = ssl->session; - word32 now, milli; + #ifdef WOLFSSL_32BIT_MILLI_TIME + word32 now, milli; + #else + word64 now, milli, seen; + #endif if (sess->ticketLen > MAX_PSK_ID_LEN) { WOLFSSL_MSG("Session ticket length for PSK ext is too large"); @@ -11520,6 +11524,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) ret = SetCipherSpecs(ssl); if (ret != 0) return ret; + #ifdef WOLFSSL_32BIT_MILLI_TIME now = TimeNowInMilliseconds(); if (now < sess->ticketSeen) milli = (0xFFFFFFFFU - sess->ticketSeen) + 1 + now; @@ -11529,10 +11534,23 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) /* Pre-shared key is mandatory extension for resumption. */ ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen, - milli, ssl->specs.mac_algorithm, - ssl->options.cipherSuite0, - ssl->options.cipherSuite, 1, - NULL); + milli, ssl->specs.mac_algorithm, ssl->options.cipherSuite0, + ssl->options.cipherSuite, 1, NULL); + #else + seen = (sword64)sess->ticketSeen * 1000 + sess->ticketSeenMilli; + now = TimeNowInMilliseconds(); + if (now < seen) + milli = (0xFFFFFFFFFFFFFFFFU - seen) + 1 + now; + else + milli = now - seen; + milli += sess->ticketAdd; + + /* Pre-shared key is mandatory extension for resumption. */ + ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen, + (word32)milli, ssl->specs.mac_algorithm, + ssl->options.cipherSuite0, ssl->options.cipherSuite, 1, + NULL); + #endif if (ret != 0) return ret; diff --git a/src/tls13.c b/src/tls13.c index be17481c4..edc239afc 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -81,6 +81,9 @@ * Verifies the ECC signature after signing in case of faults in the * calculation of the signature. Useful when signature fault injection is a * possible attack. + * WOLFSSL_32BIT_MILLI_TIME + * Function TimeNowInMilliseconds() returns an unsigned 32-bit value. + * Default behavior is to return a signed 64-bit value. */ #ifdef HAVE_CONFIG_H @@ -1372,6 +1375,7 @@ end: } #if (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) +#ifdef WOLFSSL_32BIT_MILLI_TIME #ifndef NO_ASN_TIME #if defined(USER_TICKS) #if 0 @@ -1655,6 +1659,290 @@ end: * The response is milliseconds elapsed */ #endif /* !NO_ASN_TIME */ +#else +#ifndef NO_ASN_TIME +#if defined(USER_TICKS) +#if 0 + sword64 TimeNowInMilliseconds(void) + { + /* + write your own clock tick function if don't want gettimeofday() + needs millisecond accuracy but doesn't have to correlated to EPOCH + */ + } +#endif + +#elif defined(TIME_OVERRIDES) +#if !defined(NO_ASN) && !defined(NO_ASN_TIME) + sword64 TimeNowInMilliseconds(void) + { + return (sword64) wc_Time(0) * 1000; + } +#else + #ifndef HAVE_TIME_T_TYPE + typedef long time_t; + #endif + extern time_t XTIME(time_t * timer); + + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 32-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return (sword64) XTIME(0) * 1000; + } +#endif + +#elif defined(XTIME_MS) + sword64 TimeNowInMilliseconds(void) + { + return (sword64)XTIME_MS(0); + } + +#elif defined(USE_WINDOWS_API) + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + static int init = 0; + static LARGE_INTEGER freq; + LARGE_INTEGER count; + + if (!init) { + QueryPerformanceFrequency(&freq); + init = 1; + } + + QueryPerformanceCounter(&count); + + return (sword64)(count.QuadPart / (freq.QuadPart / 1000)); + } + +#elif defined(HAVE_RTP_SYS) + #include "rtptime.h" + + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return (sword64)rtp_get_system_sec() * 1000; + } +#elif defined(WOLFSSL_DEOS) + sword64 TimeNowInMilliseconds(void) + { + const word32 systemTickTimeInHz = 1000000 / systemTickInMicroseconds(); + word32 *systemTickPtr = systemTickPointer(); + + return (sword64) (*systemTickPtr/systemTickTimeInHz) * 1000; + } +#elif defined(MICRIUM) + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + OS_TICK ticks = 0; + OS_ERR err; + + ticks = OSTimeGet(&err); + + return (sword64) (ticks / OSCfg_TickRate_Hz) * 1000; + } +#elif defined(MICROCHIP_TCPIP_V5) + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return (sword64) (TickGet() / (TICKS_PER_SECOND / 1000)); + } +#elif defined(MICROCHIP_TCPIP) + #if defined(MICROCHIP_MPLAB_HARMONY) + #include + + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return (sword64)SYS_TMR_TickCountGet() / + (SYS_TMR_TickCounterFrequencyGet() / 1000); + } + #else + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return (sword64)SYS_TICK_Get() / (SYS_TICK_TicksPerSecondGet() / 1000); + } + + #endif + +#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + TIME_STRUCT mqxTime; + + _time_get_elapsed(&mqxTime); + + return (sword64) mqxTime.SECONDS * 1000; + } +#elif defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS) + #include "include/task.h" + + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return (sword64)xTaskGetTickCount() / (configTICK_RATE_HZ / 1000); + } +#elif defined(FREESCALE_KSDK_BM) + #include "lwip/sys.h" /* lwIP */ + + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return sys_now(); + } +#elif defined(WOLFSSL_TIRTOS) + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return (sword64) Seconds_get() * 1000; + } +#elif defined(WOLFSSL_UTASKER) + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + return (sword64)(uTaskerSystemTick / (TICK_RESOLUTION / 1000)); + } +#elif defined(WOLFSSL_LINUXKM) + sword64 TimeNowInMilliseconds(void) + { + s64 t; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) + struct timespec ts; + getnstimeofday(&ts); + t = ts.tv_sec * (s64)1000; + t += ts.tv_nsec / (s64)1000000; +#else + struct timespec64 ts; +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) + ts = current_kernel_time64(); +#else + ktime_get_coarse_real_ts64(&ts); +#endif + t = ts.tv_sec * 1000L; + t += ts.tv_nsec / 1000000L; +#endif + return (sword64)t; + } +#elif defined(WOLFSSL_QNX_CAAM) + sword64 TimeNowInMilliseconds(void) + { + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + return (sword64)(now.tv_sec * 1000 + now.tv_nsec / 1000000); + } +#elif defined(FUSION_RTOS) + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + struct timeval now; + if (FCL_GETTIMEOFDAY(&now, 0) < 0) + return (sword64)GETTIME_ERROR; /* TODO: return 0 for failure */ + + /* Convert to milliseconds number. */ + return (sword64)now.tv_sec * 1000 + now.tv_usec / 1000; + } +#elif defined(WOLFSSL_ZEPHYR) + sword64 TimeNowInMilliseconds(void) + { + #if defined(CONFIG_ARCH_POSIX) + k_cpu_idle(); + #endif + return (sword64)k_uptime_get() / 1000; + } + +#else + /* The time in milliseconds. + * Used for tickets to represent difference between when first seen and when + * sending. + * + * returns the time in milliseconds as a 64-bit value. + */ + sword64 TimeNowInMilliseconds(void) + { + struct timeval now; + + if (gettimeofday(&now, 0) < 0) + return (sword64)GETTIME_ERROR; /* TODO: return 0 for failure */ + + /* Convert to milliseconds number. */ + return (sword64)now.tv_sec * 1000 + now.tv_usec / 1000; + } +#endif +#else + /* user must supply time in milliseconds function: + * sword64 TimeNowInMilliseconds(void); + * The response is milliseconds elapsed + */ +#endif /* !NO_ASN_TIME */ +#endif /* WOLFSSL_32BIT_MILLI_TIME */ #endif /* HAVE_SESSION_TICKET || !NO_PSK */ @@ -4633,7 +4921,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, #endif if (ret == WOLFSSL_TICKET_RET_OK) { - word32 now; + #ifdef WOLFSSL_32BIT_MILLI_TIME + word32 now; sword64 diff; now = TimeNowInMilliseconds(); @@ -4648,6 +4937,22 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, current = current->next; continue; } + #else + sword64 diff; + + diff = TimeNowInMilliseconds(); + if (diff == (sword64)GETTIME_ERROR) + return (word32)diff; + /* Difference between now and time ticket constructed + * (from decrypted ticket). */ + diff -= (word64)ssl->session->ticketSeen * 1000; + diff -= ssl->session->ticketSeenMilli; + if (diff > (sword64)ssl->timeout * 1000 || + diff > (sword64)TLS13_MAX_TICKET_AGE * 1000) { + current = current->next; + continue; + } + #endif /* Subtract client's ticket age and unobfuscate. */ diff -= current->ticketAge; diff += ssl->session->ticketAdd; @@ -8883,7 +9188,11 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input, word32 lifetime; word32 ageAdd; word16 length; +#ifdef WOLFSSL_32BIT_MILLI_TIME word32 now; +#else + sword64 now; +#endif const byte* nonce; byte nonceLength; @@ -8933,23 +9242,34 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input, return ret; *inOutIdx += length; +#ifdef WOLFSSL_32BIT_MILLI_TIME now = TimeNowInMilliseconds(); if (now == (word32)GETTIME_ERROR) return now; +#else + now = TimeNowInMilliseconds(); + if (now == (sword64)GETTIME_ERROR) + return (int)now; +#endif /* Copy in ticket data (server identity). */ - ssl->timeout = lifetime; - ssl->session->timeout = lifetime; - ssl->session->cipherSuite0 = ssl->options.cipherSuite0; - ssl->session->cipherSuite = ssl->options.cipherSuite; - ssl->session->ticketSeen = now; - ssl->session->ticketAdd = ageAdd; + ssl->timeout = lifetime; + ssl->session->timeout = lifetime; + ssl->session->cipherSuite0 = ssl->options.cipherSuite0; + ssl->session->cipherSuite = ssl->options.cipherSuite; +#ifdef WOLFSSL_32BIT_MILLI_TIME + ssl->session->ticketSeen = now; +#else + ssl->session->ticketSeen = (word32)(now / 1000); + ssl->session->ticketSeenMilli = now % 1000; +#endif + ssl->session->ticketAdd = ageAdd; #ifdef WOLFSSL_EARLY_DATA - ssl->session->maxEarlyDataSz = ssl->options.maxEarlyDataSz; + ssl->session->maxEarlyDataSz = ssl->options.maxEarlyDataSz; #endif ssl->session->ticketNonce.len = nonceLength; if (nonceLength > 0) XMEMCPY(&ssl->session->ticketNonce.data, nonce, nonceLength); - ssl->session->namedGroup = ssl->namedGroup; + ssl->session->namedGroup = ssl->namedGroup; if ((*inOutIdx - begin) + EXTS_SZ > size) return BUFFER_ERROR; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0015c19d1..a04e13bb1 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1255,6 +1255,15 @@ enum { #error "Max size for DTLS CID is 255 bytes" #endif +#ifndef MAX_TICKET_AGE_DIFF +/* maximum ticket age difference in seconds, 10 seconds */ +#define MAX_TICKET_AGE_DIFF 10 +#endif +#ifndef TLS13_MAX_TICKET_AGE +/* max ticket age in seconds, 7 days */ +#define TLS13_MAX_TICKET_AGE (7*24*60*60) +#endif + enum Misc { CIPHER_BYTE = 0x00, /* Default ciphers */ ECC_BYTE = 0xC0, /* ECC first cipher suite byte */ @@ -1554,8 +1563,6 @@ enum Misc { MAX_PSK_KEY_LEN = 64, /* max psk key supported */ MIN_PSK_ID_LEN = 6, /* min length of identities */ MIN_PSK_BINDERS_LEN = 33, /* min length of binders */ - MAX_TICKET_AGE_DIFF = 10, /* maximum ticket age difference in seconds */ - TLS13_MAX_TICKET_AGE = 7*24*60*60, /* max ticket age in seconds, 7 days */ #ifndef MAX_WOLFSSL_FILE_SIZE MAX_WOLFSSL_FILE_SIZE = 1024UL * 1024UL * 4, /* 4 mb file size alloc limit */ @@ -2746,6 +2753,9 @@ typedef struct InternalTicket { byte suite[SUITE_LEN]; /* cipher suite when created */ byte msecret[SECRET_LEN]; /* master secret */ byte timestamp[TIMESTAMP_LEN]; /* born on */ +#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_32BIT_MILLI_TIME) + byte timestampmilli[TIMESTAMP_LEN]; /* born on milli */ +#endif byte haveEMS; /* have extended master secret */ #ifdef WOLFSSL_TLS13 byte ageAdd[AGEADD_LEN]; /* Obfuscation of age */ @@ -3708,14 +3718,19 @@ struct WOLFSSL_SESSION { word16 namedGroup; #endif #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) - #ifdef WOLFSSL_TLS13 +#ifdef WOLFSSL_TLS13 +#ifdef WOLFSSL_32BIT_MILLI_TIME word32 ticketSeen; /* Time ticket seen (ms) */ +#else + word32 ticketSeen; /* Time ticket seen (s) */ + word32 ticketSeenMilli; /* Time ticket seen ms */ +#endif word32 ticketAdd; /* Added by client */ TicketNonce ticketNonce; /* Nonce used to derive PSK */ - #endif - #ifdef WOLFSSL_EARLY_DATA +#endif +#ifdef WOLFSSL_EARLY_DATA word32 maxEarlyDataSz; - #endif +#endif #endif #ifdef HAVE_SESSION_TICKET byte staticTicket[SESSION_TICKET_LEN]; @@ -5486,7 +5501,11 @@ WOLFSSL_LOCAL int cipherExtraData(WOLFSSL* ssl); WOLFSSL_LOCAL void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out); #if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) +#ifdef WOLFSSL_32BIT_MILLI_TIME WOLFSSL_LOCAL word32 TimeNowInMilliseconds(void); +#else + WOLFSSL_LOCAL sword64 TimeNowInMilliseconds(void); +#endif WOLFSSL_LOCAL int FindSuiteMac(WOLFSSL* ssl, byte* suite); #endif From b95df7529cbfcaac4a6c33f19c5204057d15261b Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 5 Sep 2022 09:11:46 +1000 Subject: [PATCH 2/2] Improve usage of 64-bit implementation of TimeNowInMilli Change to use 64-bits for types stored - use WOLFSSL_32BIT_MILLI_TIME if a 64-bit type is not available. TimeNowInMill() returns 0 on error instead of GETTIME_ERROR. --- src/internal.c | 23 +++++++++++++++++------ src/ssl.c | 39 +++++++++++++++++++++++++-------------- src/tls.c | 14 +++++--------- src/tls13.c | 34 +++++++++++----------------------- wolfssl/internal.h | 10 +++++----- 5 files changed, 63 insertions(+), 57 deletions(-) diff --git a/src/internal.c b/src/internal.c index 949604867..5831a890f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -33462,9 +33462,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } else { #ifdef WOLFSSL_TLS13 - #ifndef WOLFSSL_32BIT_MILLI_TIME + #ifdef WOLFSSL_32BIT_MILLI_TIME + word32 now = TimeNowInMilliseconds(); + #else sword64 now = TimeNowInMilliseconds(); #endif + if (now == 0) { + ret = GETTIME_ERROR; + goto error; + } /* Client adds to ticket age to obfuscate. */ ret = wc_RNG_GenerateBlock(ssl->rng, it->ageAdd, @@ -33476,10 +33482,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ato32(it->ageAdd, &ssl->session->ticketAdd); c16toa(ssl->session->namedGroup, it->namedGroup); #ifdef WOLFSSL_32BIT_MILLI_TIME - c32toa(TimeNowInMilliseconds(), it->timestamp); + c32toa(now, it->timestamp); #else - c32toa((word32)(now / 1000), it->timestamp); - c32toa((word32)(now % 1000), it->timestampmilli); + c32toa((word32)(now >> 32), it->timestamp); + c32toa((word32)now , it->timestamp + OPAQUE32_LEN); #endif /* Resumption master secret. */ XMEMCPY(it->msecret, ssl->session->masterSecret, SECRET_LEN); @@ -33743,9 +33749,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, else { #ifdef WOLFSSL_TLS13 /* Restore information to renegotiate. */ + #ifdef WOLFSSL_32BIT_MILLI_TIME ato32(it->timestamp, &ssl->session->ticketSeen); - #ifndef WOLFSSL_32BIT_MILLI_TIME - ato32(it->timestampmilli, &ssl->session->ticketSeenMilli); + #else + word32 seenHi, seenLo; + + ato32(it->timestamp , &seenHi); + ato32(it->timestamp + OPAQUE32_LEN, &seenLo); + ssl->session->ticketSeen = ((sword64)seenHi << 32) + seenLo; #endif ato32(it->ageAdd, &ssl->session->ticketAdd); ssl->session->cipherSuite0 = it->suite[0]; diff --git a/src/ssl.c b/src/ssl.c index b615396b9..2f981be83 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25365,7 +25365,7 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) /* ticketSeen | ticketAdd */ size += OPAQUE32_LEN + OPAQUE32_LEN; #else - /* ticketSeen | ticketSeenMilli | ticketAdd */ + /* ticketSeen Hi 32 bits | ticketSeen Lo 32 bits | ticketAdd */ size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE32_LEN; #endif /* ticketNonce */ @@ -25439,17 +25439,20 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) #endif #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #ifdef WOLFSSL_TLS13 - c32toa(sess->ticketSeen, data + idx); - idx += OPAQUE32_LEN; -#ifndef WOLFSSL_32BIT_MILLI_TIME - c32toa(sess->ticketSeenMilli, data + idx); - idx += OPAQUE32_LEN; +#ifdef WOLFSSL_32BIT_MILLI_TIME + c32toa(sess->ticketSeen, data + idx); + idx += OPAQUE32_LEN; +#else + c32toa((word32)(sess->ticketSeen >> 32), data + idx); + idx += OPAQUE32_LEN; + c32toa((word32)sess->ticketSeen, data + idx); + idx += OPAQUE32_LEN; #endif - c32toa(sess->ticketAdd, data + idx); - idx += OPAQUE32_LEN; - data[idx++] = sess->ticketNonce.len; - XMEMCPY(data + idx, sess->ticketNonce.data, sess->ticketNonce.len); - idx += sess->ticketNonce.len; + c32toa(sess->ticketAdd, data + idx); + idx += OPAQUE32_LEN; + data[idx++] = sess->ticketNonce.len; + XMEMCPY(data + idx, sess->ticketNonce.data, sess->ticketNonce.len); + idx += sess->ticketNonce.len; #endif #ifdef WOLFSSL_EARLY_DATA c32toa(sess->maxEarlyDataSz, data + idx); @@ -25639,11 +25642,19 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess, ret = BUFFER_ERROR; goto end; } +#ifdef WOLFSSL_32BIT_MILLI_TIME ato32(data + idx, &s->ticketSeen); idx += OPAQUE32_LEN; -#ifndef WOLFSSL_32BIT_MILLI_TIME - ato32(data + idx, &s->ticketSeenMilli); - idx += OPAQUE32_LEN; +#else + { + word32 seenHi, seenLo; + + ato32(data + idx, &seenHi); + idx += OPAQUE32_LEN; + ato32(data + idx, &seenLo); + idx += OPAQUE32_LEN; + s->ticketSeen = ((sword64)seenHi << 32) + seenLo; + } #endif ato32(data + idx, &s->ticketAdd); idx += OPAQUE32_LEN; diff --git a/src/tls.c b/src/tls.c index 4c1db4109..c3da6493f 100644 --- a/src/tls.c +++ b/src/tls.c @@ -11510,7 +11510,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) #ifdef WOLFSSL_32BIT_MILLI_TIME word32 now, milli; #else - word64 now, milli, seen; + word64 now, milli; #endif if (sess->ticketLen > MAX_PSK_ID_LEN) { @@ -11524,8 +11524,10 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) ret = SetCipherSpecs(ssl); if (ret != 0) return ret; - #ifdef WOLFSSL_32BIT_MILLI_TIME now = TimeNowInMilliseconds(); + if (now == 0) + return GETTIME_ERROR; + #ifdef WOLFSSL_32BIT_MILLI_TIME if (now < sess->ticketSeen) milli = (0xFFFFFFFFU - sess->ticketSeen) + 1 + now; else @@ -11537,13 +11539,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) milli, ssl->specs.mac_algorithm, ssl->options.cipherSuite0, ssl->options.cipherSuite, 1, NULL); #else - seen = (sword64)sess->ticketSeen * 1000 + sess->ticketSeenMilli; - now = TimeNowInMilliseconds(); - if (now < seen) - milli = (0xFFFFFFFFFFFFFFFFU - seen) + 1 + now; - else - milli = now - seen; - milli += sess->ticketAdd; + milli = now - sess->ticketSeen + sess->ticketAdd; /* Pre-shared key is mandatory extension for resumption. */ ret = TLSX_PreSharedKey_Use(ssl, sess->ticket, sess->ticketLen, diff --git a/src/tls13.c b/src/tls13.c index edc239afc..64371b313 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1621,7 +1621,7 @@ end: { struct timeval now; if (FCL_GETTIMEOFDAY(&now, 0) < 0) - return (word32)GETTIME_ERROR; /* TODO: return 0 for failure */ + return 0; /* Convert to milliseconds number. */ return (word32)(now.tv_sec * 1000 + now.tv_usec / 1000); @@ -1647,7 +1647,7 @@ end: struct timeval now; if (gettimeofday(&now, 0) < 0) - return (word32)GETTIME_ERROR; /* TODO: return 0 for failure */ + return 0; /* Convert to milliseconds number. */ return (word32)(now.tv_sec * 1000 + now.tv_usec / 1000); @@ -1904,7 +1904,7 @@ end: { struct timeval now; if (FCL_GETTIMEOFDAY(&now, 0) < 0) - return (sword64)GETTIME_ERROR; /* TODO: return 0 for failure */ + return 0; /* Convert to milliseconds number. */ return (sword64)now.tv_sec * 1000 + now.tv_usec / 1000; @@ -1930,7 +1930,7 @@ end: struct timeval now; if (gettimeofday(&now, 0) < 0) - return (sword64)GETTIME_ERROR; /* TODO: return 0 for failure */ + return 0; /* Convert to milliseconds number. */ return (sword64)now.tv_sec * 1000 + now.tv_usec / 1000; @@ -4926,8 +4926,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, sword64 diff; now = TimeNowInMilliseconds(); - if (now == (word32)GETTIME_ERROR) - return now; + if (now == 0) + return GETTIME_ERROR; /* Difference between now and time ticket constructed * (from decrypted ticket). */ diff = now; @@ -4941,12 +4941,11 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz, sword64 diff; diff = TimeNowInMilliseconds(); - if (diff == (sword64)GETTIME_ERROR) - return (word32)diff; + if (diff == 0) + return GETTIME_ERROR; /* Difference between now and time ticket constructed * (from decrypted ticket). */ - diff -= (word64)ssl->session->ticketSeen * 1000; - diff -= ssl->session->ticketSeenMilli; + diff -= ssl->session->ticketSeen; if (diff > (sword64)ssl->timeout * 1000 || diff > (sword64)TLS13_MAX_TICKET_AGE * 1000) { current = current->next; @@ -9242,26 +9241,15 @@ static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input, return ret; *inOutIdx += length; -#ifdef WOLFSSL_32BIT_MILLI_TIME now = TimeNowInMilliseconds(); - if (now == (word32)GETTIME_ERROR) - return now; -#else - now = TimeNowInMilliseconds(); - if (now == (sword64)GETTIME_ERROR) - return (int)now; -#endif + if (now == 0) + return GETTIME_ERROR; /* Copy in ticket data (server identity). */ ssl->timeout = lifetime; ssl->session->timeout = lifetime; ssl->session->cipherSuite0 = ssl->options.cipherSuite0; ssl->session->cipherSuite = ssl->options.cipherSuite; -#ifdef WOLFSSL_32BIT_MILLI_TIME ssl->session->ticketSeen = now; -#else - ssl->session->ticketSeen = (word32)(now / 1000); - ssl->session->ticketSeenMilli = now % 1000; -#endif ssl->session->ticketAdd = ageAdd; #ifdef WOLFSSL_EARLY_DATA ssl->session->maxEarlyDataSz = ssl->options.maxEarlyDataSz; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a04e13bb1..c10de3936 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1294,7 +1294,11 @@ enum Misc { HELLO_EXT_EXTMS = 0x0017, /* ID for the extended master secret ext */ SECRET_LEN = WOLFSSL_MAX_MASTER_KEY_LENGTH, /* pre RSA and all master */ +#if !defined(WOLFSSL_TLS13) || defined(WOLFSSL_32BIT_MILLI_TIME) TIMESTAMP_LEN = 4, /* timestamp size in ticket */ +#else + TIMESTAMP_LEN = 8, /* timestamp size in ticket */ +#endif #ifdef WOLFSSL_TLS13 AGEADD_LEN = 4, /* ageAdd size in ticket */ NAMEDGROUP_LEN = 2, /* namedGroup size in ticket */ @@ -2753,9 +2757,6 @@ typedef struct InternalTicket { byte suite[SUITE_LEN]; /* cipher suite when created */ byte msecret[SECRET_LEN]; /* master secret */ byte timestamp[TIMESTAMP_LEN]; /* born on */ -#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_32BIT_MILLI_TIME) - byte timestampmilli[TIMESTAMP_LEN]; /* born on milli */ -#endif byte haveEMS; /* have extended master secret */ #ifdef WOLFSSL_TLS13 byte ageAdd[AGEADD_LEN]; /* Obfuscation of age */ @@ -3722,8 +3723,7 @@ struct WOLFSSL_SESSION { #ifdef WOLFSSL_32BIT_MILLI_TIME word32 ticketSeen; /* Time ticket seen (ms) */ #else - word32 ticketSeen; /* Time ticket seen (s) */ - word32 ticketSeenMilli; /* Time ticket seen ms */ + sword64 ticketSeen; /* Time ticket seen (ms) */ #endif word32 ticketAdd; /* Added by client */ TicketNonce ticketNonce; /* Nonce used to derive PSK */