# `./fio-stl/190 tls13.h`

60 public symbols.

### Macros

#### `FIO_TLS13_SHA256_HASH_LEN`

```c
#define FIO_TLS13_SHA256_HASH_LEN 32
```

SHA-256 hash length (32 bytes).

_Symbol type:_ `macro`

#### `FIO_TLS13_SHA384_HASH_LEN`

```c
#define FIO_TLS13_SHA384_HASH_LEN 48
```

SHA-384 hash length (48 bytes).

_Symbol type:_ `macro`

#### `FIO_TLS13_MAX_HASH_LEN`

```c
#define FIO_TLS13_MAX_HASH_LEN 48
```

Maximum hash length supported.

_Symbol type:_ `macro`

#### `FIO_TLS13_AES128_KEY_LEN`

```c
#define FIO_TLS13_AES128_KEY_LEN 16
```

AES-128-GCM key length.

_Symbol type:_ `macro`

#### `FIO_TLS13_AES256_KEY_LEN`

```c
#define FIO_TLS13_AES256_KEY_LEN 32
```

AES-256-GCM key length.

_Symbol type:_ `macro`

#### `FIO_TLS13_CHACHA_KEY_LEN`

```c
#define FIO_TLS13_CHACHA_KEY_LEN 32
```

ChaCha20-Poly1305 key length.

_Symbol type:_ `macro`

#### `FIO_TLS13_IV_LEN`

```c
#define FIO_TLS13_IV_LEN 12
```

IV length for all AEAD ciphers.

_Symbol type:_ `macro`

#### `FIO_TLS13_RECORD_HEADER_LEN`

```c
#define FIO_TLS13_RECORD_HEADER_LEN 5
```

TLS record header length (5 bytes)

_Symbol type:_ `macro`

#### `FIO_TLS13_MAX_PLAINTEXT_LEN`

```c
#define FIO_TLS13_MAX_PLAINTEXT_LEN 16384
```

Maximum plaintext fragment length (2^14 = 16384 bytes)

_Symbol type:_ `macro`

#### `FIO_TLS13_MAX_CIPHERTEXT_LEN`

```c
#define FIO_TLS13_MAX_CIPHERTEXT_LEN (16384 + 256)
```

Maximum ciphertext length (plaintext + padding + tag)

_Symbol type:_ `macro`

#### `FIO_TLS13_TAG_LEN`

```c
#define FIO_TLS13_TAG_LEN 16
```

AEAD authentication tag length (16 bytes for all TLS 1.3 ciphers)

_Symbol type:_ `macro`

#### `FIO_TLS13_LEGACY_VERSION_MAJOR`

```c
#define FIO_TLS13_LEGACY_VERSION_MAJOR 0x03
```

Legacy TLS version bytes (0x0303 = TLS 1.2)

_Symbol type:_ `macro`

#### `FIO_TLS13_LEGACY_VERSION_MINOR`

```c
#define FIO_TLS13_LEGACY_VERSION_MINOR 0x03
```



_Symbol type:_ `macro`

#### `FIO_TLS13_VERSION_TLS12`

```c
#define FIO_TLS13_VERSION_TLS12 0x0303
```

TLS 1.3 Protocol Version Constants

_Symbol type:_ `macro`

#### `FIO_TLS13_VERSION_TLS13`

```c
#define FIO_TLS13_VERSION_TLS13 0x0304
```



_Symbol type:_ `macro`

#### `FIO_TLS13_HRR_RANDOM`

```c
#define FIO_TLS13_HRR_RANDOM   \
  "\xCF\x21\xAD\x74\xE5\x9A\x61\x11\xBE\x1D\x8C\x02\x1E\x65\xB8\x91"   \
  "\xC2\xA2\x11\x16\x7A\xBB\x8C\x5E\x07\x9E\x09\xE2\xC8\xA8\x33\x9C"
```

HelloRetryRequest magic random value (RFC 8446 Section 4.1.3)

_Symbol type:_ `macro`

### Types

#### `fio_tls13_content_type_e`

