11#if (DETWS_ENABLE_HTTP3 || DETWS_ENABLE_DTLS)
14#if DETWS_ENABLE_PQC_KEX
22 static constexpr uint16_t TLS_EXT_SERVER_NAME = 0x0000;
23 static constexpr uint16_t TLS_EXT_SUPPORTED_GROUPS = 0x000a;
24 static constexpr uint16_t TLS_EXT_SIGNATURE_ALGORITHMS = 0x000d;
25 static constexpr uint16_t TLS_EXT_ALPN = 0x0010;
26 static constexpr uint16_t TLS_EXT_SUPPORTED_VERSIONS = 0x002b;
27 static constexpr uint16_t TLS_EXT_COOKIE = 0x002c;
28 static constexpr uint16_t TLS_EXT_KEY_SHARE = 0x0033;
29 static constexpr uint16_t TLS_EXT_CONNECTION_ID = 0x0036;
45void w_u8(Writer *w, uint8_t v)
56void w_u16(Writer *w, uint16_t v)
58 w_u8(w, (uint8_t)(v >> 8));
61void w_u24(Writer *w, uint32_t v)
63 w_u8(w, (uint8_t)(v >> 16));
64 w_u8(w, (uint8_t)(v >> 8));
67void w_bytes(Writer *w,
const uint8_t *b,
size_t n)
74 if (w->pos > w->cap || n > w->cap - w->pos)
79 memcpy(w->buf + w->pos, b, n);
83size_t w_mark(Writer *w,
size_t nbytes)
86 for (
size_t i = 0; i < nbytes; i++)
90void w_patch16(Writer *w,
size_t at)
94 uint16_t len = (uint16_t)(w->pos - at - 2);
95 w->buf[at] = (uint8_t)(len >> 8);
96 w->buf[at + 1] = (uint8_t)len;
98void w_patch24(Writer *w,
size_t at)
102 uint32_t len = (uint32_t)(w->pos - at - 3);
103 w->buf[at] = (uint8_t)(len >> 16);
104 w->buf[at + 1] = (uint8_t)(len >> 8);
105 w->buf[at + 2] = (uint8_t)len;
115bool r_u8(Reader *r, uint8_t *v)
117 if (r->pos + 1 > r->len)
119 *v = r->buf[r->pos++];
122bool r_u16(Reader *r, uint16_t *v)
124 if (r->pos + 2 > r->len)
126 *v = (uint16_t)((r->buf[r->pos] << 8) | r->buf[r->pos + 1]);
130bool r_u24(Reader *r, uint32_t *v)
132 if (r->pos + 3 > r->len)
134 *v = (uint32_t)((r->buf[r->pos] << 16) | (r->buf[r->pos + 1] << 8) | r->buf[r->pos + 2]);
139bool r_take(Reader *r,
size_t n,
const uint8_t **out)
141 if (r->pos + n > r->len)
143 *out = r->buf + r->pos;
155bool list16_contains(
const uint8_t *body,
size_t body_len,
size_t list_len, uint16_t target)
157 if (list_len > body_len || (list_len % 2) != 0)
159 for (
size_t i = 0; i + 1 < list_len; i += 2)
160 if (((body[i] << 8) | body[i + 1]) == target)
166void parse_key_share(
const uint8_t *body,
size_t blen, Tls13ClientHello *out)
170 size_t ll = (body[0] << 8) | body[1];
177 uint16_t group = (uint16_t)((body[i] << 8) | body[i + 1]);
178 uint16_t klen = (uint16_t)((body[i + 2] << 8) | body[i + 3]);
182 if (group == TLS_GROUP_X25519 && klen == 32)
184 memcpy(out->client_x25519, body + i, 32);
185 out->has_key_share =
true;
187#if DETWS_ENABLE_PQC_KEX
188 else if (group == TLS_GROUP_X25519MLKEM768 && klen == MLKEM768_EK_BYTES + 32)
190 out->client_mlkem_ek = body + i;
191 memcpy(out->client_x25519, body + i + MLKEM768_EK_BYTES, 32);
192 out->has_hybrid_share =
true;
200void parse_alpn(
const uint8_t *body,
size_t blen, Tls13ClientHello *out)
204 size_t ll = (body[0] << 8) | body[1];
211 size_t nl = body[i++];
214 if (nl == 2 && body[i] ==
'h' && body[i + 1] ==
'3')
215 out->offers_h3_alpn =
true;
221void parse_server_name(
const uint8_t *body,
size_t blen, Tls13ClientHello *out)
225 size_t ll = (body[0] << 8) | body[1];
232 uint8_t nt = body[i++];
233 size_t nl = (body[i] << 8) | body[i + 1];
235 if (nt == 0 && i + nl <= end)
242void parse_extension(uint16_t type,
const uint8_t *body,
size_t blen, Tls13ClientHello *out,
bool dtls)
246 case TlsExt::TLS_EXT_SUPPORTED_VERSIONS: {
251 out->offers_tls13 = list16_contains(body + 1, blen - 1, ll, dtls ? TLS_VERSION_DTLS_1_3 : TLS_VERSION_1_3);
254 case TlsExt::TLS_EXT_SUPPORTED_GROUPS: {
257 size_t ll = (body[0] << 8) | body[1];
258 out->offers_x25519 = list16_contains(body + 2, blen - 2, ll, TLS_GROUP_X25519);
259#if DETWS_ENABLE_PQC_KEX
260 out->offers_x25519mlkem768 = list16_contains(body + 2, blen - 2, ll, TLS_GROUP_X25519MLKEM768);
264 case TlsExt::TLS_EXT_SIGNATURE_ALGORITHMS: {
267 size_t ll = (body[0] << 8) | body[1];
268 out->offers_ed25519 = list16_contains(body + 2, blen - 2, ll, TLS_SIG_ED25519);
271 case TlsExt::TLS_EXT_KEY_SHARE:
272 parse_key_share(body, blen, out);
274 case TlsExt::TLS_EXT_ALPN:
275 parse_alpn(body, blen, out);
277 case TLS_EXT_QUIC_TRANSPORT_PARAMS:
279 out->quic_tp_len = blen;
281 case TlsExt::TLS_EXT_COOKIE: {
285 size_t cl = (size_t)((body[0] << 8) | body[1]);
288 out->cookie = body + 2;
289 out->cookie_len = cl;
292 case TlsExt::TLS_EXT_CONNECTION_ID: {
300 out->has_conn_id =
true;
301 out->conn_id = body + 1;
302 out->conn_id_len = cl;
305 case TlsExt::TLS_EXT_SERVER_NAME:
306 parse_server_name(body, blen, out);
314bool tls13_parse_client_hello(
const uint8_t *msg,
size_t len, Tls13ClientHello *out,
bool dtls)
316 memset(out, 0,
sizeof(*out));
318 Reader r = {msg, len, 0};
320 uint32_t body_len = 0;
321 if (!r_u8(&r, &type) || type != TlsHs::TLS_HS_CLIENT_HELLO || !r_u24(&r, &body_len))
324 if (r.pos + body_len > len)
326 r.len = r.pos + body_len;
328 uint16_t legacy_version = 0;
329 const uint8_t *random =
nullptr;
330 if (!r_u16(&r, &legacy_version) || !r_take(&r, 32, &random))
334 if (!r_u8(&r, &sid_len) || sid_len > 32)
336 if (!r_take(&r, sid_len, &out->session_id))
338 out->session_id_len = sid_len;
344 uint8_t cookie_len = 0;
345 const uint8_t *cookie =
nullptr;
346 if (!r_u8(&r, &cookie_len) || !r_take(&r, cookie_len, &cookie))
351 const uint8_t *cs =
nullptr;
352 if (!r_u16(&r, &cs_len) || (cs_len % 2) != 0 || !r_take(&r, cs_len, &cs))
355 uint8_t comp_len = 0;
356 const uint8_t *comp =
nullptr;
357 if (!r_u8(&r, &comp_len) || !r_take(&r, comp_len, &comp))
361 uint16_t ext_total = 0;
362 if (!r_u16(&r, &ext_total))
364 size_t ext_end = r.pos + ext_total;
367 while (r.pos < ext_end)
371 const uint8_t *ebody =
nullptr;
372 if (!r_u16(&r, &etype) || !r_u16(&r, &elen) || !r_take(&r, elen, &ebody))
374 parse_extension(etype, ebody, elen, out, dtls);
382size_t tls13_build_server_hello(uint8_t *out,
size_t cap,
const uint8_t random[32],
const uint8_t *session_id,
383 uint8_t session_id_len,
const uint8_t *share,
size_t share_len, uint16_t group,
384 bool dtls,
const uint8_t *conn_id,
size_t conn_id_len)
386 Writer w = {out, cap, 0,
true};
387 w_u8(&w, TlsHs::TLS_HS_SERVER_HELLO);
388 size_t hs_len = w_mark(&w, 3);
391 w_u16(&w, dtls ? TLS_LEGACY_VERSION_DTLS : (uint16_t)0x0303);
392 w_bytes(&w, random, 32);
393 w_u8(&w, session_id_len);
394 w_bytes(&w, session_id, session_id_len);
395 w_u16(&w, TLS_CIPHER_AES_128_GCM_SHA256);
398 size_t ext_len = w_mark(&w, 2);
401 w_u16(&w, TlsExt::TLS_EXT_KEY_SHARE);
402 w_u16(&w, (uint16_t)(4 + share_len));
404 w_u16(&w, (uint16_t)share_len);
405 w_bytes(&w, share, share_len);
407 w_u16(&w, TlsExt::TLS_EXT_SUPPORTED_VERSIONS);
409 w_u16(&w, dtls ? TLS_VERSION_DTLS_1_3 : TLS_VERSION_1_3);
414 w_u16(&w, TlsExt::TLS_EXT_CONNECTION_ID);
415 w_u16(&w, (uint16_t)(1 + conn_id_len));
416 w_u8(&w, (uint8_t)conn_id_len);
417 w_bytes(&w, conn_id, conn_id_len);
419 w_patch16(&w, ext_len);
421 w_patch24(&w, hs_len);
422 return w.ok ? w.pos : 0;
426const uint8_t tls13_hrr_random[32] = {0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C,
427 0x02, 0x1E, 0x65, 0xB8, 0x91, 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB,
428 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C};
430size_t tls13_build_hello_retry_request(uint8_t *out,
size_t cap,
const uint8_t *session_id, uint8_t session_id_len,
431 uint16_t selected_group,
const uint8_t *cookie,
size_t cookie_len,
bool dtls)
433 if (cookie_len > 0xFFFD)
435 Writer w = {out, cap, 0,
true};
436 w_u8(&w, TlsHs::TLS_HS_SERVER_HELLO);
437 size_t hs_len = w_mark(&w, 3);
442 w_u16(&w, dtls ? TLS_LEGACY_VERSION_DTLS : (uint16_t)0x0303);
443 w_bytes(&w, tls13_hrr_random, 32);
444 w_u8(&w, session_id_len);
445 w_bytes(&w, session_id, session_id_len);
446 w_u16(&w, TLS_CIPHER_AES_128_GCM_SHA256);
449 size_t ext_len = w_mark(&w, 2);
451 w_u16(&w, TlsExt::TLS_EXT_SUPPORTED_VERSIONS);
453 w_u16(&w, dtls ? TLS_VERSION_DTLS_1_3 : TLS_VERSION_1_3);
455 w_u16(&w, TlsExt::TLS_EXT_KEY_SHARE);
457 w_u16(&w, selected_group);
461 w_u16(&w, TlsExt::TLS_EXT_COOKIE);
462 w_u16(&w, (uint16_t)(cookie_len + 2));
463 w_u16(&w, (uint16_t)cookie_len);
464 w_bytes(&w, cookie, cookie_len);
466 w_patch16(&w, ext_len);
468 w_patch24(&w, hs_len);
469 return w.ok ? w.pos : 0;
472size_t tls13_build_encrypted_extensions_empty(uint8_t *out,
size_t cap)
474 Writer w = {out, cap, 0,
true};
475 w_u8(&w, TlsHs::TLS_HS_ENCRYPTED_EXTENSIONS);
476 size_t hs_len = w_mark(&w, 3);
478 w_patch24(&w, hs_len);
479 return w.ok ? w.pos : 0;
482size_t tls13_build_message_hash(uint8_t *out,
size_t cap,
const uint8_t ch1_hash[32])
484 Writer w = {out, cap, 0,
true};
487 w_bytes(&w, ch1_hash, 32);
488 return w.ok ? w.pos : 0;
491size_t tls13_build_encrypted_extensions(uint8_t *out,
size_t cap,
const uint8_t *quic_tp,
size_t quic_tp_len)
493 Writer w = {out, cap, 0,
true};
494 w_u8(&w, TlsHs::TLS_HS_ENCRYPTED_EXTENSIONS);
495 size_t hs_len = w_mark(&w, 3);
497 size_t ext_len = w_mark(&w, 2);
499 w_u16(&w, TlsExt::TLS_EXT_ALPN);
503 w_bytes(&w, (
const uint8_t *)
"h3", 2);
505 w_u16(&w, TLS_EXT_QUIC_TRANSPORT_PARAMS);
506 w_u16(&w, (uint16_t)quic_tp_len);
507 w_bytes(&w, quic_tp, quic_tp_len);
508 w_patch16(&w, ext_len);
510 w_patch24(&w, hs_len);
511 return w.ok ? w.pos : 0;
514size_t tls13_build_certificate(uint8_t *out,
size_t cap,
const uint8_t *cert_der,
size_t cert_len)
516 Writer w = {out, cap, 0,
true};
517 w_u8(&w, TlsHs::TLS_HS_CERTIFICATE);
518 size_t hs_len = w_mark(&w, 3);
521 size_t list_len = w_mark(&w, 3);
522 w_u24(&w, (uint32_t)cert_len);
523 w_bytes(&w, cert_der, cert_len);
525 w_patch24(&w, list_len);
527 w_patch24(&w, hs_len);
528 return w.ok ? w.pos : 0;
531size_t tls13_cert_verify_content(uint8_t *out,
size_t cap,
const uint8_t transcript_hash[32],
bool is_server)
534 static const char SRV[] =
"TLS 1.3, server CertificateVerify";
535 static const char CLI[] =
"TLS 1.3, client CertificateVerify";
536 const char *ctx = is_server ? SRV : CLI;
537 size_t ctx_len = is_server ?
sizeof(SRV) - 1 : sizeof(CLI) - 1;
538 size_t total = 64 + ctx_len + 1 + 32;
541 memset(out, 0x20, 64);
542 memcpy(out + 64, ctx, ctx_len);
543 out[64 + ctx_len] = 0x00;
544 memcpy(out + 64 + ctx_len + 1, transcript_hash, 32);
548size_t tls13_build_cert_verify(uint8_t *out,
size_t cap,
const uint8_t transcript_hash[32],
const uint8_t seed[32])
550 uint8_t content[64 + 33 + 1 + 32];
551 size_t clen = tls13_cert_verify_content(content,
sizeof(content), transcript_hash,
true);
560 Writer w = {out, cap, 0,
true};
561 w_u8(&w, TlsHs::TLS_HS_CERTIFICATE_VERIFY);
562 size_t hs_len = w_mark(&w, 3);
563 w_u16(&w, TLS_SIG_ED25519);
566 w_patch24(&w, hs_len);
567 return w.ok ? w.pos : 0;
570size_t tls13_build_finished(uint8_t *out,
size_t cap,
const uint8_t verify_data[32])
572 Writer w = {out, cap, 0,
true};
573 w_u8(&w, TlsHs::TLS_HS_FINISHED);
574 size_t hs_len = w_mark(&w, 3);
575 w_bytes(&w, verify_data, 32);
576 w_patch24(&w, hs_len);
577 return w.ok ? w.pos : 0;
ML-KEM-768 encapsulation (FIPS 203), responder side only.
void ssh_ed25519_sign(uint8_t sig[64], const uint8_t *msg, size_t mlen, const uint8_t seed[32])
Ed25519 signatures (RFC 8032) for ssh-ed25519 host keys + client auth.
#define SSH_ED25519_SIG_LEN
Ed25519 signature length (R || S).
TLS 1.3 handshake messages for the QUIC handshake (RFC 8446 sec 4).