Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 7648:b28ea685a56e quic
Moved all QUIC code into ngx_event_quic.c
Introduced ngx_quic_input() and ngx_quic_output() as interface between
nginx and protocol. They are the only functions that are exported.
While there, added copyrights.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Fri, 28 Feb 2020 16:23:25 +0300 |
parents | 01dc595de244 |
children | 6091506af0f7 |
comparison
equal
deleted
inserted
replaced
7647:3cb4f16426a5 | 7648:b28ea685a56e |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Nginx, Inc. | |
4 */ | |
5 | |
6 | |
1 #include <ngx_config.h> | 7 #include <ngx_config.h> |
2 #include <ngx_core.h> | 8 #include <ngx_core.h> |
3 #include <ngx_event.h> | 9 |
10 | |
11 #define quic_version 0xff000018 | |
12 | |
13 | |
14 #if (NGX_HAVE_NONALIGNED) | |
15 | |
16 #define ngx_quic_parse_uint16(p) ntohs(*(uint16_t *) (p)) | |
17 #define ngx_quic_parse_uint32(p) ntohl(*(uint32_t *) (p)) | |
18 | |
19 #define ngx_quic_write_uint16 ngx_quic_write_uint16_aligned | |
20 #define ngx_quic_write_uint32 ngx_quic_write_uint32_aligned | |
21 | |
22 #else | |
23 | |
24 #define ngx_quic_parse_uint16(p) ((p)[0] << 8 | (p)[1]) | |
25 #define ngx_quic_parse_uint32(p) \ | |
26 ((uint32_t) (p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3]) | |
27 | |
28 #define ngx_quic_write_uint16(p, s) \ | |
29 ((p)[0] = (u_char) ((s) >> 8), \ | |
30 (p)[1] = (u_char) (s), \ | |
31 (p) + sizeof(uint16_t)) | |
32 | |
33 #define ngx_quic_write_uint32(p, s) \ | |
34 ((p)[0] = (u_char) ((s) >> 24), \ | |
35 (p)[1] = (u_char) ((s) >> 16), \ | |
36 (p)[2] = (u_char) ((s) >> 8), \ | |
37 (p)[3] = (u_char) (s), \ | |
38 (p) + sizeof(uint32_t)) | |
39 | |
40 #endif | |
41 | |
42 | |
43 #define ngx_quic_write_uint16_aligned(p, s) \ | |
44 (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t)) | |
45 | |
46 #define ngx_quic_write_uint32_aligned(p, s) \ | |
47 (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t)) | |
48 | |
49 | |
50 /* TODO: real states, these are stubs */ | |
51 typedef enum { | |
52 NGX_QUIC_ST_INITIAL, | |
53 NGX_QUIC_ST_HANDSHAKE, | |
54 NGX_QUIC_ST_APP_DATA | |
55 } ngx_quic_state_t; | |
56 | |
57 | |
58 typedef struct { | |
59 ngx_str_t secret; | |
60 ngx_str_t key; | |
61 ngx_str_t iv; | |
62 ngx_str_t hp; | |
63 } ngx_quic_secret_t; | |
64 | |
65 | |
66 struct ngx_quic_connection_s { | |
67 | |
68 ngx_quic_state_t state; | |
69 ngx_ssl_t *ssl; | |
70 | |
71 ngx_str_t out; // stub for some kind of output queue | |
72 | |
73 ngx_str_t scid; | |
74 ngx_str_t dcid; | |
75 ngx_str_t token; | |
76 | |
77 ngx_quic_secret_t client_in; | |
78 ngx_quic_secret_t client_hs; | |
79 ngx_quic_secret_t client_ad; | |
80 ngx_quic_secret_t server_in; | |
81 ngx_quic_secret_t server_hs; | |
82 ngx_quic_secret_t server_ad; | |
83 }; | |
84 | |
85 | |
86 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, | |
87 ngx_buf_t *b); | |
88 static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c, ngx_buf_t *b); | |
89 | |
90 static int ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, | |
91 enum ssl_encryption_level_t level, const uint8_t *read_secret, | |
92 const uint8_t *write_secret, size_t secret_len); | |
93 static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, | |
94 enum ssl_encryption_level_t level, const uint8_t *data, size_t len); | |
95 static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn); | |
96 static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, | |
97 enum ssl_encryption_level_t level, uint8_t alert); | |
98 | |
99 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask); | |
100 static uint64_t ngx_quic_parse_int(u_char **pos); | |
101 static void ngx_quic_build_int(u_char **pos, uint64_t value); | |
102 | |
103 static ngx_int_t ngx_hkdf_extract(u_char *out_key, size_t *out_len, | |
104 const EVP_MD *digest, const u_char *secret, size_t secret_len, | |
105 const u_char *salt, size_t salt_len); | |
106 static ngx_int_t ngx_hkdf_expand(u_char *out_key, size_t out_len, | |
107 const EVP_MD *digest, const u_char *prk, size_t prk_len, | |
108 const u_char *info, size_t info_len); | |
109 | |
110 static ngx_int_t ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest, | |
111 ngx_str_t *out, ngx_str_t *label, const uint8_t *prk, size_t prk_len); | |
112 | |
113 static ngx_int_t ngx_quic_tls_open(ngx_connection_t *c, | |
114 const EVP_CIPHER *cipher, ngx_quic_secret_t *s, ngx_str_t *out, | |
115 u_char *nonce, ngx_str_t *in, ngx_str_t *ad); | |
116 static ngx_int_t ngx_quic_tls_seal(ngx_connection_t *c, | |
117 const EVP_CIPHER *cipher, ngx_quic_secret_t *s, ngx_str_t *out, | |
118 u_char *nonce, ngx_str_t *in, ngx_str_t *ad); | |
119 | |
120 static ngx_int_t ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, | |
121 ngx_quic_secret_t *s, u_char *out, u_char *in); | |
122 | |
123 | |
124 static SSL_QUIC_METHOD quic_method = { | |
125 ngx_quic_set_encryption_secrets, | |
126 ngx_quic_add_handshake_data, | |
127 ngx_quic_flush_flight, | |
128 ngx_quic_send_alert, | |
129 }; | |
130 | |
131 | |
132 void | |
133 ngx_quic_init_ssl_methods(SSL_CTX* ctx) | |
134 { | |
135 SSL_CTX_set_quic_method(ctx, &quic_method); | |
136 } | |
137 | |
138 | |
139 ngx_int_t | |
140 ngx_quic_input(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_buf_t *b) | |
141 { | |
142 if (c->quic == NULL) { | |
143 return ngx_quic_new_connection(c, ssl, b); //TODO: change state by results | |
144 } | |
145 | |
146 switch (c->quic->state) { | |
147 case NGX_QUIC_ST_INITIAL: | |
148 case NGX_QUIC_ST_HANDSHAKE: | |
149 return ngx_quic_handshake_input(c, b); | |
150 default: | |
151 /* application data */ | |
152 break; | |
153 } | |
154 | |
155 return NGX_OK; | |
156 } | |
157 | |
158 | |
159 ngx_int_t | |
160 ngx_quic_output(ngx_connection_t *c) | |
161 { | |
162 /* stub for processing output queue */ | |
163 | |
164 if (c->quic->out.data) { | |
165 c->send(c, c->quic->out.data, c->quic->out.len); | |
166 c->quic->out.data = NULL; | |
167 } | |
168 | |
169 return NGX_OK; | |
170 } | |
171 | |
172 | |
173 static int | |
174 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, | |
175 enum ssl_encryption_level_t level, const uint8_t *read_secret, | |
176 const uint8_t *write_secret, size_t secret_len) | |
177 { | |
178 u_char *name; | |
179 ngx_uint_t i; | |
180 const EVP_MD *digest; | |
181 const EVP_CIPHER *cipher; | |
182 ngx_connection_t *c; | |
183 ngx_quic_secret_t *client, *server; | |
184 | |
185 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
186 | |
187 //ngx_ssl_handshake_log(c); // TODO: enable again | |
188 | |
189 #if (NGX_DEBUG) | |
190 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
191 u_char buf[64]; | |
192 size_t m; | |
193 | |
194 m = ngx_hex_dump(buf, (u_char *) read_secret, secret_len) - buf; | |
195 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
196 "set_encryption_secrets: read %*s, len: %uz, level:%d", | |
197 m, buf, secret_len, (int) level); | |
198 | |
199 m = ngx_hex_dump(buf, (u_char *) write_secret, secret_len) - buf; | |
200 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
201 "set_encryption_secrets: write %*s, len: %uz, level:%d", | |
202 m, buf, secret_len, (int) level); | |
203 } | |
204 #endif | |
205 | |
206 name = (u_char *) SSL_get_cipher(ssl_conn); | |
207 | |
208 if (ngx_strcasecmp(name, (u_char *) "TLS_AES_128_GCM_SHA256") == 0 | |
209 || ngx_strcasecmp(name, (u_char *) "(NONE)") == 0) | |
210 { | |
211 cipher = EVP_aes_128_gcm(); | |
212 digest = EVP_sha256(); | |
213 | |
214 } else if (ngx_strcasecmp(name, (u_char *) "TLS_AES_256_GCM_SHA384") == 0) { | |
215 cipher = EVP_aes_256_gcm(); | |
216 digest = EVP_sha384(); | |
217 | |
218 } else { | |
219 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); | |
220 return 0; | |
221 } | |
222 | |
223 switch (level) { | |
224 | |
225 case ssl_encryption_handshake: | |
226 client = &c->quic->client_hs; | |
227 server = &c->quic->server_hs; | |
228 | |
229 break; | |
230 | |
231 case ssl_encryption_application: | |
232 client = &c->quic->client_ad; | |
233 server = &c->quic->server_ad; | |
234 | |
235 break; | |
236 | |
237 default: | |
238 return 0; | |
239 } | |
240 | |
241 client->key.len = EVP_CIPHER_key_length(cipher); | |
242 server->key.len = EVP_CIPHER_key_length(cipher); | |
243 | |
244 client->iv.len = EVP_CIPHER_iv_length(cipher); | |
245 server->iv.len = EVP_CIPHER_iv_length(cipher); | |
246 | |
247 client->hp.len = EVP_CIPHER_key_length(cipher); | |
248 server->hp.len = EVP_CIPHER_key_length(cipher); | |
249 | |
250 struct { | |
251 ngx_str_t label; | |
252 ngx_str_t *key; | |
253 const uint8_t *secret; | |
254 } seq[] = { | |
255 { ngx_string("tls13 quic key"), &client->key, read_secret }, | |
256 { ngx_string("tls13 quic iv"), &client->iv, read_secret }, | |
257 { ngx_string("tls13 quic hp"), &client->hp, read_secret }, | |
258 { ngx_string("tls13 quic key"), &server->key, write_secret }, | |
259 { ngx_string("tls13 quic iv"), &server->iv, write_secret }, | |
260 { ngx_string("tls13 quic hp"), &server->hp, write_secret }, | |
261 }; | |
262 | |
263 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { | |
264 | |
265 if (ngx_quic_hkdf_expand(c, digest, seq[i].key, &seq[i].label, | |
266 seq[i].secret, secret_len) | |
267 != NGX_OK) | |
268 { | |
269 return 0; | |
270 } | |
271 } | |
272 | |
273 return 1; | |
274 } | |
275 | |
276 | |
277 static int | |
278 ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, | |
279 enum ssl_encryption_level_t level, const uint8_t *data, size_t len) | |
280 { | |
281 u_char *p, *pnp, *name, *nonce, *sample; | |
282 ngx_int_t m; | |
283 ngx_str_t in, out, ad; | |
284 static int pn; | |
285 const EVP_CIPHER *cipher; | |
286 ngx_connection_t *c; | |
287 ngx_quic_secret_t *secret; | |
288 ngx_quic_connection_t *qc; | |
289 u_char buf[2048], mask[16]; | |
290 | |
291 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
292 qc = c->quic; | |
293 | |
294 //ngx_ssl_handshake_log(c); // TODO: enable again | |
295 | |
296 switch (level) { | |
297 | |
298 case ssl_encryption_initial: | |
299 secret = &qc->server_in; | |
300 break; | |
301 | |
302 case ssl_encryption_handshake: | |
303 secret = &qc->server_hs; | |
304 break; | |
305 | |
306 default: | |
307 return 0; | |
308 } | |
309 | |
310 m = ngx_hex_dump(buf, (u_char *) data, ngx_min(len, 1024)) - buf; | |
311 ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
312 "ngx_quic_add_handshake_data: %*s%s, len: %uz, level:%d", | |
313 m, buf, len < 2048 ? "" : "...", len, (int) level); | |
314 | |
315 in.data = ngx_alloc(4 + len + 5 /*minimal ACK*/, c->log); | |
316 if (in.data == 0) { | |
317 return 0; | |
318 } | |
319 | |
320 p = in.data; | |
321 ngx_quic_build_int(&p, 6); // crypto frame | |
322 ngx_quic_build_int(&p, 0); | |
323 ngx_quic_build_int(&p, len); | |
324 p = ngx_cpymem(p, data, len); | |
325 | |
326 if (level == ssl_encryption_initial) { | |
327 ngx_quic_build_int(&p, 2); // ack frame | |
328 ngx_quic_build_int(&p, 0); | |
329 ngx_quic_build_int(&p, 0); | |
330 ngx_quic_build_int(&p, 0); | |
331 ngx_quic_build_int(&p, 0); | |
332 } | |
333 | |
334 in.len = p - in.data; | |
335 out.len = in.len + EVP_GCM_TLS_TAG_LEN; | |
336 | |
337 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
338 "ngx_quic_add_handshake_data: clear_len:%uz, ciphertext_len:%uz", | |
339 in.len, out.len); | |
340 | |
341 ad.data = ngx_alloc(346 /*max header*/, c->log); | |
342 if (ad.data == 0) { | |
343 return 0; | |
344 } | |
345 | |
346 p = ad.data; | |
347 if (level == ssl_encryption_initial) { | |
348 *p++ = 0xc0; // initial, packet number len | |
349 } else if (level == ssl_encryption_handshake) { | |
350 *p++ = 0xe0; // handshake, packet number len | |
351 } | |
352 p = ngx_quic_write_uint32(p, quic_version); | |
353 *p++ = qc->scid.len; | |
354 p = ngx_cpymem(p, qc->scid.data, qc->scid.len); | |
355 *p++ = qc->dcid.len; | |
356 p = ngx_cpymem(p, qc->dcid.data, qc->dcid.len); | |
357 if (level == ssl_encryption_initial) { | |
358 ngx_quic_build_int(&p, 0); // token length | |
359 } | |
360 ngx_quic_build_int(&p, out.len + 1); // length (inc. pnl) | |
361 pnp = p; | |
362 | |
363 if (level == ssl_encryption_initial) { | |
364 *p++ = 0; // packet number 0 | |
365 | |
366 } else if (level == ssl_encryption_handshake) { | |
367 *p++ = pn++; | |
368 } | |
369 | |
370 ad.len = p - ad.data; | |
371 | |
372 m = ngx_hex_dump(buf, ad.data, ad.len) - buf; | |
373 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
374 "ngx_quic_add_handshake_data ad: %*s, len: %uz", | |
375 m, buf, ad.len); | |
376 | |
377 | |
378 name = (u_char *) SSL_get_cipher(ssl_conn); | |
379 | |
380 if (ngx_strcasecmp(name, (u_char *) "TLS_AES_128_GCM_SHA256") == 0 | |
381 || ngx_strcasecmp(name, (u_char *) "(NONE)") == 0) | |
382 { | |
383 cipher = EVP_aes_128_gcm(); | |
384 | |
385 } else if (ngx_strcasecmp(name, (u_char *) "TLS_AES_256_GCM_SHA384") == 0) { | |
386 cipher = EVP_aes_256_gcm(); | |
387 | |
388 } else { | |
389 return 0; | |
390 } | |
391 | |
392 nonce = ngx_pstrdup(c->pool, &secret->iv); | |
393 if (level == ssl_encryption_handshake) { | |
394 nonce[11] ^= (pn - 1); | |
395 } | |
396 | |
397 m = ngx_hex_dump(buf, (u_char *) secret->iv.data, 12) - buf; | |
398 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
399 "ngx_quic_add_handshake_data sample: server_iv %*s", | |
400 m, buf); | |
401 m = ngx_hex_dump(buf, (u_char *) nonce, 12) - buf; | |
402 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
403 "ngx_quic_add_handshake_data sample: n=%d nonce %*s", | |
404 pn - 1, m, buf); | |
405 | |
406 if (ngx_quic_tls_seal(c, cipher, secret, &out, nonce, &in, &ad) != NGX_OK) | |
407 { | |
408 return 0; | |
409 } | |
410 | |
411 sample = &out.data[3]; // pnl=0 | |
412 if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), secret, mask, sample) != NGX_OK) { | |
413 return 0; | |
414 } | |
415 | |
416 m = ngx_hex_dump(buf, (u_char *) sample, 16) - buf; | |
417 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
418 "ngx_quic_add_handshake_data sample: %*s, len: %uz", | |
419 m, buf, 16); | |
420 | |
421 m = ngx_hex_dump(buf, (u_char *) mask, 16) - buf; | |
422 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
423 "ngx_quic_add_handshake_data mask: %*s, len: %uz", | |
424 m, buf, 16); | |
425 | |
426 m = ngx_hex_dump(buf, (u_char *) secret->hp.data, 16) - buf; | |
427 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
428 "ngx_quic_add_handshake_data hp_key: %*s, len: %uz", | |
429 m, buf, 16); | |
430 | |
431 // header protection, pnl = 0 | |
432 ad.data[0] ^= mask[0] & 0x0f; | |
433 *pnp ^= mask[1]; | |
434 | |
435 u_char *packet = ngx_alloc(ad.len + out.len, c->log); | |
436 if (packet == 0) { | |
437 return 0; | |
438 } | |
439 | |
440 p = ngx_cpymem(packet, ad.data, ad.len); | |
441 p = ngx_cpymem(p, out.data, out.len); | |
442 | |
443 m = ngx_hex_dump(buf, (u_char *) packet, ngx_min(1024, p - packet)) - buf; | |
444 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
445 "ngx_quic_add_handshake_data packet: %*s%s, len: %uz", | |
446 m, buf, len < 2048 ? "" : "...", p - packet); | |
447 | |
448 // TODO: save state of data to send into qc (push into queue) | |
449 | |
450 qc->out.data = packet; | |
451 qc->out.len = p - packet; | |
452 | |
453 if (ngx_quic_output(c) != NGX_OK) { | |
454 return 0; | |
455 } | |
456 | |
457 return 1; | |
458 } | |
459 | |
460 | |
461 static int | |
462 ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn) | |
463 { | |
464 ngx_connection_t *c; | |
465 | |
466 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
467 | |
468 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_quic_flush_flight()"); | |
469 | |
470 return 1; | |
471 } | |
472 | |
473 | |
474 static int | |
475 ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, enum ssl_encryption_level_t level, | |
476 uint8_t alert) | |
477 { | |
478 ngx_connection_t *c; | |
479 | |
480 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
481 | |
482 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
483 "ngx_quic_send_alert(), lvl=%d, alert=%d", | |
484 (int) level, (int) alert); | |
485 | |
486 return 1; | |
487 } | |
488 | |
489 | |
490 static ngx_int_t | |
491 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_buf_t *b) | |
492 { | |
493 int n, sslerr; | |
494 #if (NGX_DEBUG) | |
495 u_char buf[512]; | |
496 size_t m; | |
497 #endif | |
498 | |
499 ngx_quic_connection_t *qc; | |
500 | |
501 if ((b->pos[0] & 0xf0) != 0xc0) { | |
502 ngx_log_error(NGX_LOG_INFO, c->log, 0, "invalid initial packet"); | |
503 return NGX_ERROR; | |
504 } | |
505 | |
506 if (ngx_buf_size(b) < 1200) { | |
507 ngx_log_error(NGX_LOG_INFO, c->log, 0, "too small UDP datagram"); | |
508 return NGX_ERROR; | |
509 } | |
510 | |
511 ngx_int_t flags = *b->pos++; | |
512 uint32_t version = ngx_quic_parse_uint32(b->pos); | |
513 b->pos += sizeof(uint32_t); | |
514 | |
515 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
516 "quic flags:%xi version:%xD", flags, version); | |
517 | |
518 if (version != quic_version) { | |
519 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unsupported quic version"); | |
520 return NGX_ERROR; | |
521 } | |
522 | |
523 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t)); | |
524 if (qc == NULL) { | |
525 return NGX_ERROR; | |
526 } | |
527 | |
528 c->quic = qc; | |
529 | |
530 qc->dcid.len = *b->pos++; | |
531 qc->dcid.data = ngx_pnalloc(c->pool, qc->dcid.len); | |
532 if (qc->dcid.data == NULL) { | |
533 return NGX_ERROR; | |
534 } | |
535 | |
536 ngx_memcpy(qc->dcid.data, b->pos, qc->dcid.len); | |
537 b->pos += qc->dcid.len; | |
538 | |
539 qc->scid.len = *b->pos++; | |
540 qc->scid.data = ngx_pnalloc(c->pool, qc->scid.len); | |
541 if (qc->scid.data == NULL) { | |
542 return NGX_ERROR; | |
543 } | |
544 | |
545 ngx_memcpy(qc->scid.data, b->pos, qc->scid.len); | |
546 b->pos += qc->scid.len; | |
547 | |
548 qc->token.len = ngx_quic_parse_int(&b->pos); | |
549 qc->token.data = ngx_pnalloc(c->pool, qc->token.len); | |
550 if (qc->token.data == NULL) { | |
551 return NGX_ERROR; | |
552 } | |
553 | |
554 ngx_memcpy(qc->token.data, b->pos, qc->token.len); | |
555 b->pos += qc->token.len; | |
556 | |
557 ngx_int_t plen = ngx_quic_parse_int(&b->pos); | |
558 | |
559 if (plen > b->last - b->pos) { | |
560 ngx_log_error(NGX_LOG_INFO, c->log, 0, "truncated initial packet"); | |
561 return NGX_ERROR; | |
562 } | |
563 | |
564 /* draft-ietf-quic-tls-23#section-5.4.2: | |
565 * the Packet Number field is assumed to be 4 bytes long | |
566 * draft-ietf-quic-tls-23#section-5.4.[34]: | |
567 * AES-Based and ChaCha20-Based header protections sample 16 bytes | |
568 */ | |
569 u_char *sample = b->pos + 4; | |
570 | |
571 #if (NGX_DEBUG) | |
572 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
573 m = ngx_hex_dump(buf, qc->dcid.data, qc->dcid.len) - buf; | |
574 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
575 "quic DCID: %*s, len: %uz", m, buf, qc->dcid.len); | |
576 | |
577 m = ngx_hex_dump(buf, qc->scid.data, qc->scid.len) - buf; | |
578 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
579 "quic SCID: %*s, len: %uz", m, buf, qc->scid.len); | |
580 | |
581 m = ngx_hex_dump(buf, qc->token.data, qc->token.len) - buf; | |
582 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
583 "quic token: %*s, len: %uz", m, buf, qc->token.len); | |
584 | |
585 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
586 "quic packet length: %d", plen); | |
587 | |
588 m = ngx_hex_dump(buf, sample, 16) - buf; | |
589 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
590 "quic sample: %*s", m, buf); | |
591 } | |
592 #endif | |
593 | |
594 // initial secret | |
595 | |
596 size_t is_len; | |
597 uint8_t is[SHA256_DIGEST_LENGTH]; | |
598 ngx_uint_t i; | |
599 const EVP_MD *digest; | |
600 const EVP_CIPHER *cipher; | |
601 static const uint8_t salt[20] = | |
602 "\xc3\xee\xf7\x12\xc7\x2e\xbb\x5a\x11\xa7" | |
603 "\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02"; | |
604 | |
605 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */ | |
606 | |
607 cipher = EVP_aes_128_gcm(); | |
608 digest = EVP_sha256(); | |
609 | |
610 if (ngx_hkdf_extract(is, &is_len, digest, qc->dcid.data, qc->dcid.len, | |
611 salt, sizeof(salt)) | |
612 != NGX_OK) | |
613 { | |
614 return NGX_ERROR; | |
615 } | |
616 | |
617 ngx_str_t iss = { | |
618 .data = is, | |
619 .len = is_len | |
620 }; | |
621 | |
622 #if (NGX_DEBUG) | |
623 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
624 m = ngx_hex_dump(buf, (uint8_t *) salt, sizeof(salt)) - buf; | |
625 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
626 "quic salt: %*s, len: %uz", m, buf, sizeof(salt)); | |
627 | |
628 m = ngx_hex_dump(buf, is, is_len) - buf; | |
629 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
630 "quic initial secret: %*s, len: %uz", m, buf, is_len); | |
631 } | |
632 #endif | |
633 | |
634 /* draft-ietf-quic-tls-23#section-5.2 */ | |
635 qc->client_in.secret.len = SHA256_DIGEST_LENGTH; | |
636 qc->server_in.secret.len = SHA256_DIGEST_LENGTH; | |
637 | |
638 qc->client_in.key.len = EVP_CIPHER_key_length(cipher); | |
639 qc->server_in.key.len = EVP_CIPHER_key_length(cipher); | |
640 | |
641 qc->client_in.hp.len = EVP_CIPHER_key_length(cipher); | |
642 qc->server_in.hp.len = EVP_CIPHER_key_length(cipher); | |
643 | |
644 qc->client_in.iv.len = EVP_CIPHER_iv_length(cipher); | |
645 qc->server_in.iv.len = EVP_CIPHER_iv_length(cipher); | |
646 | |
647 struct { | |
648 ngx_str_t label; | |
649 ngx_str_t *key; | |
650 ngx_str_t *prk; | |
651 } seq[] = { | |
652 | |
653 /* draft-ietf-quic-tls-23#section-5.2 */ | |
654 { ngx_string("tls13 client in"), &qc->client_in.secret, &iss }, | |
655 { | |
656 ngx_string("tls13 quic key"), | |
657 &qc->client_in.key, | |
658 &qc->client_in.secret, | |
659 }, | |
660 { | |
661 ngx_string("tls13 quic iv"), | |
662 &qc->client_in.iv, | |
663 &qc->client_in.secret, | |
664 }, | |
665 { | |
666 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */ | |
667 ngx_string("tls13 quic hp"), | |
668 &qc->client_in.hp, | |
669 &qc->client_in.secret, | |
670 }, | |
671 { ngx_string("tls13 server in"), &qc->server_in.secret, &iss }, | |
672 { | |
673 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */ | |
674 ngx_string("tls13 quic key"), | |
675 &qc->server_in.key, | |
676 &qc->server_in.secret, | |
677 }, | |
678 { | |
679 ngx_string("tls13 quic iv"), | |
680 &qc->server_in.iv, | |
681 &qc->server_in.secret, | |
682 }, | |
683 { | |
684 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */ | |
685 ngx_string("tls13 quic hp"), | |
686 &qc->server_in.hp, | |
687 &qc->server_in.secret, | |
688 }, | |
689 | |
690 }; | |
691 | |
692 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { | |
693 | |
694 if (ngx_quic_hkdf_expand(c, digest, seq[i].key, &seq[i].label, | |
695 seq[i].prk->data, seq[i].prk->len) | |
696 != NGX_OK) | |
697 { | |
698 return NGX_ERROR; | |
699 } | |
700 } | |
701 | |
702 // header protection | |
703 | |
704 uint8_t mask[16]; | |
705 if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), &qc->client_in, mask, sample) | |
706 != NGX_OK) | |
707 { | |
708 return NGX_ERROR; | |
709 } | |
710 | |
711 u_char clearflags = flags ^ (mask[0] & 0x0f); | |
712 ngx_int_t pnl = (clearflags & 0x03) + 1; | |
713 uint64_t pn = ngx_quic_parse_pn(&b->pos, pnl, &mask[1]); | |
714 | |
715 #if (NGX_DEBUG) | |
716 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
717 m = ngx_hex_dump(buf, sample, 16) - buf; | |
718 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
719 "quic sample: %*s", m, buf); | |
720 | |
721 m = ngx_hex_dump(buf, mask, 5) - buf; | |
722 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
723 "quic mask: %*s", m, buf); | |
724 | |
725 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
726 "quic packet number: %uL, len: %xi", pn, pnl); | |
727 } | |
728 #endif | |
729 | |
730 // packet protection | |
731 | |
732 ngx_str_t in; | |
733 in.data = b->pos; | |
734 in.len = plen - pnl; | |
735 | |
736 ngx_str_t ad; | |
737 ad.len = b->pos - b->start; | |
738 ad.data = ngx_pnalloc(c->pool, ad.len); | |
739 if (ad.data == NULL) { | |
740 return NGX_ERROR; | |
741 } | |
742 | |
743 ngx_memcpy(ad.data, b->start, ad.len); | |
744 ad.data[0] = clearflags; | |
745 ad.data[ad.len - pnl] = (u_char)pn; | |
746 | |
747 uint8_t *nonce = ngx_pstrdup(c->pool, &qc->client_in.iv); | |
748 nonce[11] ^= pn; | |
749 | |
750 #if (NGX_DEBUG) | |
751 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
752 m = ngx_hex_dump(buf, nonce, 12) - buf; | |
753 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
754 "quic nonce: %*s, len: %uz", m, buf, 12); | |
755 | |
756 m = ngx_hex_dump(buf, ad.data, ad.len) - buf; | |
757 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
758 "quic ad: %*s, len: %uz", m, buf, ad.len); | |
759 } | |
760 #endif | |
761 | |
762 ngx_str_t out; | |
763 | |
764 if (ngx_quic_tls_open(c, EVP_aes_128_gcm(), &qc->client_in, &out, nonce, | |
765 &in, &ad) | |
766 != NGX_OK) | |
767 { | |
768 return NGX_ERROR; | |
769 } | |
770 | |
771 #if (NGX_DEBUG) | |
772 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
773 m = ngx_hex_dump(buf, out.data, ngx_min(out.len, 256)) - buf; | |
774 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
775 "quic packet payload: %*s%s, len: %uz", | |
776 m, buf, m < 512 ? "" : "...", out.len); | |
777 } | |
778 #endif | |
779 | |
780 if (out.data[0] != 0x06) { | |
781 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
782 "unexpected frame in initial packet"); | |
783 return NGX_ERROR; | |
784 } | |
785 | |
786 if (out.data[1] != 0x00) { | |
787 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
788 "unexpected CRYPTO offset in initial packet"); | |
789 return NGX_ERROR; | |
790 } | |
791 | |
792 uint8_t *crypto = &out.data[2]; | |
793 uint64_t crypto_len = ngx_quic_parse_int(&crypto); | |
794 | |
795 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
796 "quic initial packet CRYPTO length: %uL pp:%p:%p", | |
797 crypto_len, out.data, crypto); | |
798 | |
799 if (ngx_ssl_create_connection(ssl, c, NGX_SSL_BUFFER) != NGX_OK) { | |
800 return NGX_ERROR; | |
801 } | |
802 | |
803 static const uint8_t params[12] = "\x00\x0a\x00\x3a\x00\x01\x00\x00\x09\x00\x01\x03"; | |
804 | |
805 if (SSL_set_quic_transport_params(c->ssl->connection, params, | |
806 sizeof(params)) == 0) | |
807 { | |
808 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
809 "SSL_set_quic_transport_params() failed"); | |
810 return NGX_ERROR; | |
811 } | |
812 | |
813 n = SSL_do_handshake(c->ssl->connection); | |
814 | |
815 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | |
816 | |
817 if (n == -1) { | |
818 sslerr = SSL_get_error(c->ssl->connection, n); | |
819 | |
820 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", | |
821 sslerr); | |
822 } | |
823 | |
824 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
825 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", | |
826 (int) SSL_quic_read_level(c->ssl->connection), | |
827 (int) SSL_quic_write_level(c->ssl->connection)); | |
828 | |
829 if (!SSL_provide_quic_data(c->ssl->connection, | |
830 SSL_quic_read_level(c->ssl->connection), | |
831 crypto, crypto_len)) | |
832 { | |
833 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
834 "SSL_provide_quic_data() failed"); | |
835 return NGX_ERROR; | |
836 } | |
837 | |
838 n = SSL_do_handshake(c->ssl->connection); | |
839 | |
840 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | |
841 | |
842 if (n == -1) { | |
843 sslerr = SSL_get_error(c->ssl->connection, n); | |
844 | |
845 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", | |
846 sslerr); | |
847 | |
848 if (sslerr == SSL_ERROR_SSL) { | |
849 ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "SSL_do_handshake() failed"); | |
850 } | |
851 } | |
852 | |
853 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
854 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", | |
855 (int) SSL_quic_read_level(c->ssl->connection), | |
856 (int) SSL_quic_write_level(c->ssl->connection)); | |
857 | |
858 return NGX_OK; | |
859 } | |
860 | |
861 | |
862 static ngx_int_t | |
863 ngx_quic_handshake_input(ngx_connection_t *c, ngx_buf_t *bb) | |
864 { | |
865 size_t m; | |
866 ssize_t n; | |
867 ngx_str_t out; | |
868 const EVP_CIPHER *cipher; | |
869 ngx_quic_connection_t *qc; | |
870 u_char buf[4096], *p, *b; | |
871 | |
872 qc = c->quic; | |
873 | |
874 n = bb->last - bb->pos; | |
875 p = bb->pos; | |
876 b = bb->start; | |
877 | |
878 m = ngx_hex_dump(buf, b, n) - buf; | |
879 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
880 "quic handshake handler: %*s, len: %uz", m, buf, n); | |
881 | |
882 if ((p[0] & 0xf0) != 0xe0) { | |
883 ngx_log_error(NGX_LOG_INFO, c->log, 0, "invalid packet type"); | |
884 return NGX_ERROR; | |
885 } | |
886 | |
887 ngx_int_t flags = *p++; | |
888 uint32_t version = ngx_quic_parse_uint32(p); | |
889 p += sizeof(uint32_t); | |
890 | |
891 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
892 "quic flags:%xi version:%xD", flags, version); | |
893 | |
894 if (version != quic_version) { | |
895 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unsupported quic version"); | |
896 return NGX_ERROR; | |
897 } | |
898 | |
899 if (*p++ != qc->dcid.len) { | |
900 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected quic dcidl"); | |
901 return NGX_ERROR; | |
902 } | |
903 | |
904 if (ngx_memcmp(p, qc->dcid.data, qc->dcid.len) != 0) { | |
905 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected quic dcid"); | |
906 return NGX_ERROR; | |
907 } | |
908 | |
909 p += qc->dcid.len; | |
910 | |
911 if (*p++ != qc->scid.len) { | |
912 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected quic scidl"); | |
913 return NGX_ERROR; | |
914 } | |
915 | |
916 if (ngx_memcmp(p, qc->scid.data, qc->scid.len) != 0) { | |
917 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected quic scid"); | |
918 return NGX_ERROR; | |
919 } | |
920 | |
921 p += qc->scid.len; | |
922 | |
923 ngx_int_t plen = ngx_quic_parse_int(&p); | |
924 | |
925 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
926 "quic packet length: %d", plen); | |
927 | |
928 if (plen > b + n - p) { | |
929 ngx_log_error(NGX_LOG_INFO, c->log, 0, "truncated handshake packet"); | |
930 return NGX_ERROR; | |
931 } | |
932 | |
933 u_char *sample = p + 4; | |
934 | |
935 m = ngx_hex_dump(buf, sample, 16) - buf; | |
936 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic sample: %*s", m, buf); | |
937 | |
938 // header protection | |
939 | |
940 uint8_t mask[16]; | |
941 if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), &qc->client_hs, mask, sample) | |
942 != NGX_OK) | |
943 { | |
944 return NGX_ERROR; | |
945 } | |
946 | |
947 u_char clearflags = flags ^ (mask[0] & 0x0f); | |
948 ngx_int_t pnl = (clearflags & 0x03) + 1; | |
949 uint64_t pn = ngx_quic_parse_pn(&p, pnl, &mask[1]); | |
950 | |
951 #if (NGX_DEBUG) | |
952 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
953 m = ngx_hex_dump(buf, mask, 5) - buf; | |
954 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
955 "quic mask: %*s", m, buf); | |
956 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
957 "quic clear flags: %xi", clearflags); | |
958 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
959 "quic packet number: %uL, len: %xi", pn, pnl); | |
960 } | |
961 #endif | |
962 | |
963 // packet protection | |
964 | |
965 ngx_str_t in; | |
966 in.data = p; | |
967 in.len = plen - pnl; | |
968 | |
969 ngx_str_t ad; | |
970 ad.len = p - b; | |
971 ad.data = ngx_pnalloc(c->pool, ad.len); | |
972 if (ad.data == NULL) { | |
973 return NGX_ERROR; | |
974 } | |
975 | |
976 ngx_memcpy(ad.data, b, ad.len); | |
977 ad.data[0] = clearflags; | |
978 ad.data[ad.len - pnl] = (u_char)pn; | |
979 | |
980 uint8_t *nonce = ngx_pstrdup(c->pool, &qc->client_hs.iv); | |
981 nonce[11] ^= pn; | |
982 | |
983 #if (NGX_DEBUG) | |
984 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
985 m = ngx_hex_dump(buf, nonce, 12) - buf; | |
986 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
987 "quic nonce: %*s, len: %uz", m, buf, 12); | |
988 | |
989 m = ngx_hex_dump(buf, ad.data, ad.len) - buf; | |
990 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
991 "quic ad: %*s, len: %uz", m, buf, ad.len); | |
992 } | |
993 #endif | |
994 | |
995 u_char *name = (u_char *) SSL_get_cipher(c->ssl->connection); | |
996 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
997 "quic ssl cipher: %s", name); | |
998 | |
999 if (ngx_strcasecmp(name, (u_char *) "TLS_AES_128_GCM_SHA256") == 0 | |
1000 || ngx_strcasecmp(name, (u_char *) "(NONE)") == 0) | |
1001 { | |
1002 cipher = EVP_aes_128_gcm(); | |
1003 | |
1004 } else if (ngx_strcasecmp(name, (u_char *) "TLS_AES_256_GCM_SHA384") == 0) { | |
1005 cipher = EVP_aes_256_gcm(); | |
1006 | |
1007 } else { | |
1008 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); | |
1009 return NGX_ERROR; | |
1010 } | |
1011 | |
1012 if (ngx_quic_tls_open(c, cipher, &qc->client_hs, &out, nonce, &in, &ad) | |
1013 != NGX_OK) | |
1014 { | |
1015 return NGX_ERROR; | |
1016 } | |
1017 | |
1018 #if (NGX_DEBUG) | |
1019 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
1020 m = ngx_hex_dump(buf, out.data, ngx_min(out.len, 256)) - buf; | |
1021 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1022 "quic packet payload: %*s%s, len: %uz", | |
1023 m, buf, m < 512 ? "" : "...", out.len); | |
1024 } | |
1025 #endif | |
1026 | |
1027 return NGX_OK; | |
1028 } | |
4 | 1029 |
5 | 1030 |
6 uint64_t | 1031 uint64_t |
7 ngx_quic_parse_int(u_char **pos) | 1032 ngx_quic_parse_int(u_char **pos) |
8 { | 1033 { |
51 *pos = p; | 1076 *pos = p; |
52 // return len2; | 1077 // return len2; |
53 } | 1078 } |
54 | 1079 |
55 | 1080 |
56 uint64_t | 1081 static uint64_t |
57 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask) | 1082 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask) |
58 { | 1083 { |
59 u_char *p; | 1084 u_char *p; |
60 uint64_t value; | 1085 uint64_t value; |
61 | 1086 |
69 *pos = p; | 1094 *pos = p; |
70 return value; | 1095 return value; |
71 } | 1096 } |
72 | 1097 |
73 | 1098 |
74 ngx_int_t | 1099 static ngx_int_t |
75 ngx_hkdf_extract(u_char *out_key, size_t *out_len, const EVP_MD *digest, | 1100 ngx_hkdf_extract(u_char *out_key, size_t *out_len, const EVP_MD *digest, |
76 const u_char *secret, size_t secret_len, const u_char *salt, | 1101 const u_char *secret, size_t secret_len, const u_char *salt, |
77 size_t salt_len) | 1102 size_t salt_len) |
78 { | 1103 { |
79 #ifdef OPENSSL_IS_BORINGSSL | 1104 #ifdef OPENSSL_IS_BORINGSSL |
117 | 1142 |
118 return NGX_OK; | 1143 return NGX_OK; |
119 } | 1144 } |
120 | 1145 |
121 | 1146 |
122 ngx_int_t | 1147 static ngx_int_t |
123 ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest, ngx_str_t *out, | 1148 ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest, ngx_str_t *out, |
124 ngx_str_t *label, const uint8_t *prk, size_t prk_len) | 1149 ngx_str_t *label, const uint8_t *prk, size_t prk_len) |
125 { | 1150 { |
126 uint8_t *p; | 1151 uint8_t *p; |
127 size_t info_len; | 1152 size_t info_len; |
166 | 1191 |
167 return NGX_OK; | 1192 return NGX_OK; |
168 } | 1193 } |
169 | 1194 |
170 | 1195 |
171 ngx_int_t | 1196 static ngx_int_t |
172 ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest, | 1197 ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest, |
173 const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len) | 1198 const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len) |
174 { | 1199 { |
175 #ifdef OPENSSL_IS_BORINGSSL | 1200 #ifdef OPENSSL_IS_BORINGSSL |
176 if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len) | 1201 if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len) |
212 | 1237 |
213 return NGX_OK; | 1238 return NGX_OK; |
214 } | 1239 } |
215 | 1240 |
216 | 1241 |
217 ngx_int_t | 1242 static ngx_int_t |
218 ngx_quic_tls_open(ngx_connection_t *c, const EVP_CIPHER *cipher, | 1243 ngx_quic_tls_open(ngx_connection_t *c, const EVP_CIPHER *cipher, |
219 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, | 1244 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, |
220 ngx_str_t *ad) | 1245 ngx_str_t *ad) |
221 { | 1246 { |
222 out->len = in->len - EVP_GCM_TLS_TAG_LEN; | 1247 out->len = in->len - EVP_GCM_TLS_TAG_LEN; |
317 | 1342 |
318 return NGX_OK; | 1343 return NGX_OK; |
319 } | 1344 } |
320 | 1345 |
321 | 1346 |
322 ngx_int_t | 1347 static ngx_int_t |
323 ngx_quic_tls_seal(ngx_connection_t *c, const EVP_CIPHER *cipher, | 1348 ngx_quic_tls_seal(ngx_connection_t *c, const EVP_CIPHER *cipher, |
324 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, | 1349 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, |
325 ngx_str_t *ad) | 1350 ngx_str_t *ad) |
326 { | 1351 { |
327 out->len = in->len + EVP_GCM_TLS_TAG_LEN; | 1352 out->len = in->len + EVP_GCM_TLS_TAG_LEN; |
420 | 1445 |
421 return NGX_OK; | 1446 return NGX_OK; |
422 } | 1447 } |
423 | 1448 |
424 | 1449 |
425 ngx_int_t | 1450 static ngx_int_t |
426 ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, | 1451 ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, |
427 ngx_quic_secret_t *s, u_char *out, u_char *in) | 1452 ngx_quic_secret_t *s, u_char *out, u_char *in) |
428 { | 1453 { |
429 int outlen; | 1454 int outlen; |
430 EVP_CIPHER_CTX *ctx; | 1455 EVP_CIPHER_CTX *ctx; |