```c
typedef enum {
FIO_TLS13_CONTENT_INVALID = 0,
FIO_TLS13_CONTENT_CHANGE_CIPHER_SPEC = 20, /* Legacy, ignored in TLS 1.3 */
FIO_TLS13_CONTENT_ALERT = 21,
FIO_TLS13_CONTENT_HANDSHAKE = 22,
FIO_TLS13_CONTENT_APPLICATION_DATA = 23,
} fio_tls13_content_type_e
```

TLS 1.3 content types

_Symbol type:_ `type`

#### `fio_tls13_handshake_type_e`

```c
typedef enum {
FIO_TLS13_HS_CLIENT_HELLO = 1,
FIO_TLS13_HS_SERVER_HELLO = 2,
FIO_TLS13_HS_NEW_SESSION_TICKET = 4,
FIO_TLS13_HS_END_OF_EARLY_DATA = 5,
FIO_TLS13_HS_ENCRYPTED_EXTENSIONS = 8,
FIO_TLS13_HS_CERTIFICATE = 11,
FIO_TLS13_HS_CERTIFICATE_REQUEST = 13,
FIO_TLS13_HS_CERTIFICATE_VERIFY = 15,
FIO_TLS13_HS_FINISHED = 20,
FIO_TLS13_HS_KEY_UPDATE = 24,
FIO_TLS13_HS_MESSAGE_HASH = 254,
} fio_tls13_handshake_type_e
```

TLS 1.3 Handshake Message Types

_Symbol type:_ `type`

#### `fio_tls13_key_update_request_e`

```c
typedef enum {
FIO_TLS13_KEY_UPDATE_NOT_REQUESTED = 0,
FIO_TLS13_KEY_UPDATE_REQUESTED = 1,
} fio_tls13_key_update_request_e
```

TLS 1.3 KeyUpdate Request Types (RFC 8446 Section 4.6.3)

_Symbol type:_ `type`

#### `fio_tls13_extension_type_e`

```c
typedef enum {
FIO_TLS13_EXT_SERVER_NAME = 0, /* SNI */
FIO_TLS13_EXT_SUPPORTED_GROUPS = 10, /* Key exchange groups */
FIO_TLS13_EXT_SIGNATURE_ALGORITHMS = 13, /* Signature schemes */
FIO_TLS13_EXT_ALPN = 16, /* Application-Layer Protocol Negotiation */
FIO_TLS13_EXT_SUPPORTED_VERSIONS = 43, /* TLS version negotiation */
FIO_TLS13_EXT_COOKIE = 44, /* Cookie for HRR (RFC 8446 4.2.2) */
FIO_TLS13_EXT_CERTIFICATE_AUTHORITIES =
47, /* Acceptable CAs (RFC 8446 4.2.4) */
FIO_TLS13_EXT_SIGNATURE_ALGORITHMS_CERT = 50, /* Cert chain sig algs */
FIO_TLS13_EXT_KEY_SHARE = 51, /* ECDHE key shares */
} fio_tls13_extension_type_e
```

TLS 1.3 Extension Types (RFC 8446 Section 4.2)

_Symbol type:_ `type`

#### `fio_tls13_cipher_suite_e`

```c
typedef enum {
FIO_TLS13_CIPHER_SUITE_AES_128_GCM_SHA256 = 0x1301,
FIO_TLS13_CIPHER_SUITE_AES_256_GCM_SHA384 = 0x1302,
FIO_TLS13_CIPHER_SUITE_CHACHA20_POLY1305_SHA256 = 0x1303,
} fio_tls13_cipher_suite_e
```

TLS 1.3 Cipher Suites (RFC 8446 Section B.4)

_Symbol type:_ `type`

#### `fio_tls13_named_group_e`

```c
typedef enum {
FIO_TLS13_GROUP_SECP256R1 = 23, /* P-256 */
FIO_TLS13_GROUP_SECP384R1 = 24, /* P-384 */
FIO_TLS13_GROUP_X25519 = 29, /* Curve25519 */
FIO_TLS13_GROUP_X25519MLKEM768 =
0x11ec, /* X25519 + ML-KEM-768 hybrid (PQC) */
} fio_tls13_named_group_e
```

