Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
crypto.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
8#include "keys.h"
10
11#include <cstdint>
12#include <functional>
13#include <map>
14#include <memory>
15#include <span>
16#include <string>
17#include <vector>
18
19// Forward declarations for OpenSSL types
20typedef struct ssl_ctx_st SSL_CTX;
21typedef struct ssl_st SSL;
22
24{
25
26// ============================================================================
27// Initial Secret Derivation
28// ============================================================================
29
36constexpr std::array<uint8_t, 20> initial_salt_v1 = {
37 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17,
38 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a
39};
40
44constexpr std::array<uint8_t, 20> initial_salt_v2 = {
45 0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93,
46 0x81, 0xbe, 0x6e, 0x26, 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9
47};
48
49// ============================================================================
50// HKDF Functions
51// ============================================================================
52
59class hkdf
60{
61public:
68 [[nodiscard]] static auto extract(std::span<const uint8_t> salt,
69 std::span<const uint8_t> ikm)
71
79 [[nodiscard]] static auto expand(std::span<const uint8_t> prk,
80 std::span<const uint8_t> info,
81 size_t length)
83
92 [[nodiscard]] static auto expand_label(std::span<const uint8_t> secret,
93 const std::string& label,
94 std::span<const uint8_t> context,
95 size_t length)
97};
98
99// ============================================================================
100// Initial Keys
101// ============================================================================
102
111{
112public:
119 [[nodiscard]] static auto derive(const connection_id& dest_cid,
120 uint32_t version = 0x00000001)
122
129 [[nodiscard]] static auto derive_keys(std::span<const uint8_t> initial_secret,
130 bool is_client_keys)
132};
133
134// ============================================================================
135// Packet Protection
136// ============================================================================
137
146{
147public:
156 [[nodiscard]] static auto protect(const quic_keys& keys,
157 std::span<const uint8_t> header,
158 std::span<const uint8_t> payload,
159 uint64_t packet_number)
161
170 [[nodiscard]] static auto unprotect(
171 const quic_keys& keys,
172 std::span<const uint8_t> packet,
173 size_t header_length,
174 uint64_t packet_number)
175 -> Result<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>>;
176
186 [[nodiscard]] static auto protect_header(const quic_keys& keys,
187 std::span<uint8_t> header,
188 size_t pn_offset,
189 size_t pn_length,
190 std::span<const uint8_t> sample)
191 -> VoidResult;
192
201 [[nodiscard]] static auto unprotect_header(const quic_keys& keys,
202 std::span<uint8_t> header,
203 size_t pn_offset,
204 std::span<const uint8_t> sample)
206
213 [[nodiscard]] static auto generate_hp_mask(std::span<const uint8_t> hp_key,
214 std::span<const uint8_t> sample)
216
217private:
224 [[nodiscard]] static auto make_nonce(std::span<const uint8_t> iv,
225 uint64_t packet_number)
226 -> std::array<uint8_t, aead_iv_size>;
227};
228
229// ============================================================================
230// QUIC Crypto Handler
231// ============================================================================
232
245{
246public:
250 quic_crypto();
251
256
257 // Non-copyable
258 quic_crypto(const quic_crypto&) = delete;
260
261 // Movable
262 quic_crypto(quic_crypto&& other) noexcept;
264
270 [[nodiscard]] auto init_client(const std::string& server_name) -> VoidResult;
271
278 [[nodiscard]] auto init_server(const std::string& cert_file,
279 const std::string& key_file) -> VoidResult;
280
286 [[nodiscard]] auto derive_initial_secrets(const connection_id& dest_cid)
287 -> VoidResult;
288
295 [[nodiscard]] auto process_crypto_data(encryption_level level,
296 std::span<const uint8_t> data)
298
303 [[nodiscard]] auto start_handshake() -> Result<std::vector<uint8_t>>;
304
309 [[nodiscard]] auto is_handshake_complete() const noexcept -> bool;
310
315 [[nodiscard]] auto current_level() const noexcept -> encryption_level;
316
322 [[nodiscard]] auto get_write_keys(encryption_level level) const
323 -> Result<quic_keys>;
324
330 [[nodiscard]] auto get_read_keys(encryption_level level) const
331 -> Result<quic_keys>;
332
339 void set_keys(encryption_level level,
340 const quic_keys& read_keys,
341 const quic_keys& write_keys);
342
347 [[nodiscard]] auto update_keys() -> VoidResult;
348
353 [[nodiscard]] auto get_alpn() const -> std::string;
354
360 [[nodiscard]] auto set_alpn(const std::vector<std::string>& protocols)
361 -> VoidResult;
362
367 [[nodiscard]] auto is_server() const noexcept -> bool;
368
373 [[nodiscard]] auto key_phase() const noexcept -> uint8_t;
374
375 // =========================================================================
376 // 0-RTT Session Resumption (RFC 9001 Section 4.6)
377 // =========================================================================
378
390 using session_ticket_callback_t = std::function<void(
391 std::vector<uint8_t> ticket_data,
392 uint32_t lifetime_hint,
393 uint32_t ticket_age_add,
394 uint32_t max_early_data)>;
395
404
412 [[nodiscard]] auto set_session_ticket(std::span<const uint8_t> ticket_data)
413 -> VoidResult;
414
422 [[nodiscard]] auto enable_early_data(uint32_t max_early_data) -> VoidResult;
423
430 [[nodiscard]] auto is_early_data_accepted() const noexcept -> bool;
431
438 [[nodiscard]] auto derive_zero_rtt_keys() -> VoidResult;
439
444 [[nodiscard]] auto has_zero_rtt_keys() const noexcept -> bool;
445
446private:
447 struct impl;
448 std::unique_ptr<impl> impl_;
449};
450
451} // namespace kcenon::network::protocols::quic
QUIC Connection ID (RFC 9000 Section 5.1)
HKDF (HMAC-based Key Derivation Function) utilities (RFC 5869)
Definition crypto.h:60
static auto expand_label(std::span< const uint8_t > secret, const std::string &label, std::span< const uint8_t > context, size_t length) -> Result< std::vector< uint8_t > >
HKDF-Expand-Label function (TLS 1.3 style)
Definition crypto.cpp:193
static auto extract(std::span< const uint8_t > salt, std::span< const uint8_t > ikm) -> Result< std::array< uint8_t, secret_size > >
HKDF-Extract function.
Definition crypto.cpp:56
static auto expand(std::span< const uint8_t > prk, std::span< const uint8_t > info, size_t length) -> Result< std::vector< uint8_t > >
HKDF-Expand function.
Definition crypto.cpp:124
Derives initial encryption keys from Destination Connection ID.
Definition crypto.h:111
static auto derive_keys(std::span< const uint8_t > initial_secret, bool is_client_keys) -> Result< quic_keys >
Derive keys from an initial secret.
Definition crypto.cpp:339
static auto derive(const connection_id &dest_cid, uint32_t version=0x00000001) -> Result< key_pair >
Derive client and server initial keys.
Definition crypto.cpp:237
QUIC packet number utilities (RFC 9000 Section 17.1)
Definition packet.h:174
QUIC packet protection (encryption/decryption) (RFC 9001 Section 5)
Definition crypto.h:146
static auto unprotect_header(const quic_keys &keys, std::span< uint8_t > header, size_t pn_offset, std::span< const uint8_t > sample) -> Result< std::pair< uint8_t, size_t > >
Remove header protection.
Definition crypto.cpp:687
static auto unprotect(const quic_keys &keys, std::span< const uint8_t > packet, size_t header_length, uint64_t packet_number) -> Result< std::pair< std::vector< uint8_t >, std::vector< uint8_t > > >
Unprotect (decrypt) a QUIC packet.
Definition crypto.cpp:508
static auto make_nonce(std::span< const uint8_t > iv, uint64_t packet_number) -> std::array< uint8_t, aead_iv_size >
Construct nonce from IV and packet number.
Definition crypto.cpp:408
static auto protect_header(const quic_keys &keys, std::span< uint8_t > header, size_t pn_offset, size_t pn_length, std::span< const uint8_t > sample) -> VoidResult
Apply header protection.
Definition crypto.cpp:649
static auto protect(const quic_keys &keys, std::span< const uint8_t > header, std::span< const uint8_t > payload, uint64_t packet_number) -> Result< std::vector< uint8_t > >
Protect (encrypt) a QUIC packet.
Definition crypto.cpp:425
static auto generate_hp_mask(std::span< const uint8_t > hp_key, std::span< const uint8_t > sample) -> Result< std::array< uint8_t, 5 > >
Generate header protection mask using AES-ECB.
Definition crypto.cpp:598
QUIC-TLS integration handler (RFC 9001)
Definition crypto.h:245
auto init_server(const std::string &cert_file, const std::string &key_file) -> VoidResult
Initialize as server.
Definition crypto.cpp:827
auto update_keys() -> VoidResult
Perform a key update (1-RTT only)
Definition crypto.cpp:1052
~quic_crypto()
Destructor (cleans up OpenSSL resources)
auto start_handshake() -> Result< std::vector< uint8_t > >
Start the handshake (generate initial CRYPTO data)
Definition crypto.cpp:965
auto get_read_keys(encryption_level level) const -> Result< quic_keys >
Get read keys for an encryption level.
Definition crypto.cpp:1026
auto get_alpn() const -> std::string
Get the negotiated ALPN protocol.
Definition crypto.cpp:1097
auto is_early_data_accepted() const noexcept -> bool
Check if 0-RTT early data was accepted by the server.
Definition crypto.cpp:1177
auto get_write_keys(encryption_level level) const -> Result< quic_keys >
Get write keys for an encryption level.
Definition crypto.cpp:1013
auto process_crypto_data(encryption_level level, std::span< const uint8_t > data) -> Result< std::vector< uint8_t > >
Process incoming CRYPTO frame data.
Definition crypto.cpp:912
auto is_server() const noexcept -> bool
Check if this is a server instance.
Definition crypto.cpp:1132
void set_keys(encryption_level level, const quic_keys &read_keys, const quic_keys &write_keys)
Set keys for an encryption level (used during handshake)
Definition crypto.cpp:1039
auto set_alpn(const std::vector< std::string > &protocols) -> VoidResult
Set ALPN protocols to offer/accept.
Definition crypto.cpp:1102
std::function< void( std::vector< uint8_t > ticket_data, uint32_t lifetime_hint, uint32_t ticket_age_add, uint32_t max_early_data)> session_ticket_callback_t
Callback type for receiving session tickets.
Definition crypto.h:390
quic_crypto(const quic_crypto &)=delete
auto set_session_ticket(std::span< const uint8_t > ticket_data) -> VoidResult
Set a session ticket for 0-RTT resumption.
Definition crypto.cpp:1151
quic_crypto & operator=(quic_crypto &&other) noexcept
quic_crypto & operator=(const quic_crypto &)=delete
auto init_client(const std::string &server_name) -> VoidResult
Initialize as client.
Definition crypto.cpp:782
auto current_level() const noexcept -> encryption_level
Get current encryption level.
Definition crypto.cpp:1008
auto derive_zero_rtt_keys() -> VoidResult
Derive 0-RTT keys from session ticket.
Definition crypto.cpp:1182
auto has_zero_rtt_keys() const noexcept -> bool
Check if 0-RTT keys are available.
Definition crypto.cpp:1265
auto key_phase() const noexcept -> uint8_t
Get current key phase (for key updates)
Definition crypto.cpp:1137
auto derive_initial_secrets(const connection_id &dest_cid) -> VoidResult
Derive initial secrets from destination connection ID.
Definition crypto.cpp:883
void set_session_ticket_callback(session_ticket_callback_t cb)
Set callback for receiving session tickets.
Definition crypto.cpp:1146
quic_crypto(quic_crypto &&other) noexcept
auto enable_early_data(uint32_t max_early_data) -> VoidResult
Enable 0-RTT early data.
Definition crypto.cpp:1163
auto is_handshake_complete() const noexcept -> bool
Check if the handshake is complete.
Definition crypto.cpp:1003
QUIC connection identifier type.
struct ssl_ctx_st SSL_CTX
Definition crypto.h:20
struct ssl_st SSL
Definition crypto.h:21
constexpr std::array< uint8_t, 20 > initial_salt_v1
QUIC version 1 initial salt (RFC 9001 Section 5.2)
Definition crypto.h:36
constexpr std::array< uint8_t, 20 > initial_salt_v2
QUIC version 2 initial salt (RFC 9369)
Definition crypto.h:44
encryption_level
QUIC encryption levels (RFC 9001 Section 4)
Definition keys.h:54
constexpr const char * version() noexcept
Get the network system version string.
Definition network.cppm:111
Result< std::monostate > VoidResult
Network-specific error and result type definitions.
QUIC encryption keys for a single encryption level (RFC 9001 Section 5)
Definition keys.h:92