ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
tls13_msg.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file tls13_msg.h
6 * @brief TLS 1.3 handshake messages for the QUIC handshake (RFC 8446 sec 4).
7 *
8 * The wire formats of the handshake messages a QUIC server exchanges: it parses the client's
9 * ClientHello and builds its own flight (ServerHello, then the encrypted EncryptedExtensions,
10 * Certificate, CertificateVerify, and Finished). Every message is emitted whole, including the
11 * 4-byte handshake header (msg_type + 24-bit length), because that is what both the CRYPTO stream
12 * carries and the transcript hash covers.
13 *
14 * This server is deliberately a single, spec-valid profile: cipher suite TLS_AES_128_GCM_SHA256,
15 * key share X25519, and an Ed25519 certificate (the only signature scheme we produce - the in-tree
16 * crypto has Ed25519 but no ECDSA P-256 or RSA-PSS). A ClientHello that offers none of these is a
17 * handshake failure, decided by the state machine that drives this module. QUIC transport parameters
18 * ride in the quic_transport_parameters extension (codepoint 0x39, RFC 9001 sec 8.2).
19 *
20 * Pure, zero heap, host-tested against the RFC 8448 sec 3 ServerHello / Certificate / Finished bytes
21 * and by ClientHello field extraction + an Ed25519 CertificateVerify sign/verify round-trip.
22 *
23 * @author Douglas Quigg (dstroy0)
24 * @date 2026
25 */
26
27#ifndef PROTOCORE_TLS13_MSG_H
28#define PROTOCORE_TLS13_MSG_H
29
30#include "protocore_config.h" // the entry point: the enable gate below, and the widths
31
32#if (PROTOCORE_ENABLE_HTTP3 || PROTOCORE_ENABLE_DTLS || PROTOCORE_ENABLE_TLS)
33
35
36// Shared by the HTTP/3 (QUIC) handshake and the DTLS 1.3 handshake: both carry the same TLS 1.3
37// messages, so this module compiles for either. The DTLS-specific additions (HelloRetryRequest, the
38// cookie extension, the sec 4.4.1 message_hash) are used by the DTLS handshake but are valid TLS 1.3.
39// The RFC 7250 RawPublicKey credential a Certificate may carry instead of an X.509 chain is
40// tls13_rpk's.
41//
42// This module holds nothing between calls, so it carves no borrow and states none. An entry
43// takes one all the same, and never reads it, so every namespace in the tree is invoked the
44// same way.
45
46/** @brief TLS handshake message types (RFC 8446 sec 4). */
47#define TLS_HS_CLIENT_HELLO 1
48#define TLS_HS_SERVER_HELLO 2
49#define TLS_HS_ENCRYPTED_EXTENSIONS 8
50#define TLS_HS_CERTIFICATE 11
51#define TLS_HS_CERTIFICATE_VERIFY 15
52#define TLS_HS_FINISHED 20
53
54// The two RFC 8446 sec B.4 mandatory-to-implement suites, as their IANA code points. These are the
55// numbers on the wire; ::TlsCipher names the same two for the record layer and takes its values here.
56#define PROTOCORE_TLS_SUITE_AES_128_GCM_SHA256 0x1301 ///< AEAD_AES_128_GCM with a SHA-256 schedule
57#define PROTOCORE_TLS_SUITE_AES_256_GCM_SHA384 0x1302 ///< AEAD_AES_256_GCM with a SHA-384 schedule
58#define TLS_GROUP_X25519 0x001d ///< the classical key-exchange group we support
59#define TLS_X25519_SHARE_LEN 32 ///< an X25519 key_share, and the shared secret it produces (RFC 7748 sec 6.1)
60#define TLS_GROUP_X25519MLKEM768 0x11ec ///< PQ/T hybrid group (ML-KEM-768 + X25519), when PROTOCORE_ENABLE_PQC_KEX
61#define TLS_SIG_ED25519 0x0807 ///< the one signature scheme we produce
62
63// SignatureScheme code points a CertificateVerify may carry (RFC 8446 sec 4.2.3). The
64// RSASSA-PKCS1-v1_5 values are deliberately absent: sec 4.2.3 says they "refer solely to signatures
65// which appear in certificates ... and are not defined for use in signed TLS handshake messages".
66#define TLS_SIG_ECDSA_SECP256R1_SHA256 0x0403 ///< ECDSA over P-256 with SHA-256
67#define TLS_SIG_RSA_PSS_RSAE_SHA256 0x0804 ///< RSASSA-PSS with an rsaEncryption key
68#define TLS_CERT_TYPE_X509 0 ///< RFC 7250 CertificateType: X.509 (IANA "TLS Certificate Types" 0)
69#define TLS_CERT_TYPE_RAW_PUBLIC_KEY \
70 2 ///< RFC 7250 CertificateType: RawPublicKey (IANA 2), when PROTOCORE_ENABLE_TLS_RPK
71#define TLS_VERSION_1_3 0x0304 ///< supported_versions selected value (TLS 1.3)
72#define PROTOCORE_TLS_VERSION_DTLS_1_3 0xFEFC ///< supported_versions selected value (DTLS 1.3, RFC 9147)
73#define PROTOCORE_TLS_LEGACY_VERSION_DTLS 0xFEFD ///< legacy_version on the wire for DTLS (DTLS 1.2)
74#define TLS_EXT_QUIC_TRANSPORT_PARAMS 0x0039 ///< quic_transport_parameters (RFC 9001 sec 8.2)
75
76/** @brief What the state machine needs out of a parsed ClientHello (pointers alias the input). */
77typedef struct
78{
79 const uint8_t *session_id; ///< legacy_session_id (echoed back in ServerHello)
80 uint8_t session_id_len;
81 uint8_t client_x25519[32]; ///< the client's X25519 key_share (valid iff has_key_share or has_hybrid_share)
82 proto_bool has_key_share;
83#if PROTOCORE_ENABLE_PQC_KEX
84 proto_bool offers_x25519mlkem768; ///< supported_groups contains X25519MLKEM768
85 proto_bool has_hybrid_share; ///< key_share carried an X25519MLKEM768 entry
86 const uint8_t *client_mlkem_ek; ///< the client's ML-KEM-768 encapsulation key (1184 B, aliases input)
87#endif
88 proto_bool offers_tls13; ///< supported_versions contains 0x0304
89 proto_bool offers_aes128gcm_sha256; ///< cipher_suites contains TLS_AES_128_GCM_SHA256
90 proto_bool offers_aes256gcm_sha384; ///< cipher_suites contains TLS_AES_256_GCM_SHA384
91 proto_bool offers_x25519; ///< supported_groups contains x25519
92 proto_bool offers_ed25519; ///< signature_algorithms contains ed25519
93 proto_bool has_server_cert_type; ///< a server_certificate_type extension (RFC 7250) was present
94 proto_bool offers_x509_server_cert; ///< that extension's list contained X509(0)
95#if PROTOCORE_ENABLE_TLS_RPK
96 proto_bool offers_rpk_server_cert; ///< server_certificate_type (RFC 7250) offered RawPublicKey(2)
97#endif
98 proto_bool offers_h3_alpn; ///< ALPN contains "h3"
99 const uint8_t *alpn_list; ///< the ProtocolNameList body (aliases input), or NULL when absent
100 size_t alpn_list_len; ///< how many bytes of it there are
101 const uint8_t *quic_tp; ///< raw quic_transport_parameters extension body (or NULL)
102 size_t quic_tp_len;
103 const uint8_t *sni; ///< first server_name host_name (or NULL), not NUL-terminated
104 size_t sni_len;
105 const uint8_t *cookie; ///< cookie extension body echoed after a HelloRetryRequest (or NULL); DTLS §5.1
106 size_t cookie_len;
107 proto_bool has_conn_id; ///< the connection_id extension was present (RFC 9146 / RFC 9147 §9)
108 const uint8_t *conn_id; ///< the CID the client wants the server to use in records sent to it (may be empty)
109 size_t conn_id_len; ///< length of @c conn_id (0..255; 0 = the client wants a zero-length CID)
110} Tls13ClientHello;
111
112/** @brief A parsed ServerHello (RFC 8446 sec 4.1.3). Pointer fields alias the input, not copied. */
113typedef struct
114{
115 const uint8_t *random; ///< the 32-byte Random (aliases input)
116 const uint8_t *session_id; ///< legacy_session_id_echo (aliases input)
117 uint8_t session_id_len;
118 uint16_t cipher_suite; ///< the suite the server selected
119 proto_bool selected_tls13; ///< supported_versions carried the 1.3 code point
120 proto_bool is_hrr; ///< the Random is the fixed HelloRetryRequest value (sec 4.1.3)
121 proto_bool has_key_share; ///< a key_share extension was present
122 uint16_t group; ///< its NamedGroup: the server's share, or a HelloRetryRequest's selected_group
123 const uint8_t *share; ///< the server's key_exchange (aliases input); NULL in a HelloRetryRequest
124 size_t share_len;
125 const uint8_t *cookie; ///< cookie to echo in the retried ClientHello (aliases input), or NULL
126 size_t cookie_len;
127 proto_bool has_conn_id; ///< a connection_id extension was present (RFC 9146 / RFC 9147 §9)
128 const uint8_t *conn_id; ///< the CID to place in records sent to the server (aliases input)
129 size_t conn_id_len;
130} Tls13ServerHello;
131
132/** @brief The fixed HelloRetryRequest random - SHA-256("HelloRetryRequest"), RFC 8446 §4.1.3. A
133 * ServerHello carrying this random _is_ a HelloRetryRequest. 32 bytes. */
134extern const uint8_t protocore_tls13_hrr_random[32];
135
136/** @brief What parse_client_hello takes: msg, len, out, dtls. */
137typedef struct
138{
139 const uint8_t *msg;
140 size_t len;
141 Tls13ClientHello *out;
142 proto_bool dtls; ///< true for a DTLS ClientHello (RFC 9147 §5.3), which carries an extra legacy_cookie field ...
143} Tls13MsgParseClientHelloArgs;
144
145/** @brief What parse_server_hello takes: msg, len, out, dtls. */
146typedef struct
147{
148 const uint8_t *msg;
149 size_t len;
150 Tls13ServerHello *out;
151 proto_bool dtls; ///< true for DTLS, whose supported_versions selection is 0xFEFC (RFC 9147 §5.3)
152} Tls13MsgParseServerHelloArgs;
153
154/** @brief What build_client_hello takes: out, cap, random, ... */
155typedef struct
156{
157 uint8_t *out;
158 size_t cap;
159 const uint8_t *random; ///< 32 bytes.
160 const uint8_t *session_id;
161 uint8_t session_id_len;
162 const uint8_t *share;
163 size_t share_len;
164 uint16_t group;
165 uint16_t suite; ///< the one cipher suite offered, as its IANA code point
166 const char *sni;
167 const char *alpn;
168 const uint8_t *cookie;
169 size_t cookie_len;
170 proto_bool rpk_server_cert;
171 proto_bool dtls;
172} Tls13MsgBuildClientHelloArgs;
173
174/** @brief What parse_certificate takes: msg, len, cert, cert_len. */
175typedef struct
176{
177 const uint8_t *msg;
178 size_t len;
179 const uint8_t **cert;
180 size_t *cert_len;
181} Tls13MsgParseCertificateArgs;
182
183/** @brief What parse_cert_verify takes: msg, len, scheme, sig, sig_len. */
184typedef struct
185{
186 const uint8_t *msg;
187 size_t len;
188 uint16_t *scheme;
189 const uint8_t **sig;
190 size_t *sig_len;
191} Tls13MsgParseCertVerifyArgs;
192
193/** @brief What parse_finished takes: msg, len, vd, verify_len. */
194typedef struct
195{
196 const uint8_t *msg;
197 size_t len;
198 const uint8_t **vd;
199 size_t verify_len; ///< the suite's Hash.length, which sec 4.4.4 makes the body's exact size
200} Tls13MsgParseFinishedArgs;
201
202/** @brief What build_server_hello takes: out, cap, random, ... */
203typedef struct
204{
205 uint8_t *out;
206 size_t cap;
207 const uint8_t *random; ///< 32-byte server random 32 bytes.
208 const uint8_t *session_id; ///< legacy_session_id_echo (the client's, echoed verbatim; may be NULL if len 0)
209 uint8_t session_id_len; ///< echoed session-id length (0..32)
210 const uint8_t
211 *share; ///< the server's key_share (X25519 pub for the classical group, or the ciphertext || X25519 ...
212 size_t share_len; ///< length of share (32 for X25519, 1120 for the hybrid)
213 uint16_t group; ///< the selected named group (TLS_GROUP_X25519 or TLS_GROUP_X25519MLKEM768)
214 uint16_t suite; ///< the selected cipher suite, as its IANA code point
215 proto_bool dtls; ///< true to emit the DTLS 1.3 version codepoints (RFC 9147 §5.3), false for TLS 1.3
216 const uint8_t *conn_id; ///< when non-NULL, emit a connection_id extension (RFC 9146 / RFC 9147 §9) carrying the ...
217 size_t conn_id_len; ///< length of conn_id (0..255)
218} Tls13MsgBuildServerHelloArgs;
219
220/** @brief What build_encrypted_extensions takes: out, cap, quic_tp, ... */
221typedef struct
222{
223 uint8_t *out;
224 size_t cap;
225 const uint8_t *quic_tp;
226 size_t quic_tp_len;
227 proto_bool rpk_server_cert; ///< when true (PROTOCORE_ENABLE_TLS_RPK), also emit the negotiated
228 ///< server_certificate_type = ...
229} Tls13MsgBuildEncryptedExtensionsArgs;
230
231/** @brief What build_certificate takes: out, cap, cert_der, cert_len. */
232typedef struct
233{
234 uint8_t *out;
235 size_t cap;
236 const uint8_t *cert_der;
237 size_t cert_len;
238} Tls13MsgBuildCertificateArgs;
239
240/** @brief What build_cert_verify takes: sign_work, out, cap, ... */
241typedef struct
242{
243 uint8_t *sign_work;
244 uint8_t *out;
245 size_t cap;
246 const uint8_t *transcript_hash; ///< Transcript-Hash through the Certificate message
247 size_t hash_len; ///< its length: the suite's Hash.length, at most PROTOCORE_TLS13_SECRET_MAX
248 const uint8_t *seed; ///< 32-byte Ed25519 private seed 32 bytes.
249} Tls13MsgBuildCertVerifyArgs;
250
251/** @brief What build_finished takes: out, cap, verify_data, verify_len. */
252typedef struct
253{
254 uint8_t *out;
255 size_t cap;
256 const uint8_t *verify_data;
257 size_t verify_len;
258} Tls13MsgBuildFinishedArgs;
259
260/** @brief What cert_verify_content takes: out, cap, transcript_hash, ... */
261typedef struct
262{
263 uint8_t *out;
264 size_t cap;
265 const uint8_t *transcript_hash;
266 size_t hash_len;
267 proto_bool is_server;
268} Tls13MsgCertVerifyContentArgs;
269
270/** @brief What build_hello_retry_request takes: out, cap, session_id, ... */
271typedef struct
272{
273 uint8_t *out;
274 size_t cap;
275 const uint8_t *session_id; ///< legacy_session_id_echo (the client's, echoed verbatim; may be NULL if len 0)
276 uint8_t session_id_len;
277 uint16_t selected_group; ///< the NamedGroup the server wants the client's key_share for
278 uint16_t suite; ///< the selected cipher suite, as its IANA code point; §4.1.4 makes the retried ServerHello ...
279 const uint8_t *cookie; ///< the return-routability cookie the client must echo (may be NULL if len 0)
280 size_t cookie_len;
281 proto_bool dtls; ///< true to emit the DTLS 1.3 version codepoints (0xFEFD / 0xFEFC, RFC 9147 §5.3); false for ...
282} Tls13MsgBuildHelloRetryRequestArgs;
283
284/** @brief What build_encrypted_extensions_empty takes: out, cap, ... */
285typedef struct
286{
287 uint8_t *out;
288 size_t cap;
289 proto_bool rpk_server_cert;
290 const char *alpn;
291} Tls13MsgBuildEncryptedExtensionsEmptyArgs;
292
293/** @brief What build_message_hash takes: out, cap, ch1_hash. */
294typedef struct
295{
296 uint8_t *out;
297 size_t cap;
298 const uint8_t *ch1_hash; ///< 32 bytes.
299} Tls13MsgBuildMessageHashArgs;
300
301/**
302 * @brief TLS 1.3 handshake messages for the QUIC handshake (RFC 8446 sec 4).
303 *
304 * A caller sets the members a call takes, invokes it through ::Tls13Msg with the bytes it runs
305 * out of, and reads the outcome off the same handle.
306 *
307 * Tls13Msg.parse_client_hello_args.msg = ...;
308 * Tls13Msg.parse_client_hello_args.len = ...;
309 * Tls13Msg.parse_client_hello_args.out = ...;
310 * Tls13Msg.parse_client_hello_args.dtls = ...;
311 * Tls13Msg.parse_client_hello(work);
312 * // Tls13Msg.ok is what the call reports
313 *
314 * @var Tls13MsgNs::parse_client_hello_args what parse_client_hello takes: msg, len, out, dtls
315 * @var Tls13MsgNs::parse_server_hello_args what parse_server_hello takes: msg, len, out, dtls
316 * @var Tls13MsgNs::build_client_hello_args what build_client_hello takes: out, cap, random,
317 * @var Tls13MsgNs::parse_certificate_args what parse_certificate takes: msg, len, cert, cert_len
318 * @var Tls13MsgNs::parse_cert_verify_args what parse_cert_verify takes: msg, len, scheme, sig, sig_len
319 * @var Tls13MsgNs::parse_finished_args what parse_finished takes: msg, len, vd, verify_len
320 * @var Tls13MsgNs::build_server_hello_args what build_server_hello takes: out, cap, random,
321 * @var Tls13MsgNs::build_encrypted_extensions_args what build_encrypted_extensions takes: out, cap, quic_tp,
322 * @var Tls13MsgNs::build_certificate_args what build_certificate takes: out, cap, cert_der, cert_len
323 * @var Tls13MsgNs::build_cert_verify_args what build_cert_verify takes: sign_work, out, cap,
324 * @var Tls13MsgNs::build_finished_args what build_finished takes: out, cap, verify_data, verify_len
325 * @var Tls13MsgNs::cert_verify_content_args what cert_verify_content takes: out, cap, transcript_hash,
326 * @var Tls13MsgNs::build_hello_retry_request_args what build_hello_retry_request takes: out, cap, session_id,
327 * @var Tls13MsgNs::build_encrypted_extensions_empty_args what build_encrypted_extensions_empty takes: out, cap,
328 * @var Tls13MsgNs::build_message_hash_args what build_message_hash takes: out, cap, ch1_hash
329 * @var Tls13MsgNs::ok false if it is not a well-formed ClientHello. Missing/!supported ...
330 * @var Tls13MsgNs::n bytes written, or 0 on overflow
331 * @var Tls13MsgNs::parse_client_hello parse a ClientHello handshake message (msg includes the 4-byte ...
332 * @var Tls13MsgNs::parse_server_hello parse a ServerHello handshake message (msg includes the 4-byte ...
333 * @var Tls13MsgNs::build_client_hello build a ClientHello (RFC 8446 sec 4.1.2) offering TLS 1.3, suite, ...
334 * @var Tls13MsgNs::parse_certificate the first CertificateEntry's cert_data in a Certificate message ...
335 * @var Tls13MsgNs::parse_cert_verify the algorithm and signature of a CertificateVerify (RFC 8446 sec ...
336 * @var Tls13MsgNs::parse_finished the verify_data of a Finished (RFC 8446 sec 4.4.4). vd points into ...
337 * @var Tls13MsgNs::build_server_hello build a ServerHello (RFC 8446 sec 4.1.3) selecting TLS 1.3 / ...
338 * @var Tls13MsgNs::build_encrypted_extensions build EncryptedExtensions (RFC 8446 sec 4.3.1) carrying ALPN "h3" ...
339 * @var Tls13MsgNs::build_certificate build a Certificate message (RFC 8446 sec 4.4.2) with an empty ...
340 * @var Tls13MsgNs::build_cert_verify build a CertificateVerify (RFC 8446 sec 4.4.3) with an Ed25519 ...
341 * @var Tls13MsgNs::build_finished build a Finished message (RFC 8446 sec 4.4.4) carrying verify_data ...
342 * @var Tls13MsgNs::cert_verify_content assemble the sec 4.4.3 signed content into out (64*0x20 || context ...
343 * @var Tls13MsgNs::build_hello_retry_request build a HelloRetryRequest (RFC 8446 §4.1.4): a ServerHello whose ...
344 * @var Tls13MsgNs::build_encrypted_extensions_empty build an EncryptedExtensions (RFC 8446 §4.3.1) for the DTLS ...
345 * @var Tls13MsgNs::build_message_hash write the synthetic message_hash handshake message that replaces ...
346 *
347 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
348 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
349 * a caller drives every namespace the same way.
350 */
351typedef struct
352{
353 Tls13MsgParseClientHelloArgs parse_client_hello_args;
354 Tls13MsgParseServerHelloArgs parse_server_hello_args;
355 Tls13MsgBuildClientHelloArgs build_client_hello_args;
356 Tls13MsgParseCertificateArgs parse_certificate_args;
357 Tls13MsgParseCertVerifyArgs parse_cert_verify_args;
358 Tls13MsgParseFinishedArgs parse_finished_args;
359 Tls13MsgBuildServerHelloArgs build_server_hello_args;
360 Tls13MsgBuildEncryptedExtensionsArgs build_encrypted_extensions_args;
361 Tls13MsgBuildCertificateArgs build_certificate_args;
362 Tls13MsgBuildCertVerifyArgs build_cert_verify_args;
363 Tls13MsgBuildFinishedArgs build_finished_args;
364 Tls13MsgCertVerifyContentArgs cert_verify_content_args;
365 Tls13MsgBuildHelloRetryRequestArgs build_hello_retry_request_args;
366 Tls13MsgBuildEncryptedExtensionsEmptyArgs build_encrypted_extensions_empty_args;
367 Tls13MsgBuildMessageHashArgs build_message_hash_args;
368 proto_bool ok;
369 size_t n;
370} Tls13MsgVars;
371
372/** @brief The operands and the outcome. */
373extern Tls13MsgVars Tls13MsgV;
374
375/** @brief The entries. */
376typedef struct
377{
378 void (*const parse_client_hello)(uint8_t *work);
379 void (*const parse_server_hello)(uint8_t *work);
380 void (*const build_client_hello)(uint8_t *work);
381 void (*const parse_certificate)(uint8_t *work);
382 void (*const parse_cert_verify)(uint8_t *work);
383 void (*const parse_finished)(uint8_t *work);
384 void (*const build_server_hello)(uint8_t *work);
385 void (*const build_encrypted_extensions)(uint8_t *work);
386 void (*const build_certificate)(uint8_t *work);
387 void (*const build_cert_verify)(uint8_t *work);
388 void (*const build_finished)(uint8_t *work);
389 void (*const cert_verify_content)(uint8_t *work);
390 void (*const build_hello_retry_request)(uint8_t *work);
391 void (*const build_encrypted_extensions_empty)(uint8_t *work);
392 void (*const build_message_hash)(uint8_t *work);
393} Tls13MsgNs;
394
395// What the table binds, defined once in the .c and taking one parameter each: everything
396// else an entry needs is an operand in Tls13MsgV or a region of the borrow at a fixed offset.
397void protocore_tls13_msg_parse_client_hello(uint8_t *work);
398void protocore_tls13_msg_parse_server_hello(uint8_t *work);
399void protocore_tls13_msg_build_client_hello(uint8_t *work);
400void protocore_tls13_msg_parse_certificate(uint8_t *work);
401void protocore_tls13_msg_parse_cert_verify(uint8_t *work);
402void protocore_tls13_msg_parse_finished(uint8_t *work);
403void protocore_tls13_msg_build_server_hello(uint8_t *work);
404void protocore_tls13_msg_build_encrypted_extensions(uint8_t *work);
405void protocore_tls13_msg_build_certificate(uint8_t *work);
406void protocore_tls13_msg_build_cert_verify(uint8_t *work);
407void protocore_tls13_msg_build_finished(uint8_t *work);
408void protocore_tls13_msg_cert_verify_content(uint8_t *work);
409void protocore_tls13_msg_build_hello_retry_request(uint8_t *work);
410void protocore_tls13_msg_build_encrypted_extensions_empty(uint8_t *work);
411void protocore_tls13_msg_build_message_hash(uint8_t *work);
412
413// `static const`, initialised HERE rather than `extern` against a definition in the .c: a
414// const object whose initializer every translation unit can see is a COMPILE-TIME FACT, so
415// `Tls13Msg.parse_client_hello(work)` resolves to a named function and becomes a DIRECT call. An extern table
416// leaves the call indirect and the symbol live at every level, -O2 -flto included.
417static const Tls13MsgNs Tls13Msg __attribute__((unused)) = {
418 .parse_client_hello = protocore_tls13_msg_parse_client_hello,
419 .parse_server_hello = protocore_tls13_msg_parse_server_hello,
420 .build_client_hello = protocore_tls13_msg_build_client_hello,
421 .parse_certificate = protocore_tls13_msg_parse_certificate,
422 .parse_cert_verify = protocore_tls13_msg_parse_cert_verify,
423 .parse_finished = protocore_tls13_msg_parse_finished,
424 .build_server_hello = protocore_tls13_msg_build_server_hello,
425 .build_encrypted_extensions = protocore_tls13_msg_build_encrypted_extensions,
426 .build_certificate = protocore_tls13_msg_build_certificate,
427 .build_cert_verify = protocore_tls13_msg_build_cert_verify,
428 .build_finished = protocore_tls13_msg_build_finished,
429 .cert_verify_content = protocore_tls13_msg_cert_verify_content,
430 .build_hello_retry_request = protocore_tls13_msg_build_hello_retry_request,
431 .build_encrypted_extensions_empty = protocore_tls13_msg_build_encrypted_extensions_empty,
432 .build_message_hash = protocore_tls13_msg_build_message_hash,
433};
434
436
437#endif // (PROTOCORE_ENABLE_HTTP3 || PROTOCORE_ENABLE_DTLS || PROTOCORE_ENABLE_TLS)
438
439#endif // PROTOCORE_TLS13_MSG_H
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97