TLS 1.3 Named Groups (RFC 8446 Section 4.2.7, draft-ietf-tls-hybrid-design)

_Symbol type:_ `type`

#### `fio_tls13_signature_algo_e`

```c
typedef enum {
FIO_TLS13_SIGNATURE_RSA_PKCS1_SHA256 = 0x0401,
FIO_TLS13_SIGNATURE_RSA_PKCS1_SHA384 = 0x0501,
FIO_TLS13_SIGNATURE_RSA_PKCS1_SHA512 = 0x0601,
FIO_TLS13_SIGNATURE_ECDSA_SECP256R1_SHA256 = 0x0403,
FIO_TLS13_SIGNATURE_ECDSA_SECP384R1_SHA384 = 0x0503,
FIO_TLS13_SIGNATURE_RSA_PSS_RSAE_SHA256 = 0x0804,
FIO_TLS13_SIGNATURE_RSA_PSS_RSAE_SHA384 = 0x0805,
FIO_TLS13_SIGNATURE_ED25519 = 0x0807,
} fio_tls13_signature_algo_e
```

TLS 1.3 Signature Algorithms (RFC 8446 Section 4.2.3)

_Symbol type:_ `type`

#### `fio_tls13_server_hello_s`

```c
typedef struct {
uint8_t random[32]; /* Server random */
uint16_t cipher_suite; /* Selected cipher suite */
uint8_t
key_share[1120]; /* Server's key share (max size for X25519MLKEM768) */
uint16_t key_share_len; /* Length of key share */
uint16_t key_share_group; /* Selected group */
int is_hello_retry_request; /* 1 if HRR */
} fio_tls13_server_hello_s
```

Parsed ServerHello message

_Symbol type:_ `type`

#### `fio_tls13_encrypted_extensions_s`

```c
typedef struct {
int has_server_name; /* Server acknowledged SNI */
char alpn_selected[256]; /* Selected ALPN protocol (null-terminated) */
size_t alpn_selected_len; /* Length of selected ALPN protocol */
} fio_tls13_encrypted_extensions_s
```

Parsed EncryptedExtensions message

_Symbol type:_ `type`

#### `fio_tls13_certificate_s`

```c
typedef struct {
fio_ubuf_info_s cert; /* First certificate (view into message data) */
} fio_tls13_certificate_s
```

Parsed Certificate message (minimal - first cert only)

_Symbol type:_ `type`

#### `fio_tls13_certificate_verify_s`

```c
typedef struct {
fio_ubuf_info_s signature; /* Signature (view into message data) */
uint16_t signature_algo;
} fio_tls13_certificate_verify_s
```

Parsed CertificateVerify message

_Symbol type:_ `type`

#### `fio_tls13_certificate_request_s`

```c
typedef struct {
fio_ubuf_info_s authorities; /* Raw CA DNs data (view into message) */
size_t context_len; /* Context length (0-255) */
size_t algo_count; /* Number of signature algorithms */
size_t cert_algos_count; /* Number of cert sig algos */
uint16_t algos[16]; /* Required signature algorithms */
uint16_t cert_algos[16]; /* Cert chain sig algos (optional) */
uint8_t context[255]; /* Opaque context */
} fio_tls13_certificate_request_s
```

Parsed CertificateRequest message (RFC 8446 Section 4.3.2)

_Symbol type:_ `type`

#### `fio_tls13_cipher_type_e`

```c
typedef enum {
FIO_TLS13_CIPHER_AES_128_GCM = 0, /* TLS_AES_128_GCM_SHA256 */
FIO_TLS13_CIPHER_AES_256_GCM = 1, /* TLS_AES_256_GCM_SHA384 */
FIO_TLS13_CIPHER_CHACHA20_POLY1305 = 2, /* TLS_CHACHA20_POLY1305_SHA256 */
} fio_tls13_cipher_type_e
```

Supported AEAD cipher types for TLS 1.3

_Symbol type:_ `type`

#### `fio_tls13_plaintext_header_s`

