Make time in milliseconds 64-bits

Allow for longer session ticket lives.
This commit is contained in:
Sean Parkinson 2022-08-26 12:29:51 +10:00
parent 1976601811
commit ef451d316c
5 changed files with 402 additions and 20 deletions

View File

@ -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];

View File

@ -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) {

View File

@ -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;

View File

@ -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 <system/tmr/sys_tmr.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)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;

View File

@ -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