1 /*
2  * ngtcp2
3  *
4  * Copyright (c) 2019 ngtcp2 contributors
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif /* HAVE_CONFIG_H */
28 
29 #include <assert.h>
30 
31 #include <ngtcp2/ngtcp2_crypto.h>
32 #include <ngtcp2/ngtcp2_crypto_openssl.h>
33 
34 #include <openssl/ssl.h>
35 #include <openssl/evp.h>
36 #include <openssl/kdf.h>
37 #include <openssl/rand.h>
38 
39 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
40 #  include <openssl/core_names.h>
41 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
42 
43 #include "shared.h"
44 
crypto_aead_max_overhead(const EVP_CIPHER * aead)45 static size_t crypto_aead_max_overhead(const EVP_CIPHER *aead) {
46   switch (EVP_CIPHER_nid(aead)) {
47   case NID_aes_128_gcm:
48   case NID_aes_256_gcm:
49     return EVP_GCM_TLS_TAG_LEN;
50   case NID_chacha20_poly1305:
51     return EVP_CHACHAPOLY_TLS_TAG_LEN;
52   case NID_aes_128_ccm:
53     return EVP_CCM_TLS_TAG_LEN;
54   default:
55     assert(0);
56     abort(); /* if NDEBUG is set */
57   }
58 }
59 
ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead * aead)60 ngtcp2_crypto_aead *ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead *aead) {
61   return ngtcp2_crypto_aead_init(aead, (void *)EVP_aes_128_gcm());
62 }
63 
ngtcp2_crypto_md_sha256(ngtcp2_crypto_md * md)64 ngtcp2_crypto_md *ngtcp2_crypto_md_sha256(ngtcp2_crypto_md *md) {
65   md->native_handle = (void *)EVP_sha256();
66   return md;
67 }
68 
ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx * ctx)69 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx *ctx) {
70   ngtcp2_crypto_aead_init(&ctx->aead, (void *)EVP_aes_128_gcm());
71   ctx->md.native_handle = (void *)EVP_sha256();
72   ctx->hp.native_handle = (void *)EVP_aes_128_ctr();
73   ctx->max_encryption = 0;
74   ctx->max_decryption_failure = 0;
75   return ctx;
76 }
77 
ngtcp2_crypto_aead_init(ngtcp2_crypto_aead * aead,void * aead_native_handle)78 ngtcp2_crypto_aead *ngtcp2_crypto_aead_init(ngtcp2_crypto_aead *aead,
79                                             void *aead_native_handle) {
80   aead->native_handle = aead_native_handle;
81   aead->max_overhead = crypto_aead_max_overhead(aead_native_handle);
82   return aead;
83 }
84 
ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead * aead)85 ngtcp2_crypto_aead *ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead *aead) {
86   return ngtcp2_crypto_aead_init(aead, (void *)EVP_aes_128_gcm());
87 }
88 
crypto_ssl_get_aead(SSL * ssl)89 static const EVP_CIPHER *crypto_ssl_get_aead(SSL *ssl) {
90   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
91   case TLS1_3_CK_AES_128_GCM_SHA256:
92     return EVP_aes_128_gcm();
93   case TLS1_3_CK_AES_256_GCM_SHA384:
94     return EVP_aes_256_gcm();
95   case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
96     return EVP_chacha20_poly1305();
97   case TLS1_3_CK_AES_128_CCM_SHA256:
98     return EVP_aes_128_ccm();
99   default:
100     return NULL;
101   }
102 }
103 
crypto_ssl_get_aead_max_encryption(SSL * ssl)104 static uint64_t crypto_ssl_get_aead_max_encryption(SSL *ssl) {
105   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
106   case TLS1_3_CK_AES_128_GCM_SHA256:
107   case TLS1_3_CK_AES_256_GCM_SHA384:
108     return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_GCM;
109   case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
110     return NGTCP2_CRYPTO_MAX_ENCRYPTION_CHACHA20_POLY1305;
111   case TLS1_3_CK_AES_128_CCM_SHA256:
112     return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_CCM;
113   default:
114     return 0;
115   }
116 }
117 
crypto_ssl_get_aead_max_decryption_failure(SSL * ssl)118 static uint64_t crypto_ssl_get_aead_max_decryption_failure(SSL *ssl) {
119   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
120   case TLS1_3_CK_AES_128_GCM_SHA256:
121   case TLS1_3_CK_AES_256_GCM_SHA384:
122     return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_GCM;
123   case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
124     return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_CHACHA20_POLY1305;
125   case TLS1_3_CK_AES_128_CCM_SHA256:
126     return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_CCM;
127   default:
128     return 0;
129   }
130 }
131 
crypto_ssl_get_hp(SSL * ssl)132 static const EVP_CIPHER *crypto_ssl_get_hp(SSL *ssl) {
133   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
134   case TLS1_3_CK_AES_128_GCM_SHA256:
135   case TLS1_3_CK_AES_128_CCM_SHA256:
136     return EVP_aes_128_ctr();
137   case TLS1_3_CK_AES_256_GCM_SHA384:
138     return EVP_aes_256_ctr();
139   case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
140     return EVP_chacha20();
141   default:
142     return NULL;
143   }
144 }
145 
crypto_ssl_get_md(SSL * ssl)146 static const EVP_MD *crypto_ssl_get_md(SSL *ssl) {
147   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
148   case TLS1_3_CK_AES_128_GCM_SHA256:
149   case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
150   case TLS1_3_CK_AES_128_CCM_SHA256:
151     return EVP_sha256();
152   case TLS1_3_CK_AES_256_GCM_SHA384:
153     return EVP_sha384();
154   default:
155     return NULL;
156   }
157 }
158 
ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx * ctx,void * tls_native_handle)159 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
160                                          void *tls_native_handle) {
161   SSL *ssl = tls_native_handle;
162   ngtcp2_crypto_aead_init(&ctx->aead, (void *)crypto_ssl_get_aead(ssl));
163   ctx->md.native_handle = (void *)crypto_ssl_get_md(ssl);
164   ctx->hp.native_handle = (void *)crypto_ssl_get_hp(ssl);
165   ctx->max_encryption = crypto_ssl_get_aead_max_encryption(ssl);
166   ctx->max_decryption_failure = crypto_ssl_get_aead_max_decryption_failure(ssl);
167   return ctx;
168 }
169 
ngtcp2_crypto_ctx_tls_early(ngtcp2_crypto_ctx * ctx,void * tls_native_handle)170 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls_early(ngtcp2_crypto_ctx *ctx,
171                                                void *tls_native_handle) {
172   return ngtcp2_crypto_ctx_tls(ctx, tls_native_handle);
173 }
174 
crypto_md_hashlen(const EVP_MD * md)175 static size_t crypto_md_hashlen(const EVP_MD *md) {
176   return (size_t)EVP_MD_size(md);
177 }
178 
ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md * md)179 size_t ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md *md) {
180   return crypto_md_hashlen(md->native_handle);
181 }
182 
crypto_aead_keylen(const EVP_CIPHER * aead)183 static size_t crypto_aead_keylen(const EVP_CIPHER *aead) {
184   return (size_t)EVP_CIPHER_key_length(aead);
185 }
186 
ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead * aead)187 size_t ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead *aead) {
188   return crypto_aead_keylen(aead->native_handle);
189 }
190 
crypto_aead_noncelen(const EVP_CIPHER * aead)191 static size_t crypto_aead_noncelen(const EVP_CIPHER *aead) {
192   return (size_t)EVP_CIPHER_iv_length(aead);
193 }
194 
ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead * aead)195 size_t ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead *aead) {
196   return crypto_aead_noncelen(aead->native_handle);
197 }
198 
ngtcp2_crypto_aead_ctx_encrypt_init(ngtcp2_crypto_aead_ctx * aead_ctx,const ngtcp2_crypto_aead * aead,const uint8_t * key,size_t noncelen)199 int ngtcp2_crypto_aead_ctx_encrypt_init(ngtcp2_crypto_aead_ctx *aead_ctx,
200                                         const ngtcp2_crypto_aead *aead,
201                                         const uint8_t *key, size_t noncelen) {
202   const EVP_CIPHER *cipher = aead->native_handle;
203   int cipher_nid = EVP_CIPHER_nid(cipher);
204   EVP_CIPHER_CTX *actx;
205   size_t taglen = crypto_aead_max_overhead(cipher);
206 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
207   OSSL_PARAM params[3];
208 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
209 
210   actx = EVP_CIPHER_CTX_new();
211   if (actx == NULL) {
212     return -1;
213   }
214 
215 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
216   params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &noncelen);
217 
218   if (cipher_nid == NID_aes_128_ccm) {
219     params[1] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
220                                                   NULL, taglen);
221     params[2] = OSSL_PARAM_construct_end();
222   } else {
223     params[1] = OSSL_PARAM_construct_end();
224   }
225 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
226 
227   if (!EVP_EncryptInit_ex(actx, cipher, NULL, NULL, NULL) ||
228 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
229       !EVP_CIPHER_CTX_set_params(actx, params) ||
230 #else  /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
231       !EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_IVLEN, (int)noncelen,
232                            NULL) ||
233       (cipher_nid == NID_aes_128_ccm &&
234        !EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_TAG, (int)taglen, NULL)) ||
235 #endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
236       !EVP_EncryptInit_ex(actx, NULL, NULL, key, NULL)) {
237     EVP_CIPHER_CTX_free(actx);
238     return -1;
239   }
240 
241   aead_ctx->native_handle = actx;
242 
243   return 0;
244 }
245 
ngtcp2_crypto_aead_ctx_decrypt_init(ngtcp2_crypto_aead_ctx * aead_ctx,const ngtcp2_crypto_aead * aead,const uint8_t * key,size_t noncelen)246 int ngtcp2_crypto_aead_ctx_decrypt_init(ngtcp2_crypto_aead_ctx *aead_ctx,
247                                         const ngtcp2_crypto_aead *aead,
248                                         const uint8_t *key, size_t noncelen) {
249   const EVP_CIPHER *cipher = aead->native_handle;
250   int cipher_nid = EVP_CIPHER_nid(cipher);
251   EVP_CIPHER_CTX *actx;
252   size_t taglen = crypto_aead_max_overhead(cipher);
253 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
254   OSSL_PARAM params[3];
255 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
256 
257   actx = EVP_CIPHER_CTX_new();
258   if (actx == NULL) {
259     return -1;
260   }
261 
262 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
263   params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &noncelen);
264 
265   if (cipher_nid == NID_aes_128_ccm) {
266     params[1] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
267                                                   NULL, taglen);
268     params[2] = OSSL_PARAM_construct_end();
269   } else {
270     params[1] = OSSL_PARAM_construct_end();
271   }
272 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
273 
274   if (!EVP_DecryptInit_ex(actx, cipher, NULL, NULL, NULL) ||
275 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
276       !EVP_CIPHER_CTX_set_params(actx, params) ||
277 #else  /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
278       !EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_IVLEN, (int)noncelen,
279                            NULL) ||
280       (cipher_nid == NID_aes_128_ccm &&
281        !EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_TAG, (int)taglen, NULL)) ||
282 #endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
283       !EVP_DecryptInit_ex(actx, NULL, NULL, key, NULL)) {
284     EVP_CIPHER_CTX_free(actx);
285     return -1;
286   }
287 
288   aead_ctx->native_handle = actx;
289 
290   return 0;
291 }
292 
ngtcp2_crypto_aead_ctx_free(ngtcp2_crypto_aead_ctx * aead_ctx)293 void ngtcp2_crypto_aead_ctx_free(ngtcp2_crypto_aead_ctx *aead_ctx) {
294   if (aead_ctx->native_handle) {
295     EVP_CIPHER_CTX_free(aead_ctx->native_handle);
296   }
297 }
298 
ngtcp2_crypto_cipher_ctx_encrypt_init(ngtcp2_crypto_cipher_ctx * cipher_ctx,const ngtcp2_crypto_cipher * cipher,const uint8_t * key)299 int ngtcp2_crypto_cipher_ctx_encrypt_init(ngtcp2_crypto_cipher_ctx *cipher_ctx,
300                                           const ngtcp2_crypto_cipher *cipher,
301                                           const uint8_t *key) {
302   EVP_CIPHER_CTX *actx;
303 
304   actx = EVP_CIPHER_CTX_new();
305   if (actx == NULL) {
306     return -1;
307   }
308 
309   if (!EVP_EncryptInit_ex(actx, cipher->native_handle, NULL, key, NULL)) {
310     EVP_CIPHER_CTX_free(actx);
311     return -1;
312   }
313 
314   cipher_ctx->native_handle = actx;
315 
316   return 0;
317 }
318 
ngtcp2_crypto_cipher_ctx_free(ngtcp2_crypto_cipher_ctx * cipher_ctx)319 void ngtcp2_crypto_cipher_ctx_free(ngtcp2_crypto_cipher_ctx *cipher_ctx) {
320   if (cipher_ctx->native_handle) {
321     EVP_CIPHER_CTX_free(cipher_ctx->native_handle);
322   }
323 }
324 
ngtcp2_crypto_hkdf_extract(uint8_t * dest,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen,const uint8_t * salt,size_t saltlen)325 int ngtcp2_crypto_hkdf_extract(uint8_t *dest, const ngtcp2_crypto_md *md,
326                                const uint8_t *secret, size_t secretlen,
327                                const uint8_t *salt, size_t saltlen) {
328 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
329   const EVP_MD *prf = md->native_handle;
330   EVP_KDF *kdf = EVP_KDF_fetch(NULL, "hkdf", NULL);
331   EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
332   int mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
333   OSSL_PARAM params[] = {
334       OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode),
335       OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
336                                        (char *)EVP_MD_get0_name(prf), 0),
337       OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (void *)secret,
338                                         secretlen),
339       OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, (void *)salt,
340                                         saltlen),
341       OSSL_PARAM_construct_end(),
342   };
343   int rv = 0;
344 
345   EVP_KDF_free(kdf);
346 
347   if (EVP_KDF_derive(kctx, dest, (size_t)EVP_MD_size(prf), params) <= 0) {
348     rv = -1;
349   }
350 
351   EVP_KDF_CTX_free(kctx);
352 
353   return rv;
354 #else  /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
355   const EVP_MD *prf = md->native_handle;
356   int rv = 0;
357   EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
358   size_t destlen = (size_t)EVP_MD_size(prf);
359 
360   if (pctx == NULL) {
361     return -1;
362   }
363 
364   if (EVP_PKEY_derive_init(pctx) != 1 ||
365       EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) != 1 ||
366       EVP_PKEY_CTX_set_hkdf_md(pctx, prf) != 1 ||
367       EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, (int)saltlen) != 1 ||
368       EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, (int)secretlen) != 1 ||
369       EVP_PKEY_derive(pctx, dest, &destlen) != 1) {
370     rv = -1;
371   }
372 
373   EVP_PKEY_CTX_free(pctx);
374 
375   return rv;
376 #endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
377 }
378 
ngtcp2_crypto_hkdf_expand(uint8_t * dest,size_t destlen,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen,const uint8_t * info,size_t infolen)379 int ngtcp2_crypto_hkdf_expand(uint8_t *dest, size_t destlen,
380                               const ngtcp2_crypto_md *md, const uint8_t *secret,
381                               size_t secretlen, const uint8_t *info,
382                               size_t infolen) {
383 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
384   const EVP_MD *prf = md->native_handle;
385   EVP_KDF *kdf = EVP_KDF_fetch(NULL, "hkdf", NULL);
386   EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
387   int mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
388   OSSL_PARAM params[] = {
389       OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode),
390       OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
391                                        (char *)EVP_MD_get0_name(prf), 0),
392       OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (void *)secret,
393                                         secretlen),
394       OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, (void *)info,
395                                         infolen),
396       OSSL_PARAM_construct_end(),
397   };
398   int rv = 0;
399 
400   EVP_KDF_free(kdf);
401 
402   if (EVP_KDF_derive(kctx, dest, destlen, params) <= 0) {
403     rv = -1;
404   }
405 
406   EVP_KDF_CTX_free(kctx);
407 
408   return rv;
409 #else  /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
410   const EVP_MD *prf = md->native_handle;
411   int rv = 0;
412   EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
413   if (pctx == NULL) {
414     return -1;
415   }
416 
417   if (EVP_PKEY_derive_init(pctx) != 1 ||
418       EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) != 1 ||
419       EVP_PKEY_CTX_set_hkdf_md(pctx, prf) != 1 ||
420       EVP_PKEY_CTX_set1_hkdf_salt(pctx, (const unsigned char *)"", 0) != 1 ||
421       EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, (int)secretlen) != 1 ||
422       EVP_PKEY_CTX_add1_hkdf_info(pctx, info, (int)infolen) != 1 ||
423       EVP_PKEY_derive(pctx, dest, &destlen) != 1) {
424     rv = -1;
425   }
426 
427   EVP_PKEY_CTX_free(pctx);
428 
429   return rv;
430 #endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
431 }
432 
ngtcp2_crypto_hkdf(uint8_t * dest,size_t destlen,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen,const uint8_t * salt,size_t saltlen,const uint8_t * info,size_t infolen)433 int ngtcp2_crypto_hkdf(uint8_t *dest, size_t destlen,
434                        const ngtcp2_crypto_md *md, const uint8_t *secret,
435                        size_t secretlen, const uint8_t *salt, size_t saltlen,
436                        const uint8_t *info, size_t infolen) {
437 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
438   const EVP_MD *prf = md->native_handle;
439   EVP_KDF *kdf = EVP_KDF_fetch(NULL, "hkdf", NULL);
440   EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf);
441   OSSL_PARAM params[] = {
442       OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
443                                        (char *)EVP_MD_get0_name(prf), 0),
444       OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (void *)secret,
445                                         secretlen),
446       OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, (void *)salt,
447                                         saltlen),
448       OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, (void *)info,
449                                         infolen),
450       OSSL_PARAM_construct_end(),
451   };
452   int rv = 0;
453 
454   EVP_KDF_free(kdf);
455 
456   if (EVP_KDF_derive(kctx, dest, destlen, params) <= 0) {
457     rv = -1;
458   }
459 
460   EVP_KDF_CTX_free(kctx);
461 
462   return rv;
463 #else  /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
464   const EVP_MD *prf = md->native_handle;
465   int rv = 0;
466   EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
467   if (pctx == NULL) {
468     return -1;
469   }
470 
471   if (EVP_PKEY_derive_init(pctx) != 1 ||
472       EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) !=
473           1 ||
474       EVP_PKEY_CTX_set_hkdf_md(pctx, prf) != 1 ||
475       EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, (int)saltlen) != 1 ||
476       EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, (int)secretlen) != 1 ||
477       EVP_PKEY_CTX_add1_hkdf_info(pctx, info, (int)infolen) != 1 ||
478       EVP_PKEY_derive(pctx, dest, &destlen) != 1) {
479     rv = -1;
480   }
481 
482   EVP_PKEY_CTX_free(pctx);
483 
484   return rv;
485 #endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
486 }
487 
ngtcp2_crypto_encrypt(uint8_t * dest,const ngtcp2_crypto_aead * aead,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * plaintext,size_t plaintextlen,const uint8_t * nonce,size_t noncelen,const uint8_t * aad,size_t aadlen)488 int ngtcp2_crypto_encrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
489                           const ngtcp2_crypto_aead_ctx *aead_ctx,
490                           const uint8_t *plaintext, size_t plaintextlen,
491                           const uint8_t *nonce, size_t noncelen,
492                           const uint8_t *aad, size_t aadlen) {
493   const EVP_CIPHER *cipher = aead->native_handle;
494   size_t taglen = crypto_aead_max_overhead(cipher);
495   int cipher_nid = EVP_CIPHER_nid(cipher);
496   EVP_CIPHER_CTX *actx = aead_ctx->native_handle;
497   int len;
498 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
499   OSSL_PARAM params[] = {
500       OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
501                                         dest + plaintextlen, taglen),
502       OSSL_PARAM_construct_end(),
503   };
504 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
505 
506   (void)noncelen;
507 
508   if (!EVP_EncryptInit_ex(actx, NULL, NULL, NULL, nonce) ||
509       (cipher_nid == NID_aes_128_ccm &&
510        !EVP_EncryptUpdate(actx, NULL, &len, NULL, (int)plaintextlen)) ||
511       !EVP_EncryptUpdate(actx, NULL, &len, aad, (int)aadlen) ||
512       !EVP_EncryptUpdate(actx, dest, &len, plaintext, (int)plaintextlen) ||
513       !EVP_EncryptFinal_ex(actx, dest + len, &len) ||
514 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
515       !EVP_CIPHER_CTX_get_params(actx, params)
516 #else  /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
517       !EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_GET_TAG, (int)taglen,
518                            dest + plaintextlen)
519 #endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
520   ) {
521     return -1;
522   }
523 
524   return 0;
525 }
526 
ngtcp2_crypto_decrypt(uint8_t * dest,const ngtcp2_crypto_aead * aead,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * ciphertext,size_t ciphertextlen,const uint8_t * nonce,size_t noncelen,const uint8_t * aad,size_t aadlen)527 int ngtcp2_crypto_decrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
528                           const ngtcp2_crypto_aead_ctx *aead_ctx,
529                           const uint8_t *ciphertext, size_t ciphertextlen,
530                           const uint8_t *nonce, size_t noncelen,
531                           const uint8_t *aad, size_t aadlen) {
532   const EVP_CIPHER *cipher = aead->native_handle;
533   size_t taglen = crypto_aead_max_overhead(cipher);
534   int cipher_nid = EVP_CIPHER_nid(cipher);
535   EVP_CIPHER_CTX *actx = aead_ctx->native_handle;
536   int len;
537   const uint8_t *tag;
538 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
539   OSSL_PARAM params[2];
540 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
541 
542   (void)noncelen;
543 
544   if (taglen > ciphertextlen) {
545     return -1;
546   }
547 
548   ciphertextlen -= taglen;
549   tag = ciphertext + ciphertextlen;
550 
551 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
552   params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
553                                                 (void *)tag, taglen);
554   params[1] = OSSL_PARAM_construct_end();
555 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
556 
557   if (!EVP_DecryptInit_ex(actx, NULL, NULL, NULL, nonce) ||
558 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
559       !EVP_CIPHER_CTX_set_params(actx, params) ||
560 #else  /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
561       !EVP_CIPHER_CTX_ctrl(actx, EVP_CTRL_AEAD_SET_TAG, (int)taglen,
562                            (uint8_t *)tag) ||
563 #endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
564       (cipher_nid == NID_aes_128_ccm &&
565        !EVP_DecryptUpdate(actx, NULL, &len, NULL, (int)ciphertextlen)) ||
566       !EVP_DecryptUpdate(actx, NULL, &len, aad, (int)aadlen) ||
567       !EVP_DecryptUpdate(actx, dest, &len, ciphertext, (int)ciphertextlen) ||
568       (cipher_nid != NID_aes_128_ccm &&
569        !EVP_DecryptFinal_ex(actx, dest + ciphertextlen, &len))) {
570     return -1;
571   }
572 
573   return 0;
574 }
575 
ngtcp2_crypto_hp_mask(uint8_t * dest,const ngtcp2_crypto_cipher * hp,const ngtcp2_crypto_cipher_ctx * hp_ctx,const uint8_t * sample)576 int ngtcp2_crypto_hp_mask(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
577                           const ngtcp2_crypto_cipher_ctx *hp_ctx,
578                           const uint8_t *sample) {
579   static const uint8_t PLAINTEXT[] = "\x00\x00\x00\x00\x00";
580   EVP_CIPHER_CTX *actx = hp_ctx->native_handle;
581   int len;
582 
583   (void)hp;
584 
585   if (!EVP_EncryptInit_ex(actx, NULL, NULL, NULL, sample) ||
586       !EVP_EncryptUpdate(actx, dest, &len, PLAINTEXT, sizeof(PLAINTEXT) - 1) ||
587       !EVP_EncryptFinal_ex(actx, dest + sizeof(PLAINTEXT) - 1, &len)) {
588     return -1;
589   }
590 
591   return 0;
592 }
593 
ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,const uint8_t * data,size_t datalen)594 int ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn,
595                                          ngtcp2_crypto_level crypto_level,
596                                          const uint8_t *data, size_t datalen) {
597   SSL *ssl = ngtcp2_conn_get_tls_native_handle(conn);
598   int rv;
599   int err;
600 
601   if (SSL_provide_quic_data(
602           ssl, ngtcp2_crypto_openssl_from_ngtcp2_crypto_level(crypto_level),
603           data, datalen) != 1) {
604     return -1;
605   }
606 
607   if (!ngtcp2_conn_get_handshake_completed(conn)) {
608     rv = SSL_do_handshake(ssl);
609     if (rv <= 0) {
610       err = SSL_get_error(ssl, rv);
611       switch (err) {
612       case SSL_ERROR_WANT_READ:
613       case SSL_ERROR_WANT_WRITE:
614         return 0;
615       case SSL_ERROR_WANT_CLIENT_HELLO_CB:
616         return NGTCP2_CRYPTO_OPENSSL_ERR_TLS_WANT_CLIENT_HELLO_CB;
617       case SSL_ERROR_WANT_X509_LOOKUP:
618         return NGTCP2_CRYPTO_OPENSSL_ERR_TLS_WANT_X509_LOOKUP;
619       case SSL_ERROR_SSL:
620         return -1;
621       default:
622         return -1;
623       }
624     }
625 
626     ngtcp2_conn_handshake_completed(conn);
627   }
628 
629   rv = SSL_process_quic_post_handshake(ssl);
630   if (rv != 1) {
631     err = SSL_get_error(ssl, rv);
632     switch (err) {
633     case SSL_ERROR_WANT_READ:
634     case SSL_ERROR_WANT_WRITE:
635       return 0;
636     case SSL_ERROR_SSL:
637     case SSL_ERROR_ZERO_RETURN:
638       return -1;
639     default:
640       return -1;
641     }
642   }
643 
644   return 0;
645 }
646 
ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn * conn,void * tls)647 int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls) {
648   SSL *ssl = tls;
649   ngtcp2_transport_params_type exttype =
650       ngtcp2_conn_is_server(conn)
651           ? NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO
652           : NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS;
653   const uint8_t *tp;
654   size_t tplen;
655   ngtcp2_transport_params params;
656   int rv;
657 
658   SSL_get_peer_quic_transport_params(ssl, &tp, &tplen);
659 
660   rv = ngtcp2_decode_transport_params(&params, exttype, tp, tplen);
661   if (rv != 0) {
662     ngtcp2_conn_set_tls_error(conn, rv);
663     return -1;
664   }
665 
666   rv = ngtcp2_conn_set_remote_transport_params(conn, &params);
667   if (rv != 0) {
668     ngtcp2_conn_set_tls_error(conn, rv);
669     return -1;
670   }
671 
672   return 0;
673 }
674 
ngtcp2_crypto_set_local_transport_params(void * tls,const uint8_t * buf,size_t len)675 int ngtcp2_crypto_set_local_transport_params(void *tls, const uint8_t *buf,
676                                              size_t len) {
677   if (SSL_set_quic_transport_params(tls, buf, len) != 1) {
678     return -1;
679   }
680 
681   return 0;
682 }
683 
ngtcp2_crypto_openssl_from_ossl_encryption_level(OSSL_ENCRYPTION_LEVEL ossl_level)684 ngtcp2_crypto_level ngtcp2_crypto_openssl_from_ossl_encryption_level(
685     OSSL_ENCRYPTION_LEVEL ossl_level) {
686   switch (ossl_level) {
687   case ssl_encryption_initial:
688     return NGTCP2_CRYPTO_LEVEL_INITIAL;
689   case ssl_encryption_early_data:
690     return NGTCP2_CRYPTO_LEVEL_EARLY;
691   case ssl_encryption_handshake:
692     return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
693   case ssl_encryption_application:
694     return NGTCP2_CRYPTO_LEVEL_APPLICATION;
695   default:
696     assert(0);
697     abort(); /* if NDEBUG is set */
698   }
699 }
700 
701 OSSL_ENCRYPTION_LEVEL
ngtcp2_crypto_openssl_from_ngtcp2_crypto_level(ngtcp2_crypto_level crypto_level)702 ngtcp2_crypto_openssl_from_ngtcp2_crypto_level(
703     ngtcp2_crypto_level crypto_level) {
704   switch (crypto_level) {
705   case NGTCP2_CRYPTO_LEVEL_INITIAL:
706     return ssl_encryption_initial;
707   case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
708     return ssl_encryption_handshake;
709   case NGTCP2_CRYPTO_LEVEL_APPLICATION:
710     return ssl_encryption_application;
711   case NGTCP2_CRYPTO_LEVEL_EARLY:
712     return ssl_encryption_early_data;
713   default:
714     assert(0);
715     abort(); /* if NDEBUG is set */
716   }
717 }
718 
ngtcp2_crypto_get_path_challenge_data_cb(ngtcp2_conn * conn,uint8_t * data,void * user_data)719 int ngtcp2_crypto_get_path_challenge_data_cb(ngtcp2_conn *conn, uint8_t *data,
720                                              void *user_data) {
721   (void)conn;
722   (void)user_data;
723 
724   if (RAND_bytes(data, NGTCP2_PATH_CHALLENGE_DATALEN) != 1) {
725     return NGTCP2_ERR_CALLBACK_FAILURE;
726   }
727 
728   return 0;
729 }
730 
ngtcp2_crypto_random(uint8_t * data,size_t datalen)731 int ngtcp2_crypto_random(uint8_t *data, size_t datalen) {
732   if (RAND_bytes(data, (int)datalen) != 1) {
733     return -1;
734   }
735 
736   return 0;
737 }
738