Transporting the state needed by a client to process a response as serialized state information in the token has several significant and nonobvious security and privacy implications that need to be mitigated; see
Section 3.1 for recommendations.
In addition to the format requirements outlined there, implementations need to ensure that they are not vulnerable to maliciously crafted, delayed, or replayed tokens.
It is generally expected that the use of encryption, integrity protection, and replay protection for serialized state is appropriate.
In the absence of integrity and replay protection, an on-path attacker or rogue server/intermediary could return a state (either one modified in a reply, or an unsolicited one) that could alter the internal state of the client.
It is for this reason that at least the use of integrity protection on the token is always recommended.
It may be that in some very specific cases, as a result of a careful and detailed analysis of any potential attacks, it is decided that such cryptographic protections do not add value. The authors of this document have not found such a use case as yet, but this is a local decision.
It should further be emphasized that the encrypted state is created by the sending node and decrypted by the same node when receiving a response. The key is not shared with any other system. Therefore, the choice of encryption scheme and the generation of the key for this system is purely a local matter.
When encryption is used, the use of [
RFC 3610] with a 64-bit tag is recommended, combined with a sequence number and a replay window. This choice is informed by available hardware acceleration of on many constrained systems. If a different algorithm is available accelerated on the sender, with similar or stronger strength, then it
SHOULD be preferred. Where privacy of the state is not required, and encryption is not needed, [
RFC 6234], combined with a sequence number and a replay window, may be used.
This size of the replay window depends upon the number of requests that need to be outstanding. This can be determined from the rate at which new ones are made and the expected time period during which responses are expected.
For instance, given a CoAP MAX_TRANSMIT_WAIT of 93 s (
Section 4.8.2 of
RFC 7252), any request that is not answered within 93 s will be considered to have failed. At a request rate of one request per 10 s, at most 10 (ceil(9.3)) requests can be outstanding at a time, and any convenient replay window larger than 20 will work. As replay windows are often implemented with a sliding window and a bit, the use of a 32-bit window would be sufficient.
For use cases where requests are being relayed from another node, the request rate may be estimated by the total link capacity allocated for that kind of traffic. An alternate view would consider how many IPv6 Neighbor Cache Entries (NCEs) the system can afford to allocate for this use.
When using an encryption mode that depends on a nonce, such as AES-CCM, repeated use of the same nonce under the same key causes the cipher to fail catastrophically.
If a nonce is ever used for more than one encryption operation with the same key, then the same key stream gets used to encrypt both plaintexts, and the confidentiality guarantees are voided. Devices with low-quality entropy sources -- as is typical with constrained devices, which incidentally happen to be a natural candidate for the stateless mechanism described in this document -- need to carefully pick a nonce-generation mechanism that provides the above uniqueness guarantee.
[
RFC 8613], Appendix B.1.1 ("Sender Sequence Number") provides a model for how to maintain nonrepeating nonces without causing excessive wear of flash memory.