Initialize the unused part of shorter server NTS keys (AES-128-GCM-SIV)
loaded from ntsdumpdir to avoid sending uninitialized data in requests
to the NTS-KE helper process.
Do that also for newly generated keys in case the memory will be
allocated dynamically.
Fixes: b1230efac3 ("nts: add support for encrypting cookies with AES-128-GCM-SIV")
Log important changes from chronyc for auditing purposes.
Add log messages for:
- loaded symmetric keys and server NTS keys (logged also on start)
- modified maxupdateskew and makestep
- enabled/disabled local reference mode (logged also on start)
- reset time smoothing (logged also on clock steps)
- reset sources
If an NTS server is configured without ntsdumpdir, keys will not be
saved and reloaded after restart, which will cause existing cookies
to be invalidated and can cause a short-term denial of service if
the server has so many clients that it cannot handle them all
making an NTS-KE session within one polling interval.
Log a warning message if a server key+certificate is specified without
ntsdumpdir.
Specify the AEAD ID for each key saved in the ntskeys file instead of
one ID for all keys. Keep support for loading files in the old format.
This will allow servers to save their keys after upgrading to a new
version with AES-128-GCM-SIV support before the loaded AES-SIV-CMAC-256
keys are rotated out.
If an unsupported key is found, don't load any keys. Also, change the
severity of the error message from debug to error.
If AES-128-GCM-SIV is available on the server, use it for encryption of
cookies. This makes them shorter by 4 bytes due to shorter nonce and it
might also improve the server performance.
After server upgrade and restart with ntsdumpdir, the switch will happen
on the second rotation of the server key. Clients should accept shorter
cookies without restarting NTS-KE. The first response will have extra
padding in the authenticator field to make the length symmetric.
Keep a server SIV instance for each available algorithm.
Select AES-128-GCM-SIV if requested by NTS-KE client as the first
supported algorithm.
Instead of encoding the AEAD ID in the cookie, select the algorithm
according to the length of decrypted keys. (This can work as a long as
all supported algorithms use keys with different lengths.)
Don't allow a cookie to contain keys with different lengths to not break
the assumption made in decoding, if there will ever be a case where this
could be requested.
Close /dev/urandom and drop cached getrandom() data after forking helper
processes to avoid them getting the same sequence of random numbers
(e.g. two NTS-KE helpers generating cookies with identical nonces).
arc4random() is assumed to be able to detect forks and reseed
automatically.
This is not strictly necessary with the current code, which does not use
the GetRandom functions before the NTS-KE helper processes are forked,
but that could change in future.
Also, call the reset function before exit to close /dev/urandom in order
to avoid valgrind reporting the file object as "still reachable".
If ntsdumpdir is specified and the server NTS keys are not reloaded from
the file, save the generated keys on start instead of waiting for the
first rotation or exit. This allows the keys to be shared with another
server without having to use the dump command.
When the request has an unrecognized critical record before the
NEXT_PROTOCOL and AEAD_ALGORITHM records, respond with error 0
(unrecognized critical record) instead of 1 (bad request).
When the request has multiple NEXT_PROTOCOL or AEAD_ALGORITHM records,
respond with error 1 (bad request).
As a Linux-specific feature, allow sockets to be bound to a device using
the SO_BINDTODEVICE socket option. The CAP_NET_RAW capability is
required for setting the option.
Allow an IP family to be specified in the socket initialization in order
to globally disable the other family. This replaces the ntp_io and
cmdmon code handling the -4/-6 options and fixes a case where the NTP
client could still use a disabled family if the source was specified
with an IP address.
When compiled with NTS support, don't require a SIV cipher to be always
supported (e.g. due to a different version of a library used for
building). Handle this case with a fatal message instead of crash.
Also, check the support early in the client unit test to prevent a hang.
Instead of sharing the NTP rate limiting with NTS-KE, specify a new
service for NTS-KE and use it in the NTS-KE server.
Add ntsratelimit directive for configuration.
Refactor the client record and clientlog API to reuse more code between
different services and enumerate the services instead of hardcoding NTP
and cmdmon.
If ntsrotate is set to 0, don't generate new server keys and don't save
them to ntsdumpdir. This allows the keys to be managed externally and
shared with other servers.
Include in the key dump file an identifier, the AEAD number, and the
age of the last key to improve robustness and avoid generating a new key
immediately on start.
Also, improve the code that saves and loads the file.
Add a context structure for the algorithm and keys established by
NTS-KE. Modify the client to save the context and reset the SIV key to
the C2S/S2C key before each request/response instead of keeping two SIV
instances.
This will make it easier for the server to support different algorithms
and allow the client to save the context with cookies to disk.
The server session instances are reused for different clients. Separate
the server name from the label used in log messages and set it on each
start of the session.
Don't require the caller to provide a SCK_Message (on stack). Modify the
SCK_ReceiveMessage*() functions to return a pointer to static buffers,
as the message buffer which SCK_Message points to already is.