1 /*
2 * ngtcp2
3 *
4 * Copyright (c) 2020 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_gnutls.h>
33
34 #include <gnutls/gnutls.h>
35 #include <gnutls/crypto.h>
36 #include <string.h>
37
38 #include "shared.h"
39
ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead * aead)40 ngtcp2_crypto_aead *ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead *aead) {
41 return ngtcp2_crypto_aead_init(aead, (void *)GNUTLS_CIPHER_AES_128_GCM);
42 }
43
ngtcp2_crypto_md_sha256(ngtcp2_crypto_md * md)44 ngtcp2_crypto_md *ngtcp2_crypto_md_sha256(ngtcp2_crypto_md *md) {
45 md->native_handle = (void *)GNUTLS_DIG_SHA256;
46 return md;
47 }
48
ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx * ctx)49 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx *ctx) {
50 ngtcp2_crypto_aead_init(&ctx->aead, (void *)GNUTLS_CIPHER_AES_128_GCM);
51 ctx->md.native_handle = (void *)GNUTLS_DIG_SHA256;
52 ctx->hp.native_handle = (void *)GNUTLS_CIPHER_AES_128_CBC;
53 ctx->max_encryption = 0;
54 ctx->max_decryption_failure = 0;
55 return ctx;
56 }
57
ngtcp2_crypto_aead_init(ngtcp2_crypto_aead * aead,void * aead_native_handle)58 ngtcp2_crypto_aead *ngtcp2_crypto_aead_init(ngtcp2_crypto_aead *aead,
59 void *aead_native_handle) {
60 aead->native_handle = aead_native_handle;
61 aead->max_overhead = gnutls_cipher_get_tag_size(
62 (gnutls_cipher_algorithm_t)(intptr_t)aead_native_handle);
63 return aead;
64 }
65
ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead * aead)66 ngtcp2_crypto_aead *ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead *aead) {
67 return ngtcp2_crypto_aead_init(aead, (void *)GNUTLS_CIPHER_AES_128_GCM);
68 }
69
70 static gnutls_cipher_algorithm_t
crypto_get_hp(gnutls_cipher_algorithm_t cipher)71 crypto_get_hp(gnutls_cipher_algorithm_t cipher) {
72 switch (cipher) {
73 case GNUTLS_CIPHER_AES_128_GCM:
74 case GNUTLS_CIPHER_AES_128_CCM:
75 return GNUTLS_CIPHER_AES_128_CBC;
76 case GNUTLS_CIPHER_AES_256_GCM:
77 case GNUTLS_CIPHER_AES_256_CCM:
78 return GNUTLS_CIPHER_AES_256_CBC;
79 case GNUTLS_CIPHER_CHACHA20_POLY1305:
80 return GNUTLS_CIPHER_CHACHA20_32;
81 default:
82 return GNUTLS_CIPHER_UNKNOWN;
83 }
84 }
85
86 static uint64_t
crypto_get_aead_max_encryption(gnutls_cipher_algorithm_t cipher)87 crypto_get_aead_max_encryption(gnutls_cipher_algorithm_t cipher) {
88 switch (cipher) {
89 case GNUTLS_CIPHER_AES_128_GCM:
90 case GNUTLS_CIPHER_AES_256_GCM:
91 return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_GCM;
92 case GNUTLS_CIPHER_CHACHA20_POLY1305:
93 return NGTCP2_CRYPTO_MAX_ENCRYPTION_CHACHA20_POLY1305;
94 case GNUTLS_CIPHER_AES_128_CCM:
95 case GNUTLS_CIPHER_AES_256_CCM:
96 return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_CCM;
97 default:
98 return 0;
99 }
100 }
101
102 static uint64_t
crypto_get_aead_max_decryption_failure(gnutls_cipher_algorithm_t cipher)103 crypto_get_aead_max_decryption_failure(gnutls_cipher_algorithm_t cipher) {
104 switch (cipher) {
105 case GNUTLS_CIPHER_AES_128_GCM:
106 case GNUTLS_CIPHER_AES_256_GCM:
107 return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_GCM;
108 case GNUTLS_CIPHER_CHACHA20_POLY1305:
109 return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_CHACHA20_POLY1305;
110 case GNUTLS_CIPHER_AES_128_CCM:
111 case GNUTLS_CIPHER_AES_256_CCM:
112 return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_CCM;
113 default:
114 return 0;
115 }
116 }
117
ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx * ctx,void * tls_native_handle)118 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
119 void *tls_native_handle) {
120 gnutls_session_t session = tls_native_handle;
121 gnutls_cipher_algorithm_t cipher;
122 gnutls_digest_algorithm_t hash;
123 gnutls_cipher_algorithm_t hp_cipher;
124
125 cipher = gnutls_cipher_get(session);
126 if (cipher != GNUTLS_CIPHER_UNKNOWN && cipher != GNUTLS_CIPHER_NULL) {
127 ngtcp2_crypto_aead_init(&ctx->aead, (void *)cipher);
128 }
129
130 hash = gnutls_prf_hash_get(session);
131 if (hash != GNUTLS_DIG_UNKNOWN && hash != GNUTLS_DIG_NULL) {
132 ctx->md.native_handle = (void *)hash;
133 }
134
135 hp_cipher = crypto_get_hp(cipher);
136 if (hp_cipher != GNUTLS_CIPHER_UNKNOWN) {
137 ctx->hp.native_handle = (void *)hp_cipher;
138 }
139
140 ctx->max_encryption = crypto_get_aead_max_encryption(cipher);
141 ctx->max_decryption_failure = crypto_get_aead_max_decryption_failure(cipher);
142
143 return ctx;
144 }
145
ngtcp2_crypto_ctx_tls_early(ngtcp2_crypto_ctx * ctx,void * tls_native_handle)146 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls_early(ngtcp2_crypto_ctx *ctx,
147 void *tls_native_handle) {
148 gnutls_session_t session = tls_native_handle;
149 gnutls_cipher_algorithm_t cipher;
150 gnutls_digest_algorithm_t hash;
151 gnutls_cipher_algorithm_t hp_cipher;
152
153 cipher = gnutls_early_cipher_get(session);
154 if (cipher != GNUTLS_CIPHER_UNKNOWN && cipher != GNUTLS_CIPHER_NULL) {
155 ngtcp2_crypto_aead_init(&ctx->aead, (void *)cipher);
156 }
157
158 hash = gnutls_early_prf_hash_get(session);
159 if (hash != GNUTLS_DIG_UNKNOWN && hash != GNUTLS_DIG_NULL) {
160 ctx->md.native_handle = (void *)hash;
161 }
162
163 hp_cipher = crypto_get_hp(cipher);
164 if (hp_cipher != GNUTLS_CIPHER_UNKNOWN) {
165 ctx->hp.native_handle = (void *)hp_cipher;
166 }
167
168 ctx->max_encryption = crypto_get_aead_max_encryption(cipher);
169 ctx->max_decryption_failure = crypto_get_aead_max_decryption_failure(cipher);
170
171 return ctx;
172 }
173
ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md * md)174 size_t ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md *md) {
175 return gnutls_hash_get_len(
176 (gnutls_digest_algorithm_t)(intptr_t)md->native_handle);
177 }
178
ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead * aead)179 size_t ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead *aead) {
180 return gnutls_cipher_get_key_size(
181 (gnutls_cipher_algorithm_t)(intptr_t)aead->native_handle);
182 }
183
ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead * aead)184 size_t ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead *aead) {
185 return gnutls_cipher_get_iv_size(
186 (gnutls_cipher_algorithm_t)(intptr_t)aead->native_handle);
187 }
188
ngtcp2_crypto_aead_ctx_encrypt_init(ngtcp2_crypto_aead_ctx * aead_ctx,const ngtcp2_crypto_aead * aead,const uint8_t * key,size_t noncelen)189 int ngtcp2_crypto_aead_ctx_encrypt_init(ngtcp2_crypto_aead_ctx *aead_ctx,
190 const ngtcp2_crypto_aead *aead,
191 const uint8_t *key, size_t noncelen) {
192 gnutls_cipher_algorithm_t cipher =
193 (gnutls_cipher_algorithm_t)(intptr_t)aead->native_handle;
194 gnutls_aead_cipher_hd_t hd;
195 gnutls_datum_t _key;
196
197 (void)noncelen;
198
199 _key.data = (void *)key;
200 _key.size = (unsigned int)ngtcp2_crypto_aead_keylen(aead);
201
202 if (gnutls_aead_cipher_init(&hd, cipher, &_key) != 0) {
203 return -1;
204 }
205
206 aead_ctx->native_handle = hd;
207
208 return 0;
209 }
210
ngtcp2_crypto_aead_ctx_decrypt_init(ngtcp2_crypto_aead_ctx * aead_ctx,const ngtcp2_crypto_aead * aead,const uint8_t * key,size_t noncelen)211 int ngtcp2_crypto_aead_ctx_decrypt_init(ngtcp2_crypto_aead_ctx *aead_ctx,
212 const ngtcp2_crypto_aead *aead,
213 const uint8_t *key, size_t noncelen) {
214 gnutls_cipher_algorithm_t cipher =
215 (gnutls_cipher_algorithm_t)(intptr_t)aead->native_handle;
216 gnutls_aead_cipher_hd_t hd;
217 gnutls_datum_t _key;
218
219 (void)noncelen;
220
221 _key.data = (void *)key;
222 _key.size = (unsigned int)ngtcp2_crypto_aead_keylen(aead);
223
224 if (gnutls_aead_cipher_init(&hd, cipher, &_key) != 0) {
225 return -1;
226 }
227
228 aead_ctx->native_handle = hd;
229
230 return 0;
231 }
232
ngtcp2_crypto_aead_ctx_free(ngtcp2_crypto_aead_ctx * aead_ctx)233 void ngtcp2_crypto_aead_ctx_free(ngtcp2_crypto_aead_ctx *aead_ctx) {
234 if (aead_ctx->native_handle) {
235 gnutls_aead_cipher_deinit(aead_ctx->native_handle);
236 }
237 }
238
ngtcp2_crypto_cipher_ctx_encrypt_init(ngtcp2_crypto_cipher_ctx * cipher_ctx,const ngtcp2_crypto_cipher * cipher,const uint8_t * key)239 int ngtcp2_crypto_cipher_ctx_encrypt_init(ngtcp2_crypto_cipher_ctx *cipher_ctx,
240 const ngtcp2_crypto_cipher *cipher,
241 const uint8_t *key) {
242 gnutls_cipher_algorithm_t _cipher =
243 (gnutls_cipher_algorithm_t)(intptr_t)cipher->native_handle;
244 gnutls_cipher_hd_t hd;
245 gnutls_datum_t _key;
246
247 _key.data = (void *)key;
248 _key.size = (unsigned int)gnutls_cipher_get_key_size(_cipher);
249
250 if (gnutls_cipher_init(&hd, _cipher, &_key, NULL) != 0) {
251 return -1;
252 }
253
254 cipher_ctx->native_handle = hd;
255
256 return 0;
257 }
258
ngtcp2_crypto_cipher_ctx_free(ngtcp2_crypto_cipher_ctx * cipher_ctx)259 void ngtcp2_crypto_cipher_ctx_free(ngtcp2_crypto_cipher_ctx *cipher_ctx) {
260 if (cipher_ctx->native_handle) {
261 gnutls_cipher_deinit(cipher_ctx->native_handle);
262 }
263 }
264
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)265 int ngtcp2_crypto_hkdf_extract(uint8_t *dest, const ngtcp2_crypto_md *md,
266 const uint8_t *secret, size_t secretlen,
267 const uint8_t *salt, size_t saltlen) {
268 gnutls_mac_algorithm_t prf =
269 (gnutls_mac_algorithm_t)(intptr_t)md->native_handle;
270 gnutls_datum_t _secret = {(void *)secret, (unsigned int)secretlen};
271 gnutls_datum_t _salt = {(void *)salt, (unsigned int)saltlen};
272
273 if (gnutls_hkdf_extract(prf, &_secret, &_salt, dest) != 0) {
274 return -1;
275 }
276
277 return 0;
278 }
279
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)280 int ngtcp2_crypto_hkdf_expand(uint8_t *dest, size_t destlen,
281 const ngtcp2_crypto_md *md, const uint8_t *secret,
282 size_t secretlen, const uint8_t *info,
283 size_t infolen) {
284 gnutls_mac_algorithm_t prf =
285 (gnutls_mac_algorithm_t)(intptr_t)md->native_handle;
286 gnutls_datum_t _secret = {(void *)secret, (unsigned int)secretlen};
287 gnutls_datum_t _info = {(void *)info, (unsigned int)infolen};
288
289 if (gnutls_hkdf_expand(prf, &_secret, &_info, dest, destlen) != 0) {
290 return -1;
291 }
292
293 return 0;
294 }
295
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)296 int ngtcp2_crypto_hkdf(uint8_t *dest, size_t destlen,
297 const ngtcp2_crypto_md *md, const uint8_t *secret,
298 size_t secretlen, const uint8_t *salt, size_t saltlen,
299 const uint8_t *info, size_t infolen) {
300 gnutls_mac_algorithm_t prf =
301 (gnutls_mac_algorithm_t)(intptr_t)md->native_handle;
302 size_t keylen = ngtcp2_crypto_md_hashlen(md);
303 uint8_t key[64];
304 gnutls_datum_t _secret = {(void *)secret, (unsigned int)secretlen};
305 gnutls_datum_t _key = {(void *)key, (unsigned int)keylen};
306 gnutls_datum_t _salt = {(void *)salt, (unsigned int)saltlen};
307 gnutls_datum_t _info = {(void *)info, (unsigned int)infolen};
308
309 assert(keylen <= sizeof(key));
310
311 if (gnutls_hkdf_extract(prf, &_secret, &_salt, key) != 0) {
312 return -1;
313 }
314
315 if (gnutls_hkdf_expand(prf, &_key, &_info, dest, destlen) != 0) {
316 return -1;
317 }
318
319 return 0;
320 }
321
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)322 int ngtcp2_crypto_encrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
323 const ngtcp2_crypto_aead_ctx *aead_ctx,
324 const uint8_t *plaintext, size_t plaintextlen,
325 const uint8_t *nonce, size_t noncelen,
326 const uint8_t *aad, size_t aadlen) {
327 gnutls_cipher_algorithm_t cipher =
328 (gnutls_cipher_algorithm_t)(intptr_t)aead->native_handle;
329 gnutls_aead_cipher_hd_t hd = aead_ctx->native_handle;
330 size_t taglen = gnutls_cipher_get_tag_size(cipher);
331 size_t ciphertextlen = plaintextlen + taglen;
332
333 if (gnutls_aead_cipher_encrypt(hd, nonce, noncelen, aad, aadlen, taglen,
334 plaintext, plaintextlen, dest,
335 &ciphertextlen) != 0) {
336 return -1;
337 }
338
339 return 0;
340 }
341
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)342 int ngtcp2_crypto_decrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
343 const ngtcp2_crypto_aead_ctx *aead_ctx,
344 const uint8_t *ciphertext, size_t ciphertextlen,
345 const uint8_t *nonce, size_t noncelen,
346 const uint8_t *aad, size_t aadlen) {
347 gnutls_cipher_algorithm_t cipher =
348 (gnutls_cipher_algorithm_t)(intptr_t)aead->native_handle;
349 gnutls_aead_cipher_hd_t hd = aead_ctx->native_handle;
350 size_t taglen = gnutls_cipher_get_tag_size(cipher);
351 size_t plaintextlen;
352
353 if (taglen > ciphertextlen) {
354 return -1;
355 }
356
357 plaintextlen = ciphertextlen - taglen;
358
359 if (gnutls_aead_cipher_decrypt(hd, nonce, noncelen, aad, aadlen, taglen,
360 ciphertext, ciphertextlen, dest,
361 &plaintextlen) != 0) {
362 return -1;
363 }
364
365 return 0;
366 }
367
ngtcp2_crypto_hp_mask(uint8_t * dest,const ngtcp2_crypto_cipher * hp,const ngtcp2_crypto_cipher_ctx * hp_ctx,const uint8_t * sample)368 int ngtcp2_crypto_hp_mask(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
369 const ngtcp2_crypto_cipher_ctx *hp_ctx,
370 const uint8_t *sample) {
371 gnutls_cipher_algorithm_t cipher =
372 (gnutls_cipher_algorithm_t)(intptr_t)hp->native_handle;
373 gnutls_cipher_hd_t hd = hp_ctx->native_handle;
374
375 switch (cipher) {
376 case GNUTLS_CIPHER_AES_128_CBC:
377 case GNUTLS_CIPHER_AES_256_CBC: {
378 uint8_t iv[16];
379 uint8_t buf[16];
380
381 /* Emulate one block AES-ECB by invalidating the effect of IV */
382 memset(iv, 0, sizeof(iv));
383
384 gnutls_cipher_set_iv(hd, iv, sizeof(iv));
385
386 if (gnutls_cipher_encrypt2(hd, sample, 16, buf, sizeof(buf)) != 0) {
387 return -1;
388 }
389
390 memcpy(dest, buf, 5);
391 } break;
392
393 case GNUTLS_CIPHER_CHACHA20_32: {
394 static const uint8_t PLAINTEXT[] = "\x00\x00\x00\x00\x00";
395 uint8_t buf[5 + 16];
396 size_t buflen = sizeof(buf);
397
398 gnutls_cipher_set_iv(hd, (void *)sample, 16);
399
400 if (gnutls_cipher_encrypt2(hd, PLAINTEXT, sizeof(PLAINTEXT) - 1, buf,
401 buflen) != 0) {
402 return -1;
403 }
404
405 memcpy(dest, buf, 5);
406 } break;
407 default:
408 assert(0);
409 }
410
411 return 0;
412 }
413
ngtcp2_crypto_gnutls_from_gnutls_record_encryption_level(gnutls_record_encryption_level_t gtls_level)414 ngtcp2_crypto_level ngtcp2_crypto_gnutls_from_gnutls_record_encryption_level(
415 gnutls_record_encryption_level_t gtls_level) {
416 switch (gtls_level) {
417 case GNUTLS_ENCRYPTION_LEVEL_INITIAL:
418 return NGTCP2_CRYPTO_LEVEL_INITIAL;
419 case GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE:
420 return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
421 case GNUTLS_ENCRYPTION_LEVEL_APPLICATION:
422 return NGTCP2_CRYPTO_LEVEL_APPLICATION;
423 case GNUTLS_ENCRYPTION_LEVEL_EARLY:
424 return NGTCP2_CRYPTO_LEVEL_EARLY;
425 default:
426 assert(0);
427 abort();
428 }
429 }
430
431 gnutls_record_encryption_level_t
ngtcp2_crypto_gnutls_from_ngtcp2_level(ngtcp2_crypto_level crypto_level)432 ngtcp2_crypto_gnutls_from_ngtcp2_level(ngtcp2_crypto_level crypto_level) {
433 switch (crypto_level) {
434 case NGTCP2_CRYPTO_LEVEL_INITIAL:
435 return GNUTLS_ENCRYPTION_LEVEL_INITIAL;
436 case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
437 return GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE;
438 case NGTCP2_CRYPTO_LEVEL_APPLICATION:
439 return GNUTLS_ENCRYPTION_LEVEL_APPLICATION;
440 case NGTCP2_CRYPTO_LEVEL_EARLY:
441 return GNUTLS_ENCRYPTION_LEVEL_EARLY;
442 default:
443 assert(0);
444 abort();
445 }
446 }
447
ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,const uint8_t * data,size_t datalen)448 int ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn,
449 ngtcp2_crypto_level crypto_level,
450 const uint8_t *data, size_t datalen) {
451 gnutls_session_t session = ngtcp2_conn_get_tls_native_handle(conn);
452 int rv;
453
454 if (datalen > 0) {
455 if (gnutls_handshake_write(
456 session, ngtcp2_crypto_gnutls_from_ngtcp2_level(crypto_level), data,
457 datalen) != 0) {
458 return -1;
459 }
460 }
461
462 if (!ngtcp2_conn_get_handshake_completed(conn)) {
463 rv = gnutls_handshake(session);
464 if (rv < 0) {
465 if (!gnutls_error_is_fatal(rv)) {
466 return 0;
467 }
468 gnutls_alert_send_appropriate(session, rv);
469 return -1;
470 }
471
472 ngtcp2_conn_handshake_completed(conn);
473 }
474
475 return 0;
476 }
477
ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn * conn,void * tls)478 int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls) {
479 (void)conn;
480 (void)tls;
481 /* Nothing to do; GnuTLS applications are supposed to register the
482 quic_transport_parameters extension with
483 gnutls_session_ext_register. */
484 return 0;
485 }
486
ngtcp2_crypto_set_local_transport_params(void * tls,const uint8_t * buf,size_t len)487 int ngtcp2_crypto_set_local_transport_params(void *tls, const uint8_t *buf,
488 size_t len) {
489 (void)tls;
490 (void)buf;
491 (void)len;
492 /* Nothing to do; GnuTLS applications are supposed to register the
493 quic_transport_parameters extension with
494 gnutls_session_ext_register. */
495 return 0;
496 }
497
ngtcp2_crypto_get_path_challenge_data_cb(ngtcp2_conn * conn,uint8_t * data,void * user_data)498 int ngtcp2_crypto_get_path_challenge_data_cb(ngtcp2_conn *conn, uint8_t *data,
499 void *user_data) {
500 (void)conn;
501 (void)user_data;
502
503 if (gnutls_rnd(GNUTLS_RND_RANDOM, data, NGTCP2_PATH_CHALLENGE_DATALEN) != 0) {
504 return NGTCP2_ERR_CALLBACK_FAILURE;
505 }
506
507 return 0;
508 }
509
ngtcp2_crypto_random(uint8_t * data,size_t datalen)510 int ngtcp2_crypto_random(uint8_t *data, size_t datalen) {
511 if (gnutls_rnd(GNUTLS_RND_RANDOM, data, datalen) != 0) {
512 return -1;
513 }
514
515 return 0;
516 }
517