```c
typedef struct {
uint8_t content_type; /* ContentType */
uint8_t legacy_version[2]; /* 0x03, 0x03 (TLS 1.2) */
uint16_t length; /* Fragment length (big-endian) */
/* Fragment follows (up to 2^14 bytes) */
} fio_tls13_plaintext_header_s
```

TLSPlaintext header structure (RFC 8446 Section 5.1)

_Symbol type:_ `type`

#### `fio_tls13_ciphertext_header_s`

```c
typedef struct {
uint8_t opaque_type; /* Always 23 (application_data) */
uint8_t legacy_version[2]; /* 0x03, 0x03 */
uint16_t length; /* Encrypted length + tag (big-endian) */
/* Encrypted content follows */
} fio_tls13_ciphertext_header_s
```

TLSCiphertext header structure (RFC 8446 Section 5.2)

_Symbol type:_ `type`

#### `fio_tls13_record_keys_s`

```c
typedef struct {
uint8_t key[32]; /* Write key (16 or 32 bytes depending on cipher) */
uint8_t iv[12]; /* Write IV (always 12 bytes) */
uint64_t sequence_number; /* Per-record sequence number (starts at 0) */
uint8_t key_len; /* 16 for AES-128, 32 for AES-256/ChaCha20 */
uint8_t cipher_type; /* fio_tls13_cipher_type_e */
} fio_tls13_record_keys_s
```

Record encryption context (per-direction keys)

_Symbol type:_ `type`

### Functions

#### `fio_tls13_hkdf_expand_label`

```c
void fio_tls13_hkdf_expand_label(void *restrict out, size_t out_len, const void *restrict secret, size_t secret_len, const char *label, size_t label_len, const void *restrict context, size_t context_len, int use_sha384)
```

TLS 1.3 HKDF-Expand-Label function.

Derives keying material using the TLS 1.3 specific label format.

**Parameters:**
- `out` - Output buffer for derived key material
- `out_len` - Desired output length (max 255)
- `secret` - The secret to expand (PRK from HKDF-Extract)
- `secret_len` - Secret length (32 for SHA-256, 48 for SHA-384)
- `label` - The label string (without "tls13 " prefix)
- `label_len` - Label length (max 249 to fit in 255 with prefix)
- `context` - Optional context (transcript hash or empty)
- `context_len` - Context length (max 255)
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_derive_secret`

```c
void fio_tls13_derive_secret(void *restrict out, const void *restrict secret, size_t secret_len, const char *label, size_t label_len, const void *restrict transcript_hash, size_t hash_len, int use_sha384)
```

TLS 1.3 Derive-Secret function.

Derives a secret from a base secret and transcript hash.

**Parameters:**
- `out` - Output buffer (32 bytes for SHA-256, 48 for SHA-384)
- `secret` - The base secret
- `secret_len` - Secret length
- `label` - The label string (e.g., "c hs traffic")
- `label_len` - Label length
- `transcript_hash` - Hash of handshake messages (or empty hash for "")
- `hash_len` - Hash length (32 or 48)
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_derive_early_secret`

```c
void fio_tls13_derive_early_secret(void *restrict early_secret, const void *restrict psk, size_t psk_len, int use_sha384)
```

Derive the Early Secret from PSK.

Early Secret = HKDF-Extract(salt=0, IKM=PSK)

**Parameters:**
- `early_secret` - Output buffer (32 or 48 bytes)
- `psk` - Pre-shared key (or NULL/zeros for no PSK)
- `psk_len` - PSK length (0 if no PSK)
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_derive_handshake_secret`

```c
void fio_tls13_derive_handshake_secret(void *restrict handshake_secret, const void *restrict early_secret, const void *restrict ecdhe_secret, size_t ecdhe_len, int use_sha384)
```

Derive the Handshake Secret from ECDHE shared secret.

Handshake Secret = HKDF-Extract(
    salt=Derive-Secret(Early Secret, "derived", ""),
    IKM=ECDHE shared secret
)

**Parameters:**
- `handshake_secret` - Output buffer (32 or 48 bytes)
- `early_secret` - The early secret (from fio_tls13_derive_early_secret)
- `ecdhe_secret` - The ECDHE shared secret (e.g., from X25519)
- `ecdhe_len` - ECDHE secret length (32 for X25519)
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_derive_master_secret`

