Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_crypto_fd_quic_crypto_suites_h
2 : #define HEADER_fd_src_waltz_quic_crypto_fd_quic_crypto_suites_h
3 :
4 : #include "../fd_quic_enum.h"
5 : #include "../../../ballet/aes/fd_aes_gcm.h"
6 :
7 : /* Defines the crypto suites used by QUIC v1.
8 :
9 : QUIC v2 is defined here:
10 : https://www.rfc-editor.org/rfc/rfc9001.html#name-header-protection
11 : https://www.rfc-editor.org/rfc/rfc8446.html#page-133
12 :
13 : The suites are defined thusly:
14 :
15 : +------------------------------+-------------+
16 : | Description | Value |
17 : +------------------------------+-------------+
18 : | TLS_AES_128_GCM_SHA256 | {0x13,0x01} |
19 : | TLS_AES_256_GCM_SHA384 | {0x13,0x02} |
20 : | TLS_CHACHA20_POLY1305_SHA256 | {0x13,0x03} |
21 : | TLS_AES_128_CCM_SHA256 | {0x13,0x04} |
22 : | TLS_AES_128_CCM_8_SHA256 | {0x13,0x05} |
23 : +------------------------------+-------------+
24 :
25 : Notes:
26 : TLS_AES_128_CCM_SHA256 does not seem to be mentioned in rfc9001, so is excluded
27 : TLS_AES_128_CCM_8_SHA256 has no packet-header encryption defined, and so must be excluded
28 :
29 : The remainder are defined below */
30 :
31 : typedef struct fd_quic_crypto_keys fd_quic_crypto_keys_t;
32 : typedef struct fd_quic_crypto_secrets fd_quic_crypto_secrets_t;
33 :
34 172818117 : #define FD_QUIC_CRYPTO_TAG_SZ 16
35 30319279 : #define FD_QUIC_CRYPTO_SAMPLE_SZ 16
36 :
37 : struct fd_quic_crypto_keys {
38 : /* packet protection: */
39 : uchar pkt_key[FD_AES_128_KEY_SZ];
40 : uchar iv [FD_AES_GCM_IV_SZ ];
41 : uchar hp_key [FD_AES_128_KEY_SZ];
42 : };
43 :
44 : /* define enums for encryption levels */
45 108427510 : #define fd_quic_enc_level_initial_id 0
46 : #define fd_quic_enc_level_early_data_id 1
47 106442207 : #define fd_quic_enc_level_handshake_id 2
48 207440926 : #define fd_quic_enc_level_appdata_id 3
49 : #define FD_QUIC_NUM_ENC_LEVELS 4
50 :
51 : /* labels defined in rfc9001 */
52 24588 : #define FD_QUIC_CRYPTO_LABEL_CLIENT_IN "client in"
53 24588 : #define FD_QUIC_CRYPTO_LABEL_SERVER_IN "server in"
54 :
55 193920 : #define FD_QUIC_CRYPTO_LABEL_QUIC_KEY "quic key"
56 193920 : #define FD_QUIC_CRYPTO_LABEL_QUIC_IV "quic iv"
57 145416 : #define FD_QUIC_CRYPTO_LABEL_QUIC_HP "quic hp"
58 :
59 48504 : #define FD_QUIC_CRYPTO_LABEL_KEY_UPDATE "quic ku"
60 :
61 : /* each of these has "-1" to avoid counting the implied terminating NUL byte */
62 12294 : #define FD_QUIC_CRYPTO_LABEL_CLIENT_IN_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_CLIENT_IN ) - 1 )
63 12294 : #define FD_QUIC_CRYPTO_LABEL_SERVER_IN_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_SERVER_IN ) - 1 )
64 :
65 96960 : #define FD_QUIC_CRYPTO_LABEL_QUIC_KEY_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_QUIC_KEY ) - 1 )
66 96960 : #define FD_QUIC_CRYPTO_LABEL_QUIC_IV_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_QUIC_IV ) - 1 )
67 72708 : #define FD_QUIC_CRYPTO_LABEL_QUIC_HP_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_QUIC_HP ) - 1 )
68 :
69 24252 : #define FD_QUIC_CRYPTO_LABEL_KEY_UPDATE_LEN ( sizeof( FD_QUIC_CRYPTO_LABEL_KEY_UPDATE ) - 1 )
70 :
71 : struct fd_quic_crypto_secrets {
72 : uchar initial_secret[FD_QUIC_INITIAL_SECRET_SZ];
73 :
74 : /* secret[enc_level][dir][FD_QUIC_SECRET_SZ]
75 : a secret for each encryption level,
76 : and each direction (dir=0 is incoming, dir=1 is outgoing) */
77 : uchar secret[FD_QUIC_NUM_ENC_LEVELS][2][FD_QUIC_SECRET_SZ];
78 :
79 : /* new secret for switching keys during key update */
80 : uchar new_secret[2][FD_QUIC_SECRET_SZ];
81 : };
82 :
83 : /* fd_quic_gen_initial_secrets generates initial secrets for the given conn ID.
84 : Does not generate keys. Sets secrets->initial_secrets, secrets->secret[0][0],
85 : (incoming secret) and secret->secret[0][1] (outgoing secret). is_server is
86 : 1 if the current QUIC instance runs from the perspective of the server, 0
87 : otherwise.
88 :
89 : Key schedule:
90 :
91 : initial_salt (hardcoded constant)
92 : |
93 : v
94 : initial_secret = HKDF-Extract(.,conn_id)
95 : |
96 : +---> initial_client_secret = HKDF-Expand-Label(., "client in", "", 32)
97 : |
98 : +---> initial_server_secret = HKDF-Expand-Label(., "server in", "", 32) */
99 :
100 : void
101 : fd_quic_gen_initial_secrets(
102 : fd_quic_crypto_secrets_t * secrets,
103 : uchar const * conn_id,
104 : ulong conn_id_sz,
105 : int is_server );
106 :
107 : /* fd_quic_gen_keys derives the IV, a header protection key, and a packet
108 : protection key from a secret. Thus *keys is fully initialized. This
109 : function is called twice per encryption level (for incoming and for
110 : outgoing keys).
111 :
112 : Key schedule:
113 :
114 : secret
115 : |
116 : +---> header protection key = HKDF-Expand-Label(.,"quic-hp")
117 : +---> packet protection IV = HKDF-Expand-Label(.,"quic-iv")
118 : +---> packet protection key = HKDF-Expand-Label(.,"quic-key") */
119 :
120 : void
121 : fd_quic_gen_keys(
122 : fd_quic_crypto_keys_t * keys,
123 : uchar const secret[ 32 ] );
124 :
125 : /* fd_quic_key_update_derive derives the IVs and packet protection keys
126 : for the next key update. Header protection keys are not updated.
127 : Key updates are periodic key rotations that some QUIC peers do out of
128 : caution. Key updates are deterministic and can be computed infinitely
129 : far in advance if the client and server secrets are known.
130 :
131 : Key schedule:
132 :
133 : client/server secret n
134 : |
135 : v
136 : client/server secret n+1 = HKDF-Expand-Label(.,"quic-ku")
137 : |
138 : +---> server packet protection IV = HKDF-Expand-Label(.,"quic-iv")
139 : +---> server packet protection key = HKDF-Expand-Label(.,"quic-key") */
140 :
141 : void
142 : fd_quic_key_update_derive( fd_quic_crypto_secrets_t * secrets,
143 : fd_quic_crypto_keys_t new_keys[2] );
144 :
145 :
146 : /* encrypt a packet according to rfc9001 packet protection and header protection
147 :
148 : may fail in the following scenarios:
149 : the receiving buffer is too small
150 : the decryption functions report failure (fd_tls)
151 :
152 : returns
153 : FD_QUIC_SUCCESS if the operation succeeded
154 : FD_QUIC_FAILED otherwise
155 :
156 : args
157 : out destination for the full packet
158 : out_sz size of the output buffer, and also returned size of the written bytes
159 : hdr the input plain text header
160 : hdr_sz the size of the input header
161 : pkt the input plain text payload
162 : pkt_sz the size of the input payload
163 : keys the keys to use
164 : */
165 : int
166 : fd_quic_crypto_encrypt(
167 : uchar * const out,
168 : ulong * const out_sz,
169 : uchar const * const hdr,
170 : ulong const hdr_sz,
171 : uchar const * const pkt,
172 : ulong const pkt_sz,
173 : fd_quic_crypto_keys_t const * const pkt_keys,
174 : fd_quic_crypto_keys_t const * const hp_keys,
175 : ulong const pkt_number );
176 :
177 :
178 : /* decrypt a quic protected packet
179 :
180 : may fail in the following scenarios:
181 : the receiving buffer is too small
182 : the decryption functions report failure (fd_tls)
183 : the decrypted data is corrupt
184 :
185 : returns
186 : FD_QUIC_SUCCESS if the operation succeeded
187 : FD_QUIC_FAILED otherwise
188 :
189 : args
190 : buf buffer containing a QUIC packet with a decrypted
191 : header, and encrypted payload, and the auth tag
192 : of size FD_QUIC_CRYPTO_TAG_SZ. On return, the
193 : payload will be decrypted.
194 : buf_sz the size of the QUIC packet
195 : pkt_number_off the offset of the packet number within the cipher text
196 : this must be determined from unprotected header data
197 : keys the keys needed to decrypt */
198 :
199 : int
200 : fd_quic_crypto_decrypt(
201 : uchar * buf,
202 : ulong buf_sz,
203 : ulong pkt_number_off,
204 : ulong pkt_number,
205 : fd_quic_crypto_keys_t const * keys );
206 :
207 :
208 : /* decrypt a quic protected packet header
209 :
210 : this removes header protection (HP)
211 :
212 : may fail in the following scenarios:
213 : the receiving buffer is too small
214 : the decryption functions report failure (fd_tls)
215 : the decrypted data is corrupt
216 :
217 : returns
218 : FD_QUIC_SUCCESS if the operation succeeded
219 : FD_QUIC_FAILED otherwise
220 :
221 : args
222 : buf buffer containing an encrypted QUIC packet.
223 : On return, the header is decrypted, the rest
224 : still encrypted
225 : buf_sz size of the QUIC packet
226 : pkt_number_off the offset of the packet number within the cipher text
227 : this must be determined from unprotected header data
228 : keys the keys needed to decrypt */
229 :
230 : int
231 : fd_quic_crypto_decrypt_hdr(
232 : uchar * buf,
233 : ulong buf_sz,
234 : ulong pkt_number_off,
235 : fd_quic_crypto_keys_t const * keys );
236 :
237 : #endif /* HEADER_fd_src_waltz_quic_crypto_fd_quic_crypto_suites_h */
|