annotate src/event/ngx_event_quic_protection.c @ 8221:69345a26ba69 quic

Split transport and crypto parts into separate files. New files: src/event/ngx_event_quic_protection.h src/event/ngx_event_quic_protection.c The protection.h header provides interface to the crypto part of the QUIC: 2 functions to initialize corresponding secrets: ngx_quic_set_initial_secret() ngx_quic_set_encryption_secret() and 2 functions to deal with packet processing: ngx_quic_encrypt() ngx_quic_decrypt() Also, structures representing secrets are defined there. All functions require SSL connection and a pool, only crypto operations inside, no access to nginx connections or events. Currently pool->log is used for the logging (instead of original c->log).
author Vladimir Homutov <vl@nginx.com>
date Mon, 16 Mar 2020 19:00:47 +0300
parents
children ae35ccba7aa6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
2 /*
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
3 * Copyright (C) Nginx, Inc.
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
4 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
5
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
6
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
7 #include <ngx_config.h>
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
8 #include <ngx_core.h>
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
9 #include <ngx_event.h>
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
10
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
11
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
12 #define NGX_QUIC_IV_LEN 12
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
13
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
14 #define NGX_AES_128_GCM_SHA256 0x1301
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
15 #define NGX_AES_256_GCM_SHA384 0x1302
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
16 #define NGX_CHACHA20_POLY1305_SHA256 0x1303
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
17
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
18
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
19 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
20 #define ngx_quic_cipher_t EVP_AEAD
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
21 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
22 #define ngx_quic_cipher_t EVP_CIPHER
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
23 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
24
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
25 typedef struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
26 const ngx_quic_cipher_t *c;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
27 const EVP_CIPHER *hp;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
28 const EVP_MD *d;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
29 } ngx_quic_ciphers_t;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
30
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
31
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
32 static ngx_int_t ngx_hkdf_expand(u_char *out_key, size_t out_len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
33 const EVP_MD *digest, const u_char *prk, size_t prk_len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
34 const u_char *info, size_t info_len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
35 static ngx_int_t ngx_hkdf_extract(u_char *out_key, size_t *out_len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
36 const EVP_MD *digest, const u_char *secret, size_t secret_len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
37 const u_char *salt, size_t salt_len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
38
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
39 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
40 static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
41 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
42
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
43 static ngx_int_t ngx_quic_tls_open(ngx_pool_t *pool, const ngx_quic_cipher_t *cipher,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
44 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
45 ngx_str_t *ad);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
46 static ngx_int_t ngx_quic_tls_seal(ngx_pool_t *pool,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
47 const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, ngx_str_t *out,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
48 u_char *nonce, ngx_str_t *in, ngx_str_t *ad);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
49 static ngx_int_t ngx_quic_tls_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
50 ngx_quic_secret_t *s, u_char *out, u_char *in);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
51 static ngx_int_t ngx_quic_hkdf_expand(ngx_pool_t *pool, const EVP_MD *digest,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
52 ngx_str_t *out, ngx_str_t *label, const uint8_t *prk, size_t prk_len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
53
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
54 static ngx_int_t ngx_quic_create_long_packet(ngx_pool_t *pool,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
55 ngx_ssl_conn_t *ssl_conn, ngx_quic_header_t *pkt, ngx_str_t *in,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
56 ngx_str_t *res);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
57
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
58 static ngx_int_t ngx_quic_create_short_packet(ngx_pool_t *pool,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
59 ngx_ssl_conn_t *ssl_conn, ngx_quic_header_t *pkt, ngx_str_t *in,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
60 ngx_str_t *res);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
61
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
62
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
63 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
64 ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, ngx_quic_ciphers_t *ciphers,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
65 enum ssl_encryption_level_t level)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
66 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
67 ngx_int_t id, len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
68
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
69 if (level == ssl_encryption_initial) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
70 id = NGX_AES_128_GCM_SHA256;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
71
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
72 } else {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
73 id = SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
74 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
75
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
76 switch (id) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
77
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
78 case NGX_AES_128_GCM_SHA256:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
79 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
80 ciphers->c = EVP_aead_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
81 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
82 ciphers->c = EVP_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
83 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
84 ciphers->hp = EVP_aes_128_ctr();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
85 ciphers->d = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
86 len = 16;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
87 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
88
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
89 case NGX_AES_256_GCM_SHA384:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
90 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
91 ciphers->c = EVP_aead_aes_256_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
92 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
93 ciphers->c = EVP_aes_256_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
94 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
95 ciphers->hp = EVP_aes_256_ctr();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
96 ciphers->d = EVP_sha384();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
97 len = 32;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
98 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
99
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
100 case NGX_CHACHA20_POLY1305_SHA256:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
101 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
102 ciphers->c = EVP_aead_chacha20_poly1305();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
103 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
104 ciphers->c = EVP_chacha20_poly1305();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
105 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
106 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
107 ciphers->hp = (const EVP_CIPHER *) EVP_aead_chacha20_poly1305();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
108 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
109 ciphers->hp = EVP_chacha20();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
110 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
111 ciphers->d = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
112 len = 32;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
113 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
114
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
115 default:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
116 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
117 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
118
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
119 return len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
120 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
121
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
122
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
123 ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
124 ngx_quic_set_initial_secret(ngx_pool_t *pool, ngx_quic_secrets_t *qsec,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
125 ngx_str_t *secret)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
126 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
127 size_t is_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
128 uint8_t is[SHA256_DIGEST_LENGTH];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
129 ngx_uint_t i;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
130 const EVP_MD *digest;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
131 const EVP_CIPHER *cipher;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
132
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
133 static const uint8_t salt[20] =
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
134 "\xc3\xee\xf7\x12\xc7\x2e\xbb\x5a\x11\xa7"
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
135 "\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02";
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
136
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
137 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
138
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
139 cipher = EVP_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
140 digest = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
141
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
142 if (ngx_hkdf_extract(is, &is_len, digest, secret->data, secret->len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
143 salt, sizeof(salt))
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
144 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
145 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
146 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
147 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
148
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
149 ngx_str_t iss = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
150 .data = is,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
151 .len = is_len
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
152 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
153
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
154 ngx_quic_hexdump0(pool->log, "salt", salt, sizeof(salt));
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
155 ngx_quic_hexdump0(pool->log, "initial secret", is, is_len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
156
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
157 /* draft-ietf-quic-tls-23#section-5.2 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
158 qsec->client.in.secret.len = SHA256_DIGEST_LENGTH;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
159 qsec->server.in.secret.len = SHA256_DIGEST_LENGTH;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
160
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
161 qsec->client.in.key.len = EVP_CIPHER_key_length(cipher);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
162 qsec->server.in.key.len = EVP_CIPHER_key_length(cipher);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
163
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
164 qsec->client.in.hp.len = EVP_CIPHER_key_length(cipher);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
165 qsec->server.in.hp.len = EVP_CIPHER_key_length(cipher);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
166
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
167 qsec->client.in.iv.len = EVP_CIPHER_iv_length(cipher);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
168 qsec->server.in.iv.len = EVP_CIPHER_iv_length(cipher);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
169
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
170 struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
171 ngx_str_t label;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
172 ngx_str_t *key;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
173 ngx_str_t *prk;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
174 } seq[] = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
175
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
176 /* draft-ietf-quic-tls-23#section-5.2 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
177 { ngx_string("tls13 client in"), &qsec->client.in.secret, &iss },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
178 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
179 ngx_string("tls13 quic key"),
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
180 &qsec->client.in.key,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
181 &qsec->client.in.secret,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
182 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
183 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
184 ngx_string("tls13 quic iv"),
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
185 &qsec->client.in.iv,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
186 &qsec->client.in.secret,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
187 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
188 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
189 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
190 ngx_string("tls13 quic hp"),
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
191 &qsec->client.in.hp,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
192 &qsec->client.in.secret,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
193 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
194 { ngx_string("tls13 server in"), &qsec->server.in.secret, &iss },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
195 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
196 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
197 ngx_string("tls13 quic key"),
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
198 &qsec->server.in.key,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
199 &qsec->server.in.secret,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
200 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
201 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
202 ngx_string("tls13 quic iv"),
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
203 &qsec->server.in.iv,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
204 &qsec->server.in.secret,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
205 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
206 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
207 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
208 ngx_string("tls13 quic hp"),
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
209 &qsec->server.in.hp,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
210 &qsec->server.in.secret,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
211 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
212
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
213 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
214
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
215 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
216
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
217 if (ngx_quic_hkdf_expand(pool, digest, seq[i].key, &seq[i].label,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
218 seq[i].prk->data, seq[i].prk->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
219 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
220 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
221 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
222 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
223 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
224
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
225 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
226 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
227
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
228
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
229 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
230 ngx_quic_hkdf_expand(ngx_pool_t *pool, const EVP_MD *digest, ngx_str_t *out,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
231 ngx_str_t *label, const uint8_t *prk, size_t prk_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
232 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
233 size_t info_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
234 uint8_t *p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
235 uint8_t info[20];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
236
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
237 out->data = ngx_pnalloc(pool, out->len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
238 if (out->data == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
239 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
240 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
241
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
242 info_len = 2 + 1 + label->len + 1;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
243
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
244 info[0] = 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
245 info[1] = out->len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
246 info[2] = label->len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
247 p = ngx_cpymem(&info[3], label->data, label->len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
248 *p = '\0';
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
249
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
250 if (ngx_hkdf_expand(out->data, out->len, digest,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
251 prk, prk_len, info, info_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
252 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
253 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
254 ngx_ssl_error(NGX_LOG_INFO, pool->log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
255 "ngx_hkdf_expand(%V) failed", label);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
256 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
257 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
258
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
259 ngx_quic_hexdump(pool->log, "%V info", info, info_len, label);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
260 ngx_quic_hexdump(pool->log, "%V key", out->data, out->len, label);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
261
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
262 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
263 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
264
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
265
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
266 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
267 ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
268 const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
269 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
270 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
271 if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
272 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
273 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
274 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
275 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
276 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
277
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
278 EVP_PKEY_CTX *pctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
279
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
280 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
281
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
282 if (EVP_PKEY_derive_init(pctx) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
283 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
284 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
285
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
286 if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
287 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
288 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
289
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
290 if (EVP_PKEY_CTX_set_hkdf_md(pctx, digest) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
291 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
292 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
293
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
294 if (EVP_PKEY_CTX_set1_hkdf_key(pctx, prk, prk_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
295 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
296 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
297
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
298 if (EVP_PKEY_CTX_add1_hkdf_info(pctx, info, info_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
299 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
300 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
301
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
302 if (EVP_PKEY_derive(pctx, out_key, &out_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
303 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
304 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
305
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
306 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
307
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
308 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
309 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
310
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
311
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
312 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
313 ngx_hkdf_extract(u_char *out_key, size_t *out_len, const EVP_MD *digest,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
314 const u_char *secret, size_t secret_len, const u_char *salt,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
315 size_t salt_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
316 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
317 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
318 if (HKDF_extract(out_key, out_len, digest, secret, secret_len, salt,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
319 salt_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
320 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
321 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
322 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
323 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
324 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
325
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
326 EVP_PKEY_CTX *pctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
327
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
328 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
329
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
330 if (EVP_PKEY_derive_init(pctx) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
331 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
332 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
333
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
334 if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
335 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
336 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
337
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
338 if (EVP_PKEY_CTX_set_hkdf_md(pctx, digest) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
339 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
340 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
341
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
342 if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, secret_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
343 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
344 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
345
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
346 if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, salt_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
347 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
348 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
349
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
350 if (EVP_PKEY_derive(pctx, out_key, out_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
351 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
352 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
353
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
354 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
355
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
356 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
357 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
358
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
359
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
360 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
361 ngx_quic_tls_open(ngx_pool_t *pool, const ngx_quic_cipher_t *cipher,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
362 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
363 ngx_str_t *ad)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
364 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
365 ngx_log_t *log;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
366
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
367 log = pool->log; // TODO: pass log ?
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
368
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
369 out->len = in->len - EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
370 out->data = ngx_pnalloc(pool, out->len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
371 if (out->data == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
372 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
373 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
374
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
375 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
376 EVP_AEAD_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
377
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
378 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
379 EVP_AEAD_DEFAULT_TAG_LENGTH);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
380 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
381 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_new() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
382 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
383 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
384
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
385 if (EVP_AEAD_CTX_open(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
386 in->data, in->len, ad->data, ad->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
387 != 1)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
388 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
389 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
390 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_open() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
391 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
392 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
393
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
394 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
395 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
396 int len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
397 u_char *tag;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
398 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
399
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
400 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
401 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
402 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CIPHER_CTX_new() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
403 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
404 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
405
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
406 if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
407 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
408 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
409 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
410 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
411
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
412 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, s->iv.len, NULL)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
413 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
414 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
415 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
416 ngx_ssl_error(NGX_LOG_INFO, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
417 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
418 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
419 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
420
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
421 if (EVP_DecryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
422 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
423 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
424 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
425 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
426
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
427 if (EVP_DecryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
428 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
429 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
430 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
431 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
432
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
433 if (EVP_DecryptUpdate(ctx, out->data, &len, in->data,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
434 in->len - EVP_GCM_TLS_TAG_LEN)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
435 != 1)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
436 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
437 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
438 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
439 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
440 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
441
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
442 out->len = len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
443 tag = in->data + in->len - EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
444
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
445 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
446 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
447 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
448 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
449 ngx_ssl_error(NGX_LOG_INFO, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
450 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_TAG) failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
451 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
452 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
453
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
454 if (EVP_DecryptFinal_ex(ctx, out->data + len, &len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
455 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
456 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptFinal_ex failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
457 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
458 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
459
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
460 out->len += len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
461
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
462 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
463 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
464
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
465 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
466 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
467
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
468
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
469 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
470 ngx_quic_tls_seal(ngx_pool_t *pool, const ngx_quic_cipher_t *cipher,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
471 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
472 ngx_str_t *ad)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
473 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
474 ngx_log_t *log;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
475
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
476 log = pool->log; // TODO: pass log ?
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
477
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
478 out->len = in->len + EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
479 out->data = ngx_pnalloc(pool, out->len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
480 if (out->data == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
481 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
482 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
483
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
484 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
485 EVP_AEAD_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
486
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
487 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
488 EVP_AEAD_DEFAULT_TAG_LENGTH);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
489 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
490 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_new() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
491 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
492 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
493
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
494 if (EVP_AEAD_CTX_seal(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
495 in->data, in->len, ad->data, ad->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
496 != 1)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
497 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
498 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
499 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_seal() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
500 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
501 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
502
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
503 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
504 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
505 int len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
506 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
507
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
508 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
509 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
510 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CIPHER_CTX_new() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
511 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
512 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
513
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
514 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
515 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
516 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
517 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
518 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
519
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
520 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, s->iv.len, NULL)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
521 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
522 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
523 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
524 ngx_ssl_error(NGX_LOG_INFO, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
525 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
526 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
527 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
528
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
529 if (EVP_EncryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
530 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
531 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
532 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
533 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
534
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
535 if (EVP_EncryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
536 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
537 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
538 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
539 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
540
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
541 if (EVP_EncryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
542 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
543 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
544 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
545 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
546
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
547 out->len = len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
548
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
549 if (EVP_EncryptFinal_ex(ctx, out->data + out->len, &len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
550 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
551 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_ex failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
552 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
553 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
554
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
555 out->len += len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
556
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
557 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
558 out->data + in->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
559 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
560 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
561 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
562 ngx_ssl_error(NGX_LOG_INFO, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
563 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_GET_TAG) failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
564 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
565 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
566
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
567 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
568
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
569 out->len += EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
570 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
571 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
572 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
573
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
574
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
575 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
576 ngx_quic_tls_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
577 ngx_quic_secret_t *s, u_char *out, u_char *in)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
578 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
579 int outlen;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
580 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
581 u_char zero[5] = {0};
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
582
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
583 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
584 uint32_t counter;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
585
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
586 ngx_memcpy(&counter, in, sizeof(uint32_t));
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
587
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
588 if (cipher == (const EVP_CIPHER *) EVP_aead_chacha20_poly1305()) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
589 CRYPTO_chacha_20(out, zero, 5, s->hp.data, &in[4], counter);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
590 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
591 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
592 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
593
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
594 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
595 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
596 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
597 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
598
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
599 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, in) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
600 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
601 goto failed;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
602 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
603
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
604 if (!EVP_EncryptUpdate(ctx, out, &outlen, zero, 5)) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
605 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
606 goto failed;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
607 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
608
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
609 if (!EVP_EncryptFinal_ex(ctx, out + 5, &outlen)) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
610 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_Ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
611 goto failed;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
612 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
613
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
614 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
615
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
616 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
617
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
618 failed:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
619
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
620 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
621
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
622 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
623 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
624
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
625
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
626 int
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
627 ngx_quic_set_encryption_secret(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
628 enum ssl_encryption_level_t level, const uint8_t *secret,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
629 size_t secret_len, ngx_quic_peer_secrets_t *qsec)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
630 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
631 ngx_int_t key_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
632 ngx_uint_t i;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
633 ngx_quic_secret_t *peer_secret;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
634 ngx_quic_ciphers_t ciphers;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
635
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
636 key_len = ngx_quic_ciphers(ssl_conn, &ciphers, level);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
637
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
638 if (key_len == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
639 ngx_ssl_error(NGX_LOG_INFO, pool->log, 0, "unexpected cipher");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
640 return 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
641 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
642
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
643 switch (level) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
644
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
645 case ssl_encryption_handshake:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
646 peer_secret= &qsec->hs;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
647 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
648
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
649 case ssl_encryption_application:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
650 peer_secret = &qsec->ad;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
651 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
652
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
653 default:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
654 return 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
655 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
656
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
657 peer_secret->key.len = key_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
658 peer_secret->iv.len = NGX_QUIC_IV_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
659 peer_secret->hp.len = key_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
660
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
661 struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
662 ngx_str_t label;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
663 ngx_str_t *key;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
664 const uint8_t *secret;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
665 } seq[] = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
666 { ngx_string("tls13 quic key"), &peer_secret->key, secret },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
667 { ngx_string("tls13 quic iv"), &peer_secret->iv, secret },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
668 { ngx_string("tls13 quic hp"), &peer_secret->hp, secret },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
669 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
670
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
671 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
672
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
673 if (ngx_quic_hkdf_expand(pool, ciphers.d, seq[i].key, &seq[i].label,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
674 seq[i].secret, secret_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
675 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
676 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
677 return 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
678 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
679 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
680
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
681 return 1;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
682 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
683
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
684
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
685 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
686 ngx_quic_create_long_packet(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
687 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
688 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
689 u_char *p, *pnp, *nonce, *sample, *packet;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
690 uint64_t pn;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
691 ngx_log_t *log;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
692 ngx_str_t ad, out;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
693 ngx_quic_ciphers_t ciphers;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
694 u_char mask[16];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
695
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
696 log = pool->log;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
697
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
698 out.len = payload->len + EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
699
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
700 ad.data = ngx_alloc(346 /*max header*/, log);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
701 if (ad.data == 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
702 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
703 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
704
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
705 p = ad.data;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
706
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
707 *p++ = pkt->flags;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
708
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
709 p = ngx_quic_write_uint32(p, quic_version);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
710
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
711 *p++ = pkt->scid.len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
712 p = ngx_cpymem(p, pkt->scid.data, pkt->scid.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
713
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
714 *p++ = pkt->dcid.len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
715 p = ngx_cpymem(p, pkt->dcid.data, pkt->dcid.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
716
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
717 if (pkt->level == ssl_encryption_initial) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
718 ngx_quic_build_int(&p, pkt->token.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
719 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
720
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
721 ngx_quic_build_int(&p, out.len + 1); // length (inc. pnl)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
722 pnp = p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
723
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
724 pn = *pkt->number;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
725
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
726 *p++ = pn;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
727
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
728 ad.len = p - ad.data;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
729
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
730 ngx_quic_hexdump0(log, "ad", ad.data, ad.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
731
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
732 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
733 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
734 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
735
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
736 nonce = ngx_pstrdup(pool, &pkt->secret->iv);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
737 if (pkt->level == ssl_encryption_handshake) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
738 nonce[11] ^= pn;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
739 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
740
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
741 ngx_quic_hexdump0(log, "server_iv", pkt->secret->iv.data, 12);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
742 ngx_quic_hexdump0(log, "nonce", nonce, 12);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
743
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
744 if (ngx_quic_tls_seal(pool, ciphers.c, pkt->secret, &out,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
745 nonce, payload, &ad)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
746 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
747 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
748 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
749 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
750
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
751 sample = &out.data[3]; // pnl=0
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
752 if (ngx_quic_tls_hp(log, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
753 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
754 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
755
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
756 ngx_quic_hexdump0(log, "sample", sample, 16);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
757 ngx_quic_hexdump0(log, "mask", mask, 16);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
758 ngx_quic_hexdump0(log, "hp_key", pkt->secret->hp.data, 16);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
759
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
760 // header protection, pnl = 0
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
761 ad.data[0] ^= mask[0] & 0x0f;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
762 *pnp ^= mask[1];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
763
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
764 packet = ngx_alloc(ad.len + out.len, log);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
765 if (packet == 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
766 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
767 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
768
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
769 p = ngx_cpymem(packet, ad.data, ad.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
770 p = ngx_cpymem(p, out.data, out.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
771
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
772 res->data = packet;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
773 res->len = p - packet;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
774
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
775 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
776 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
777
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
778
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
779 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
780 ngx_quic_create_short_packet(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
781 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
782 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
783 u_char *p, *pnp, *nonce, *sample, *packet;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
784 ngx_log_t *log;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
785 ngx_str_t ad, out;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
786 ngx_quic_ciphers_t ciphers;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
787 u_char mask[16];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
788
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
789 log = pool->log;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
790
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
791 out.len = payload->len + EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
792
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
793 ad.data = ngx_alloc(25 /*max header*/, log);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
794 if (ad.data == 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
795 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
796 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
797
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
798 p = ad.data;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
799
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
800 *p++ = 0x40;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
801
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
802 p = ngx_cpymem(p, pkt->scid.data, pkt->scid.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
803
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
804 pnp = p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
805
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
806 *p++ = (*pkt->number);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
807
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
808 ad.len = p - ad.data;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
809
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
810 ngx_quic_hexdump0(log, "ad", ad.data, ad.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
811
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
812 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
813 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
814 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
815
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
816 nonce = ngx_pstrdup(pool, &pkt->secret->iv);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
817 if (pkt->level == ssl_encryption_handshake
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
818 || pkt->level == ssl_encryption_application)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
819 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
820 nonce[11] ^= *pkt->number;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
821 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
822
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
823 ngx_quic_hexdump0(log, "server_iv", pkt->secret->iv.data, 12);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
824 ngx_quic_hexdump0(log, "nonce", nonce, 12);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
825
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
826 if (ngx_quic_tls_seal(pool, ciphers.c, pkt->secret, &out,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
827 nonce, payload, &ad)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
828 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
829 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
830 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
831 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
832
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
833 ngx_quic_hexdump0(log, "out", out.data, out.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
834
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
835 sample = &out.data[3]; // pnl=0
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
836 if (ngx_quic_tls_hp(log, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
837 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
838 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
839
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
840 ngx_quic_hexdump0(log, "sample", sample, 16);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
841 ngx_quic_hexdump0(log, "mask", mask, 16);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
842 ngx_quic_hexdump0(log, "hp_key", pkt->secret->hp.data, 16);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
843
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
844 // header protection, pnl = 0
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
845 ad.data[0] ^= mask[0] & 0x1f;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
846 *pnp ^= mask[1];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
847
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
848 packet = ngx_alloc(ad.len + out.len, log);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
849 if (packet == 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
850 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
851 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
852
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
853 p = ngx_cpymem(packet, ad.data, ad.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
854 p = ngx_cpymem(p, out.data, out.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
855
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
856 ngx_quic_hexdump0(log, "packet", packet, p - packet);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
857
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
858 res->data = packet;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
859 res->len = p - packet;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
860
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
861 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
862 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
863
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
864 static uint64_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
865 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
866 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
867 u_char *p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
868 uint64_t value;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
869
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
870 p = *pos;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
871 value = *p++ ^ *mask++;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
872
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
873 while (--len) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
874 value = (value << 8) + (*p++ ^ *mask++);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
875 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
876
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
877 *pos = p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
878 return value;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
879 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
880
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
881
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
882 ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
883 ngx_quic_encrypt(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
884 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
885 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
886 if (pkt->level == ssl_encryption_application) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
887 return ngx_quic_create_short_packet(pool, ssl_conn, pkt, payload, res);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
888 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
889
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
890 return ngx_quic_create_long_packet(pool, ssl_conn, pkt, payload, res);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
891 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
892
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
893
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
894 ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
895 ngx_quic_decrypt(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
896 ngx_quic_header_t *pkt)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
897 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
898 u_char clearflags, *p, *sample;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
899 uint8_t *nonce;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
900 uint64_t pn;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
901 ngx_log_t *log;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
902 ngx_int_t pnl, rc;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
903 ngx_str_t in, ad;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
904 ngx_quic_ciphers_t ciphers;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
905 uint8_t mask[16];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
906
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
907 log = pool->log;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
908
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
909 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
910 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
911 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
912
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
913 p = pkt->raw->pos;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
914
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
915 /* draft-ietf-quic-tls-23#section-5.4.2:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
916 * the Packet Number field is assumed to be 4 bytes long
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
917 * draft-ietf-quic-tls-23#section-5.4.[34]:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
918 * AES-Based and ChaCha20-Based header protections sample 16 bytes
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
919 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
920
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
921 sample = p + 4;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
922
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
923 ngx_quic_hexdump0(log, "sample", sample, 16);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
924
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
925 /* header protection */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
926
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
927 if (ngx_quic_tls_hp(log, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
928 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
929 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
930
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
931 if (pkt->flags & NGX_QUIC_PKT_LONG) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
932 clearflags = pkt->flags ^ (mask[0] & 0x0f);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
933
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
934 } else {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
935 clearflags = pkt->flags ^ (mask[0] & 0x1f);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
936 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
937
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
938 pnl = (clearflags & 0x03) + 1;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
939 pn = ngx_quic_parse_pn(&p, pnl, &mask[1]);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
940
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
941 pkt->pn = pn;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
942
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
943 ngx_quic_hexdump0(log, "mask", mask, 5);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
944 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
945 "quic clear flags: %xi", clearflags);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
946 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
947 "quic packet number: %uL, len: %xi", pn, pnl);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
948
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
949 /* packet protection */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
950
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
951 in.data = p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
952
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
953 if (pkt->flags & NGX_QUIC_PKT_LONG) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
954 in.len = pkt->len - pnl;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
955
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
956 } else {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
957 in.len = pkt->data + pkt->len - p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
958 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
959
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
960 ad.len = p - pkt->data;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
961 ad.data = ngx_pnalloc(pool, ad.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
962 if (ad.data == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
963 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
964 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
965
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
966 ngx_memcpy(ad.data, pkt->data, ad.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
967 ad.data[0] = clearflags;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
968
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
969 do {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
970 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
971 } while (--pnl);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
972
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
973 nonce = ngx_pstrdup(pool, &pkt->secret->iv);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
974 nonce[11] ^= pn;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
975
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
976 ngx_quic_hexdump0(log, "nonce", nonce, 12);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
977 ngx_quic_hexdump0(log, "ad", ad.data, ad.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
978
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
979 rc = ngx_quic_tls_open(pool, ciphers.c, pkt->secret, &pkt->payload,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
980 nonce, &in, &ad);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
981
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
982 ngx_quic_hexdump0(log, "packet payload",
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
983 pkt->payload.data, pkt->payload.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
984
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
985 return rc;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
986 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
987