```c
void fio_tls13_derive_master_secret(void *restrict master_secret, const void *restrict handshake_secret, int use_sha384)
```

Derive the Master Secret.

Master Secret = HKDF-Extract(
    salt=Derive-Secret(Handshake Secret, "derived", ""),
    IKM=0
)

**Parameters:**
- `master_secret` - Output buffer (32 or 48 bytes)
- `handshake_secret` - The handshake secret
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_derive_traffic_keys`

```c
void fio_tls13_derive_traffic_keys(void *restrict key, size_t key_len, void *restrict iv, const void *restrict traffic_secret, int use_sha384)
```

Derive traffic keys and IV from a traffic secret.

**Parameters:**
- `key` - Output buffer for write key
- `key_len` - Key length (16 for AES-128, 32 for AES-256/ChaCha20)
- `iv` - Output buffer for write IV (12 bytes)
- `traffic_secret` - The traffic secret (client/server handshake/app)
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_derive_finished_key`

```c
void fio_tls13_derive_finished_key(void *restrict finished_key, const void *restrict traffic_secret, int use_sha384)
```

Derive the Finished key from a traffic secret.

finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length)

**Parameters:**
- `finished_key` - Output buffer (32 or 48 bytes)
- `traffic_secret` - The handshake traffic secret
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_compute_finished`

```c
void fio_tls13_compute_finished(void *restrict verify_data, const void *restrict finished_key, const void *restrict transcript_hash, int use_sha384)
```

Compute the Finished verify_data.

verify_data = HMAC(finished_key, Transcript-Hash(Handshake Context))

**Parameters:**
- `verify_data` - Output buffer (32 or 48 bytes)
- `finished_key` - The finished key (from fio_tls13_derive_finished_key)
- `transcript_hash` - Hash of handshake messages up to this point
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_update_traffic_secret`

```c
void fio_tls13_update_traffic_secret(void *restrict new_secret, const void *restrict current_secret, int use_sha384)
```

Update application traffic secret for key update.

application_traffic_secret_N+1 =
    HKDF-Expand-Label(application_traffic_secret_N, "traffic upd", "",
Hash.length)

**Parameters:**
- `new_secret` - Output buffer (32 or 48 bytes)
- `current_secret` - Current application traffic secret
- `use_sha384` - If non-zero, use SHA-384; otherwise SHA-256

_Symbol type:_ `function`

#### `fio_tls13_build_nonce`

```c
inline void fio_tls13_build_nonce(uint8_t nonce[12], const uint8_t iv[12], uint64_t seq)
```

Build per-record nonce by XORing sequence number with IV.

Per RFC 8446 Section 5.3:
- Pad 64-bit sequence number to 12 bytes (big-endian, left-padded with zeros)
- XOR with the static IV derived from traffic secret

**Parameters:**
- `nonce` - Output buffer (must be 12 bytes)
- `iv` - Static IV from key derivation (12 bytes)
- `seq` - 64-bit sequence number

_Symbol type:_ `function`

#### `fio_tls13_record_parse_header`

```c
const uint8_t *fio_tls13_record_parse_header( const uint8_t *data, size_t data_len, fio_tls13_content_type_e *content_type, size_t *payload_len)
```

Parse a TLS record header.

**Parameters:**
- `data` - Input buffer containing record data
- `data_len` - Length of input buffer
- `content_type` - Output: content type from header
- `payload_len` - Output: payload length from header

**Returns:**
- Pointer to payload data, or NULL if incomplete/invalid

_Symbol type:_ `function`

#### `fio_tls13_record_encrypt`

```c
int fio_tls13_record_encrypt(uint8_t *out, size_t out_capacity, const uint8_t *plaintext, size_t plaintext_len, fio_tls13_content_type_e content_type, fio_tls13_record_keys_s *keys)
```

Encrypt a TLS 1.3 record.

Per RFC 8446 Section 5.2:
- Output format: 5-byte header + encrypted(plaintext + content_type) + tag
- AAD is the 5-byte record header
- Sequence number is incremented after encryption

