RFC 9146
Connection Identifier for DTLS 1.2
Connection Identifier for DTLS 1.2 ๐ฆ
Okay bestie, let's get into RFC 9146 ๐. It's titled "Connection Identifier for DTLS 1.2" and it was published in March 2022 by the Internet Engineering Task Force (IETF) โจ. The editors are E. Rescorla (Mozilla) and H. Tschofenig, and the other authors are T. Fossati (Arm Limited) and A. Kraus (Bosch.IO GmbH) ๐. It's a Standards Track document with ISSN 2070-1721. In its title block, the only relationship listed is that it updates RFC 6347, and no Obsoletes line appears ๐ธ.
Abstract ๐ฆ
This doc specifies the Connection ID (CID) construct for version 1.2 of the Datagram Transport Layer Security (DTLS) protocol ๐ .
A CID is an identifier carried in the record layer header ๐. It gives the receiver extra info so it can pick the right security association. In "classical" DTLS, the receiver finds the security association for an incoming record using the 5-tuple. If the source IP address and/or source port changes during the lifetime of an ongoing DTLS session, the receiver can't find the right security context anymore ๐.
The new ciphertext record format with the CID also brings content type encryption and record layer padding ๐.
This doc updates RFC 6347 โจ.
Status of This Memo ๐
This is an Internet Standards Track document ๐.
It's a product of the IETF, which means it reflects the consensus of the IETF community. It went through public review and was approved for publication by the Internet Engineering Steering Group (IESG) ๐ซถ. If you want more on Internet Standards, check out Section 2 of RFC 7841 ๐ง.
You can find info about this document's current status, any errata, and how to send feedback at https://www.rfc-editor.org/info/rfc9146 ๐.
Copyright Notice ๐
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.
This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, at https://trustee.ietf.org/license-info, as they stand on the publication date. Read them carefully, because they spell out your rights and restrictions for this document ๐. Code Components pulled out of this document must include the Revised BSD License text described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as the Revised BSD License says ๐.
This doc may include material from IETF Documents or IETF Contributions that were published or made public before November 10, 2008 ๐. The people who control the copyright in some of that material may not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. So unless you get an adequate license from those copyright holders, this document can't be modified outside the IETF Standards Process, and derivative works of it can't be created outside the IETF Standards Process either. The one exceptions are formatting it for publication as an RFC and translating it into languages other than English ๐ญ.
Table of Contents ๐
1. Introduction
2. Conventions and Terminology
3. The "connection_id" Extension
4. Record Layer Extensions
5. Record Payload Protection
5.1. Block Ciphers
5.2. Block Ciphers with Encrypt-then-MAC Processing
5.3. AEAD Ciphers
6. Peer Address Update
7. Example
8. Privacy Considerations
9. Security Considerations
10. IANA Considerations
10.1. Extra Column Added to the TLS ExtensionType Values
Registry
10.2. New Entry in the TLS ExtensionType Values Registry
10.3. New Entry in the TLS ContentType Registry
11. References
11.1. Normative References
11.2. Informative References
Acknowledgements
Contributors
Authors' Addresses
1. Introduction โจ
DTLS was designed to secure data sent over datagram transports, like UDP [RFC6347] ๐ธ. Like TLS, DTLS starts with a handshake, and that handshake can be pretty computationally heavy, especially when public key cryptography is involved ๐ญ. Once the handshake succeeds, symmetric key cryptography takes over to provide data origin authentication, integrity, and confidentiality protection. This two-step setup lets endpoints spread the cost of the initial handshake across all the application data that comes after it ๐ . Ideally, that second phase runs for a long time, since the keys only need updating once the key lifetime runs out ๐ฅ.
In DTLS as specified in RFC 6347, the IP address and port of the peer are used to identify the DTLS association. Sadly, that's not always enough. In cases like NAT rebinding, those values aren't sufficient ๐. This is a big deal in the Internet of Things, where devices go into long sleep periods to save battery ๐. When NAT rebinding happens, the connection fails, and you're stuck paying for a brand-new handshake ๐.
This document defines an extension to DTLS 1.2 that adds a Connection ID (CID) to the DTLS record layer ๐ฆ. Whether CIDs get used is negotiated through a DTLS extension ๐.
Adding a CID to the ciphertext record format is also a chance to change other stuff in the record format โจ. Following the best practices TLS 1.3 set, the record's type gets encrypted, and there's a mechanism for adding padding to hide the plaintext length ๐.
2. Conventions and Terminology ๐
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" get interpreted as described in BCP 14 [RFC2119] [RFC8174], but only when, and only when, they show up in all capitals, like they do right here ๐ง.
This document assumes you're already familiar with DTLS 1.2 [RFC6347] ๐. The presentation language it uses is described in Section 3 of [RFC8446] ๐.
3. The "connection_id" Extension ๐
This document defines the "connection_id" extension, which shows up in ClientHello and ServerHello messages ๐.
Here's how the extension type is specified:
enum {
connection_id(54), (65535)
} ExtensionType;
The extension_data field of this extension, when it's included in the ClientHello, MUST contain the ConnectionId structure ๐ . That structure holds the CID value the client wants the server to use when sending messages to the client ๐. A zero-length CID value means the client is ready to send using a CID, but it doesn't want the server to use one when sending ๐ธ.
struct {
opaque cid<0..2^8-1>;
} ConnectionId;
A server that's willing to use CIDs responds with a "connection_id" extension in the ServerHello ๐ฆ. That extension contains the CID the server wants the client to use when sending toward it โจ. A zero-length value means the server will send using the client's CID, but it doesn't want the client to include a CID when sending ๐ซถ.
Each party sends the value in the "connection_id" extension that it wants to receive as a CID in encrypted records. Because of that, an endpoint can use a deployment-specific constant length for these identifiers ๐ง. This can make parsing and connection lookup easier, for example by making the length a compile-time constant โญ. Even so, such implementations MUST still be able to send CIDs of different lengths to other parties ๐ฅ. Since the CID length isn't included in the record itself, implementations that want variable-length CIDs are responsible for building the CID so its length can be figured out on reception ๐งฉ.
In DTLS 1.2, CIDs only get exchanged at the very beginning of the DTLS session ๐. There's no dedicated "CID update" message for setting up new CIDs in the middle of a session, because DTLS 1.2 generally doesn't allow TLS 1.3-style post-handshake messages that don't themselves start other handshakes ๐ โโ๏ธ. When a DTLS session is resumed or renegotiated, the "connection_id" extension gets negotiated afresh ๐.
If DTLS peers haven't negotiated CIDs, or a zero-length CID has been advertised for a given direction, then the record format and content type defined in RFC 6347 MUST be used to send in the indicated direction(s) ๐.
If DTLS peers have negotiated a non-zero-length CID for a given direction, then once encryption is enabled, they MUST send with the record format defined in Figure 3 (see Section 4) ๐. That record format uses the new Message Authentication Code (MAC) computation defined in Section 5 and the content type tls12_cid โจ. Plaintext payloads never use the new record format or the CID content type ๐ซ.
When receiving, if the tls12_cid content type is set, the CID gets used to look up the connection and the security association ๐. If the tls12_cid content type isn't set, the connection and security association get looked up by the 5-tuple instead, and a check MUST be made to see whether a non-zero-length CID is expected ๐ต๏ธโโ๏ธ. If a non-zero-length CID is expected for the retrieved association, the datagram MUST be treated as invalid, as described in Section 4.1.2.1 of [RFC6347] ๐.
When a datagram with the tls12_cid content type comes in, the new MAC computation defined in Section 5 MUST be used ๐ฆ. When a datagram with the record format defined in RFC 6347 comes in, the MAC calculation defined in Section 4.1.2 of [RFC6347] MUST be used ๐.
4. Record Layer Extensions โจ
okay bestie, so this section is where the magic happens ๐ฎ it's basically the CID-enhanced record layer format for DTLS 1.2, and [DTLS13] tells you how to carry the CID in DTLS 1.3 ๐ฆ
so how does a receiver even tell if a record has a CID or not?? ๐ค connections that negotiated this extension use a special record type called tls12_cid(25) ๐ using that content type comes with three big vibes:
- the CID field is present and has one or more bytes ๐
- the MAC calculation follows the process in Section 5 ๐ง
- the real content type is hidden inside the encryption envelope, as described below ๐คซ
plaintext records are not impacted by this extension ๐ธ so the DTLSPlaintext structure stays exactly the same, as you can see in Figure 1 ๐
struct {
ContentType type;
ProtocolVersion version;
uint16 epoch;
uint48 sequence_number;
uint16 length;
opaque fragment[DTLSPlaintext.length];
} DTLSPlaintext;
Figure 1: DTLS 1.2 Plaintext Record Payload
when CIDs are in use, the content gets wrapped up with its content type and optional padding into a DTLSInnerPlaintext structure ๐ this is a brand new structure, shown in Figure 2 โจ
struct {
opaque content[length];
ContentType real_type;
uint8 zeros[length_of_padding];
} DTLSInnerPlaintext;
Figure 2: New DTLSInnerPlaintext Payload Structure
- content: corresponds to the fragment of a given length ๐
- real_type: the content type describing the cleartext payload ๐ซถ
- zeros: an arbitrary-length run of zero-valued bytes may appear in the cleartext after the type field ๐ this gives senders an opportunity to pad any DTLS record by a chosen amount, as long as the total stays within record size limits ๐ see Section 5.4 of [RFC8446] for more details (fun fact: the term TLSInnerPlaintext in RFC 8446 refers to DTLSInnerPlaintext in this specification ๐)
then the DTLSInnerPlaintext byte sequence gets encrypted ๐ and to make the DTLSCiphertext structure in Figure 3, the CID gets added ๐ง
struct {
ContentType outer_type = tls12_cid;
ProtocolVersion version;
uint16 epoch;
uint48 sequence_number;
opaque cid[cid_length]; // New field
uint16 length;
opaque enc_content[DTLSCiphertext.length];
} DTLSCiphertext;
Figure 3: DTLS 1.2 CID-Enhanced Ciphertext Record
- outer_type: the outer content type of a DTLSCiphertext record carrying a CID is always set to tls12_cid(25) ๐ the real content type gets found in DTLSInnerPlaintext.real_type after decryption ๐
- cid: the CID value, cid_length bytes long, as agreed when the extension was negotiated ๐ฆ each peer picks the CID value it will receive and use to identify the connection, so an implementation can choose to always receive CIDs of a fixed length ๐ but if an implementation chooses to receive CIDs of different lengths, the assigned CID values MUST be self-delineating, since there is no other mechanism to figure out what connection (and thus, what CID length) is in use ๐โ ๏ธ
- enc_content: the encrypted form of the serialized DTLSInnerPlaintext structure ๐
all other fields are as defined in RFC 6347 ๐
5. Record Payload Protection ๐ก๏ธ
okay so there are a bunch of ciphers for TLS and DTLS ๐ and the MAC calculations for those ciphers differ slightly ๐
this spec tweaks the MAC calculation from [RFC6347] and [RFC7366], plus the additional data used with Authenticated Encryption with Associated Data (AEAD) ciphers from [RFC6347], but only for records with content type tls12_cid ๐ the modified algorithm MUST NOT be applied to records that do not carry a CID, i.e., records with content type other than tls12_cid ๐ซ
these fields are defined in this document ๐ everything else is as defined in the cited docs:
- cid: value of the negotiated CID (variable length) ๐ฆ
- cid_length: the length (in bytes) of the negotiated CID (one-byte integer) ๐ธ
- length_of_DTLSInnerPlaintext: the length (in bytes) of the serialized DTLSInnerPlaintext (two-byte integer) ๐ง the length MUST NOT exceed 2^14 โ ๏ธ
- seq_num_placeholder: 8 bytes of 0xff ๐
- "+" denotes concatenation โ
5.1. Block Ciphers
this MAC algorithm applies to block ciphers that do NOT use the Encrypt-then-MAC processing from [RFC7366] ๐งฉ
MAC(MAC_write_key,
seq_num_placeholder +
tls12_cid +
cid_length +
tls12_cid +
DTLSCiphertext.version +
epoch +
sequence_number +
cid +
length_of_DTLSInnerPlaintext +
DTLSInnerPlaintext.content +
DTLSInnerPlaintext.real_type +
DTLSInnerPlaintext.zeros
);
the reason for this construction is to keep the MAC input for DTLS without the connection ID separate from the MAC input with the connection ID ๐ง the former always starts with a sequence number followed by some content type other than tls12_cid, while the latter always starts with the seq_num_placeholder followed by tls12_cid ๐ even though 2^64-1 is potentially a valid sequence number, tls12_cid will never be a valid content type when the connection ID is not in use ๐ also, epoch and sequence_number now go into the MAC in the same order they appear on the wire ๐ซถ
5.2. Block Ciphers with Encrypt-then-MAC Processing
this MAC algorithm applies to block ciphers that DO use the Encrypt-then-MAC processing from [RFC7366] ๐
MAC(MAC_write_key,
seq_num_placeholder +
tls12_cid +
cid_length +
tls12_cid +
DTLSCiphertext.version +
epoch +
sequence_number +
cid +
DTLSCiphertext.length +
IV +
ENC(content + padding + padding_length)
);
5.3. AEAD Ciphers
for ciphers that use AEAD, the additional data calculation gets this tweak ๐ฆ
additional_data = seq_num_placeholder +
tls12_cid +
cid_length +
tls12_cid +
DTLSCiphertext.version +
epoch +
sequence_number +
cid +
length_of_DTLSInnerPlaintext;
6. Peer Address Update ๐บ๏ธ
okay this part is important, bestie ๐ญ when a record with a CID arrives from a source address that's different from the one currently linked to the DTLS connection, the receiver MUST NOT swap the address it uses for sending records to its peer for the source address in the datagram ๐ โโ๏ธ UNLESS all three of these conditions are met:
- the received datagram has been cryptographically verified using the DTLS record layer processing procedures ๐
- the received datagram is "newer" (in terms of both epoch and sequence number) than the newest datagram received ๐ฐ๏ธ reordered datagrams sent before an address change could otherwise cause a valid address change to get reverted ๐ this also limits an attacker's ability to use replayed datagrams to force a spurious address change, which could lead to denial of service ๐ an attacker might still succeed in changing a peer address if they can rewrite source addresses and replayed packets arrive before any original ๐ฌ
- there is a strategy for making sure the new peer address can receive and process DTLS records ๐ฌ no strategy is mandated by this specification, but see note (*) below ๐
these conditions are necessary to protect against attacks that use spoofed-address datagrams or replayed datagrams to trigger attacks ๐จ there is NO requirement to use the anti-replay window mechanism from Section 4.1.2.6 of [RFC6347] ๐ both solutions, the "anti-replay window" or "newer" algorithm, prevent address updates from replay attacks ๐ก๏ธ the latter only applies to peer address updates, while the former applies to any application layer traffic ๐
datagrams that pass DTLS cryptographic verification but don't trigger a peer address change are still valid DTLS records, and they still get passed to the application ๐
(*) Note: application protocols that protect against spoofed addresses depend on knowing about changes in peer addresses so they can engage the necessary mechanisms ๐ง when they get that event, an address validation mechanism specific to the application layer can be triggered, for example one based on successfully exchanging a minimal amount of ping-pong traffic with the peer ๐ alternatively, a DTLS-specific mechanism may be used, as described in [DTLS-RRC] ๐ฆ
DTLS implementations MUST silently discard records with bad MACs or that are otherwise invalid ๐๏ธโจ
7. Example ๐ฌ
okay so Figure 4 shows an example exchange where a CID is used one way only, from the client to the server ๐ค to show that a zero-length CID is present in the "connection_id" extension, we use the notation 'connection_id=empty' ๐ซง
Client Server
------ ------
ClientHello -------->
(connection_id=empty)
<-------- HelloVerifyRequest
(cookie)
ClientHello -------->
(connection_id=empty)
(cookie)
ServerHello
(connection_id=100)
Certificate
ServerKeyExchange
CertificateRequest
<-------- ServerHelloDone
Certificate
ClientKeyExchange
CertificateVerify
[ChangeCipherSpec]
Finished -------->
<CID=100>
[ChangeCipherSpec]
<-------- Finished
Application Data ========>
<CID=100>
<======== Application Data
Legend:
<...> indicates that a connection ID is used in the record layer
(...) indicates an extension
[...] indicates a payload other than a handshake message
Figure 4: Example DTLS 1.2 Exchange with CID
Note: in the example exchange, the CID is included in the record layer once encryption is enabled ๐ in DTLS 1.2, only one handshake message is encrypted, namely the Finished message ๐ since the example shows how to use the CID for payloads sent from the client to the server, only the record layer payloads containing the Finished message or application data include a CID ๐
8. Privacy Considerations ๐โจ
okay so the CID replaces the old 5-tuple, and that means it's an identifier that sticks around for the whole life of a DTLS connection ๐. Every identifier carries some risk of linkability, as explained in [RFC6973]. literally the whole point of privacy stuff, bestie ๐ซถ
an on-path snoop watching the DTLS exchanges between the client and the server can link the payloads it sees to every later payload that carries the same ID pair (for two-way traffic) ๐ต๏ธโโ๏ธ. without multihoming or mobility, the CID leaks the same info the 5-tuple already did, so it's not a brand new problem, just a continuation ๐
now with multihoming ๐, a passive attacker can correlate the conversation across both paths. DTLS 1.2 has no CID update mechanism, so this extension is not a good fit for mobility scenarios where correlation matters ๐ซ. deployments using DTLS with multihoming that care about this SHOULD refuse to use CIDs in DTLS 1.2 and switch to DTLS 1.3, which gives you a CID update mechanism and sequence number encryption ๐ฅ. big glow-up energy ๐ฆ
this spec adds record padding for the CID-enhanced record layer ๐. that's a privacy feature the original DTLS 1.2 spec didn't have. padding lets the ciphertext size get inflated, which makes traffic analysis harder ๐. more on record padding in Section 5.4 and Appendix E.3 of [RFC8446] ๐
last one, and it's a serious one ๐ญ. endpoints can use the CID to attach arbitrary per-connection metadata to every record they receive on a connection. that could be used to pass per-connection info to on-path observers ๐. there's no straightforward fix for this when the CIDs can hold arbitrary values. implementations that are worried about this SHOULD refuse to use CIDs ๐
9. Security Considerations ๐จ
not gonna lie, this section is kind of intense ๐. an on-path attacker can run reflection attacks against third parties, because a DTLS peer has no way to tell a genuine address update (like one caused by a NAT rebinding ๐) from a malicious one. this gets especially scary when the request is tiny and the response is huge ๐ฑ. see Section 6 for more on address updates ๐ง
also, anyone who can observe the data traffic between two DTLS peers can replay datagrams with the IP addresses and port numbers changed ๐
the peer address update topic is covered in Section 6 ๐
10. IANA Considerations ๐
this document makes three IANA updates โจ
10.1. Extra Column Added to the TLS ExtensionType Values Registry ๐
IANA added a new column called "DTLS-Only" to the "TLS ExtensionType Values" registry. it says whether an extension only applies to DTLS, and it also lists this document as an extra reference for the registry ๐
10.2. New Entry in the TLS ExtensionType Values Registry ๐ฆ
IANA gave connection_id(54) its own entry in the existing "TLS ExtensionType Values" registry, as shown in the table below ๐. the value 53 had been given out through early allocation for an older version of this document, but it doesn't work with this one. so that early allocation got deprecated in favor of this assignment ๐ญ
+=======+===============+=====+===========+=============+===========+
| Value |Extension Name | TLS | DTLS-Only | Recommended | Reference |
| | | 1.3 | | | |
+=======+===============+=====+===========+=============+===========+
| 54 |connection_id | CH, | Y | N | RFC 9146 |
| | | SH | | | |
+-------+---------------+-----+-----------+-------------+-----------+
Table 1
the new "DTLS-Only" column takes "Y" if the extension only applies to DTLS and "N" otherwise. every pre-existing entry got "N" ๐ธ
Note: The value "N" in the "Recommended" column is set because this extension is intended only for specific use cases. This document describes the behavior of this extension for DTLS 1.2 only; it is not applicable to TLS, and its usage for DTLS 1.3 is described in [DTLS13].
10.3. New Entry in the TLS ContentType Registry ๐ง
IANA allocated tls12_cid(25) in the "TLS ContentType" registry. this content type only applies to DTLS 1.2 ๐
11. References ๐
11.1. Normative References ๐
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC6347] Rescorla, E. and N. Modadugu, "Datagram Transport Layer
Security Version 1.2", RFC 6347, DOI 10.17487/RFC6347,
January 2012, <https://www.rfc-editor.org/info/rfc6347>.
[RFC7366] Gutmann, P., "Encrypt-then-MAC for Transport Layer
Security (TLS) and Datagram Transport Layer Security
(DTLS)", RFC 7366, DOI 10.17487/RFC7366, September 2014,
<https://www.rfc-editor.org/info/rfc7366>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
<https://www.rfc-editor.org/info/rfc8446>.
11.2. Informative References ๐ฆ
[DTLS-RRC] Tschofenig, H., Ed. and T. Fossati, "Return Routability
Check for DTLS 1.2 and DTLS 1.3", Work in Progress,
Internet-Draft, draft-ietf-tls-dtls-rrc-05, 7 March 2022,
<https://datatracker.ietf.org/doc/html/draft-ietf-tls-
dtls-rrc-05>.
[DTLS13] Rescorla, E., Tschofenig, H., and N. Modadugu, "The
Datagram Transport Layer Security (DTLS) Protocol Version
1.3", Work in Progress, Internet-Draft, draft-ietf-tls-
dtls13-43, 30 April 2021,
<https://datatracker.ietf.org/doc/html/draft-ietf-tls-
dtls13-43>.
[RFC6973] Cooper, A., Tschofenig, H., Aboba, B., Peterson, J.,
Morris, J., Hansen, M., and R. Smith, "Privacy
Considerations for Internet Protocols", RFC 6973,
DOI 10.17487/RFC6973, July 2013,
<https://www.rfc-editor.org/info/rfc6973>.
Acknowledgements ๐
we'd like to thank Hanno Becker, Martin Duke, Lars Eggert, Ben Kaduk, Warren Kumari, Francesca Palombini, Tom Petch, John Scudder, Sean Turner, รric Vyncke, and Robert Wilton for their review comments ๐ซถ
and a big thank you to the IETF TLS Working Group chairs, Chris Wood, Joseph Salowey, and Sean Turner, for their patience, support, and feedback ๐
Contributors ๐ธ
loads of people helped build this spec, and we want to shout out these individuals for their contributions โจ
Yin Xinxing
Huawei
Email: yinxinxing@huawei.com
Nikos Mavrogiannopoulos
RedHat
Email: nmav@redhat.com
Tobias Gondrom
Email: tobias.gondrom@gondrom.org
we also want to thank the Connection ID task force team members ๐ง
- Martin Thomson (Mozilla)
- Christian Huitema (Private Octopus Inc.)
- Jana Iyengar (Google)
- Daniel Kahn Gillmor (ACLU)
- Patrick McManus (Mozilla)
- Ian Swett (Google)
- Mark Nottingham (Fastly)
the task force looked at a bunch of design ideas, including cryptographically generated session IDs using hash chains and public key encryption ๐ค. they got dismissed because they were too inefficient ๐. the approach in this spec is the simplest design that works, given the limits of DTLS 1.2 ๐. DTLS 1.3 has better privacy features, so devs are encouraged to switch to the new version ๐ฆ๐ฅ
Authors' Addresses ๐
Eric Rescorla (editor)
Mozilla
Email: ekr@rtfm.com
Hannes Tschofenig (editor)
Arm Limited
Email: hannes.tschofenig@arm.com
Thomas Fossati
Arm Limited
Email: thomas.fossati@arm.com
Achim Kraus
Bosch.IO GmbH
Email: achim.kraus@bosch.io
๐ฆ where this page comes from
- ietf: rfc9146 2022-03
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms