Secure Time Seeding – improving time keeping in Windows
What year is it?
(https://i1.kym-cdn.com/entries/icons/original/000/007/784/what-year-is-it-robin-williams.jpg AKA Robin Williams' Jumanji meme)
Most network security protocols rely on the use of keys that expire after a certain amount of time. This appears to be a plain vanilla statement until you think a bit about it. Timekeeping over long periods of time is critical for tracking the lifetime and expiry of security keys. We innately understand the passage of time and take it for granted that our computers and devices will automatically do this for us with reasonable accuracy, at least to the extent required for key rollover.
Computers must keep track of time when they are running and even when they are turned off. The latter functionality is the only way to know what time it is when they are turned back on again. By extension this is also the only way they know which keys are valid and which are not.
PCs and big form-factor hardware have a dedicated battery to power their system clock. We barely notice anything is amiss when we power-cycle these machines. Miniaturization of consumer devices has led to the elimination of this on-board dedicated (CMOS) battery, whose function is now delegated to the main device battery. The device batteries do this job as expected most of the time.
One of the annoying things about device batteries is that they run out of power (often when we seem to need them the most). As the device battery depletes and then drains completely, the time keeping function it supports also stops. The devices powered up from this state typically start up with their clock set to a random time value. This presents a little problem to the device in keeping track of the validity of its keys, some of which are used in secure networking – i.e. the device cannot connect securely to the outside world without an intervention to correct its clock.
You may ask – why doesn’t the device ask the nearest time server for the current time over the network? Since the device is not in a state to communicate securely over the network, it cannot obtain time securely over the network as well, unless you choose to ignore network security or at least punch some holes into it by making exceptions.
To summarize the issue, grossly incorrect system time can cause network security to be impaired, which in turn prevents obtaining the current time securely over the network. This is a classic circular dependency.
You may have experienced this problem on your tablet or mobile device in the form of connectivity issues to secure services. Increasing use of sleeker/smaller devices means this issue is bound to occur widely, impacting the users of these devices. Devices with aging batteries will start to experience this problem more often, contributing to the frequency of occurrence of this issue. It could also occur on larger hardware like PCs when their on-board battery drains completely (a rare event, but a certain event nonetheless).
Asking the users to check their system time when they cannot get their emails or when they cannot sign on to their websites or when they cannot sign into their AD domains will get old really fast. We had to address and solve this problem at a system level.
Solutions to this problem
Hosting a custom "Secure" Time Service:
A possible solution would involve the client obtaining the current time from a server over a protocol like SSL, ignoring errors in time-related protocol validations on the client. Any exceptions to the security validations requires thorough scrutiny since we are opening the client to potential attacks, which in part makes this an unfavorable solution. Additionally, we have to maintain a server available at all times and the clients may or may not be able to reach said server from the network they are on – additional challenges that reduce the effectiveness of this solution.
Secure Time Seeding - a client-side solution:
We started looking for solutions that would not require us to make security exceptions and SSL protocol contained data that we could use. We decided to stick to the principle of trusting only the data from SSL connections that can be established based on the certificates installed on the client, without treating specific certificates differently – i.e. a mechanism that is not very different from the one we had before.
SSL protocol allows a client to securely participate in a handshake with a server and perform time-related validation towards the end of the handshake (e.g.: certificate validity using the local system clock). Essentially a client can trust the certificates installed locally to perform the SSL handshake, but it may not trust the server enough to establish the connection because its local system time indicates the server’s certificate chain is invalid.
The SSL handshake contains encrypted/signed time metadata from the server that can be used by the client to determine the current time. This secure metadata helped us to break the cyclical dependency between client system time and security keys including SSL certificates.
We use the following two pieces of metadata from the SSL handshake:
- ServerUnixTime, an informational field.
- OCSP validity period, which is part of the cryptographically signed data obtained from optional stapled OCSP packet that has been tacked on to the SSL certificate chain presented by the server to the client.
The ServerUnixTime is supposed to be the current system time on the server, but it can also be set to a random value by some SSL implementations. We have observed that most servers provide a fairly accurate value in this field and the rest provide random values. We use this data field assuming it is somewhat accurate but can also be incorrect.
Stapled OCSP packets provide a very reliable time range, but it has low adoption on the internet and the time range can be as long as a week, making it not very suitable for use by the system clock. However, in cases where the system clock is off by weeks/months/years, setting the system clock to within a week’s accuracy is certainly a huge improvement. This OCSP time range data can be used by itself or combined with the ServerUnixTime to improve the accuracy of the time range.
We took the approach to not trust the data from a lone server, irrespective of who the server identifies itself as. We rely on corroborating information from multiple servers to arrive at a common truth about the current time.
The SSL connections made from the client are randomly interspersed in time and the metadata they provide follows suit as well. Our algorithms corroborate the data and determine reliable range for the current time. The information from ServerUnixTime and OCSP validity periods are merged to produce the smallest possible reliable time range value along with a confidence score. When the confidence score is sufficiently high, this data becomes information. We are calling this as Secure Time Seed of High Confidence (STSHC) .
STSHC is actionable information and it is used to correct grossly incorrect system clocks (i.e. seed them with a good value). After this occurs, a more accurate time synchronization is expected to be carried out using NTP (secured or unsecured) to bring the system clock close to the current time. In fact, both clock correction functions are performed by the Windows Time Service (W32Time).
A grossly incorrect system clock may cause the initial few SSL connections to fail, but the calling client applications tend to retry the calls after a short time. STSHC may have been established and the system clock corrected when the retry occurs and the retried SSL calls would likely succeed. This provides a very seamless experience for the end users, instead of them having to diagnose errors originating from SSL certificate validation failures due to incorrect system time. This is a big win for the overall user experience with SSL.
STSHC is also used to monitor the system clock for gross errors and correct those at the next chance. This adds another obstacle to tampering the system clock or even flaky clock hardware to some extent.
Does this work?
The Secure Time Seeding feature was shipped in the Windows 10 November 2015 release and is turned on by default. You may have seen the improvements in timekeeping on your Windows tablets and other Windows devices running this version of the OS. We have seen it work time and again given the prerequisites are met.
I want to see this in action
This feature requires W32time Service to be enabled (“Set Time Automatically” Date-Time UI setting enabled), internet connectivity and outgoing SSL traffic from your machine or device to function. Assuming you have the above prerequisites met, you can watch this feature in action by moving your system clock forward or backward by a week or longer and watch it get corrected after a short duration.
I trust my hardware clock and time synchronization mechanisms. I don't want this!
If you would rather trust your system clock than time data generated from your SSL traffic and want to forgo any benefit this feature gives you, we got your back. Set the following registry value to 0 and reboot your machine and the Secure Time Seeding feature will be disabled. (Standard warning about exercising care while modifying registry applies here).
Registry Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config
Value Name: UtilizeSslTimeData
Value Type: REG_DWORD
I changed my mind and want the feature back on.
Just set the above registry value to 1 and reboot your machine. Please remember that W32time service must also be enabled (“Set Time Automatically” setting in the Date-Time UI). (Standard warning about exercising care while modifying registry applies here as well).
Feature Availability
This feature was first introduced in Windows 10 Client November release (November 2015 release). It is available in both Windows Server 2016 and Windows 10 Client Anniversary releases. The feature is turned on by default in all these versions of the OS.
Known Issues
We have a known issue related to this feature in the Windows 10 Client November Release. Refer to KB article 3160312 for more details. This issue has been fixed in the Windows 10 Anniversary Release.