**Parameters:**
- `out` - Output buffer for encrypted record
- `out_capacity` - Capacity of output buffer
- `plaintext` - Plaintext data to encrypt
- `plaintext_len` - Length of plaintext
- `content_type` - Content type (appended to plaintext before encryption)
- `keys` - Encryption keys (sequence number will be incremented)

**Returns:**
- Total output length (header + ciphertext + tag), or -1 on error

_Symbol type:_ `function`

#### `fio_tls13_record_decrypt`

```c
int fio_tls13_record_decrypt(uint8_t *out, size_t out_capacity, fio_tls13_content_type_e *content_type, const uint8_t *ciphertext, size_t ciphertext_len, fio_tls13_record_keys_s *keys)
```

Decrypt a TLS 1.3 record.

Per RFC 8446 Section 5.2:
- Input includes 5-byte header
- Decrypts and verifies AEAD tag
- Scans backwards to find real content type (removes padding)
- Sequence number is incremented after successful decryption

Note: decryption is performed in-place in the ciphertext buffer, so the
ciphertext buffer will be modified. The output buffer only needs to hold
the plaintext (not the internal content type byte).

**Parameters:**
- `out` - Output buffer for decrypted plaintext
- `out_capacity` - Capacity of output buffer (>= plaintext length)
- `content_type` - Output: actual content type from inner plaintext
- `ciphertext` - Input ciphertext (includes 5-byte header, modified)
- `ciphertext_len` - Total length including header
- `keys` - Decryption keys (sequence number will be incremented)

**Returns:**
- Plaintext length (excluding padding and content type), or -1 on error

_Symbol type:_ `function`

#### `fio_tls13_record_keys_init`

```c
void fio_tls13_record_keys_init(fio_tls13_record_keys_s *keys, const uint8_t *key, uint8_t key_len, const uint8_t iv[12], fio_tls13_cipher_type_e cipher_type)
```

Initialize record keys structure.

**Parameters:**
- `keys` - Keys structure to initialize
- `key` - Key material (16 or 32 bytes)
- `key_len` - Key length (16 for AES-128, 32 for AES-256/ChaCha20)
- `iv` - IV material (12 bytes)
- `cipher_type` - Cipher type (fio_tls13_cipher_type_e)

_Symbol type:_ `function`

#### `fio_tls13_record_keys_clear`

```c
inline void fio_tls13_record_keys_clear(fio_tls13_record_keys_s *keys)
```

Clear sensitive key material from memory.

**Parameters:**
- `keys` - Keys structure to clear

_Symbol type:_ `function`

#### `fio_tls13_parse_handshake_header`

```c
const uint8_t *fio_tls13_parse_handshake_header( const uint8_t *data, size_t data_len, fio_tls13_handshake_type_e *msg_type, size_t *body_len)
```

Parse handshake header, return message type and body pointer.

Returns pointer to message body, or NULL on error.
Sets msg_type and body_len on success.

_Symbol type:_ `function`

#### `fio_tls13_write_handshake_header`

```c
void fio_tls13_write_handshake_header(uint8_t *out, fio_tls13_handshake_type_e msg_type, size_t body_len)
```

Write handshake header (4 bytes).

Format: HandshakeType (1 byte) + uint24 length (3 bytes)

_Symbol type:_ `function`

#### `fio_tls13_build_client_hello`

```c
int fio_tls13_build_client_hello(uint8_t *out, size_t out_capacity, const uint8_t random[32], const char *server_name, const uint8_t *x25519_pubkey, const uint16_t *cipher_suites, size_t cipher_suite_count)
```

Build a ClientHello message.

Returns: message length on success, -1 on error.

Parameters:
- out: output buffer
- out_capacity: size of output buffer
- random: 32-byte client random
- server_name: SNI hostname (NULL if not used)
- x25519_pubkey: 32-byte X25519 public key
- cipher_suites: array of cipher suites to offer
- cipher_suite_count: number of cipher suites

_Symbol type:_ `function`

#### `fio_tls13_parse_server_hello`

```c
int fio_tls13_parse_server_hello(fio_tls13_server_hello_s *out, const uint8_t *data, size_t data_len)
```

Parse ServerHello message.

Returns: 0 on success, -1 on error.

Note: data should point to the handshake body (after the 4-byte header).

_Symbol type:_ `function`

#### `fio_tls13_parse_encrypted_extensions`

```c
int fio_tls13_parse_encrypted_extensions( fio_tls13_encrypted_extensions_s *out, const uint8_t *data, size_t data_len)
```

Parse EncryptedExtensions message.

Returns: 0 on success, -1 on error.

_Symbol type:_ `function`

#### `fio_tls13_parse_certificate`

```c
int fio_tls13_parse_certificate(fio_tls13_certificate_s *out, const uint8_t *data, size_t data_len)
```

Parse Certificate message (extracts first certificate only).

Returns: 0 on success, -1 on error.

_Symbol type:_ `function`

#### `fio_tls13_parse_certificate_verify`

```c
int fio_tls13_parse_certificate_verify( fio_tls13_certificate_verify_s *out, const uint8_t *data, size_t data_len)
```

Parse CertificateVerify message.

Returns: 0 on success, -1 on error.

_Symbol type:_ `function`

#### `fio_tls13_build_finished`

```c
int fio_tls13_build_finished(uint8_t *out, size_t out_capacity, const uint8_t *verify_data, size_t verify_data_len)
```

Build Finished message.

verify_data = HMAC(finished_key, Transcript-Hash(Handshake Context))

Returns: message length on success, -1 on error.

_Symbol type:_ `function`

#### `fio_tls13_parse_finished`

```c
int fio_tls13_parse_finished(const uint8_t *data, size_t data_len, const uint8_t *expected_verify_data, size_t verify_data_len)
```

Parse and verify Finished message.

Returns: 0 on success (MAC matches), -1 on error.

_Symbol type:_ `function`

#### `fio_tls13_build_alert`

```c
inline int fio_tls13_build_alert(uint8_t *out, size_t out_capacity, uint8_t alert_level, uint8_t alert_desc)
```

Build an alert message (unencrypted, for use before handshake keys).

Alert format: [level:1][description:1]

**Parameters:**
- `out` - Output buffer for alert message (2 bytes minimum)
- `out_capacity` - Capacity of output buffer
- `alert_level` - Alert level (1=warning, 2=fatal)
- `alert_desc` - Alert description code

**Returns:**
- Alert message length (2), or -1 on error

_Symbol type:_ `function`

#### `fio_tls13_send_alert`

```c
int fio_tls13_send_alert(uint8_t *out, size_t out_capacity, uint8_t alert_level, uint8_t alert_desc, fio_tls13_record_keys_s *keys)
```

Build an encrypted alert record.

Per RFC 8446 Section 6, alerts are encrypted after handshake keys are
established. In TLS 1.3, all alerts except close_notify are effectively
fatal and the connection must be closed after sending.

**Parameters:**
- `out` - Output buffer for encrypted alert record
- `out_capacity` - Capacity of output buffer
- `alert_level` - Alert level (1=warning, 2=fatal)
- `alert_desc` - Alert description code
- `keys` - Encryption keys (sequence number will be incremented)

**Returns:**
- Encrypted record length, or -1 on error

_Symbol type:_ `function`

#### `fio_tls13_send_alert_plaintext`

```c
int fio_tls13_send_alert_plaintext(uint8_t *out, size_t out_capacity, uint8_t alert_level, uint8_t alert_desc)
```

Build an unencrypted alert record (for use before encryption is enabled).

**Parameters:**
- `out` - Output buffer for alert record
- `out_capacity` - Capacity of output buffer
- `alert_level` - Alert level (1=warning, 2=fatal)
- `alert_desc` - Alert description code

**Returns:**
- Record length (7 bytes: 5 header + 2 alert), or -1 on error

_Symbol type:_ `function`

#### `fio_tls13_alert_name`

```c
inline const char *fio_tls13_alert_name(uint8_t alert_desc)
```

Get human-readable name for an alert description.

**Parameters:**
- `alert_desc` - Alert description code

**Returns:**
- Static string with alert name

_Symbol type:_ `function`

-----------------------------------------------------
