22 #include <picotls/openssl.h> 24 #define QUICLY_EPOCH_1RTT 3 30 const void *, size_t);
48 ptls_aead_context_t * _ctx,
void *_output,
49 const void *input,
size_t inlen,
50 uint64_t decrypted_pn,
const void *aad,
96 size_t iv_size = ctx->algo->iv_size,
i;
97 const uint8_t *s = ctx->static_iv;
100 for (
i = iv_size - 8;
i != 0; --
i)
106 *d++ = *s++ ^ (uint8_t) (seq >>
i);
113 quicly_datagram_t *
packet,
114 size_t first_byte_at,
size_t payload_from)
116 uint8_t hpmask[1 + QUICLY_SEND_PN_SIZE] = {
121 ptls_cipher_init (hp,
122 packet->data.base + payload_from - QUICLY_SEND_PN_SIZE +
124 ptls_cipher_encrypt (hp, hpmask, hpmask,
sizeof (hpmask));
126 packet->data.base[first_byte_at] ^=
128 (QUICLY_PACKET_IS_LONG_HEADER (packet->data.base[first_byte_at]) ? 0xf :
131 for (i = 0; i != QUICLY_SEND_PN_SIZE; ++
i)
132 packet->data.base[payload_from + i - QUICLY_SEND_PN_SIZE] ^=
154 quicly_conn_t * conn,
size_t epoch,
int is_enc,
155 ptls_cipher_context_t ** hp_ctx,
156 ptls_aead_context_t ** aead_ctx,
157 ptls_aead_algorithm_t * aead,
158 ptls_hash_algorithm_t * hash,
const void *secret)
160 uint8_t hpkey[PTLS_MAX_SECRET_SIZE];
168 ret = ptls_hkdf_expand_label (hash, hpkey, aead->ctr_cipher->key_size,
169 ptls_iovec_init (secret,
171 "quic hp", ptls_iovec_init (NULL, 0),
175 *hp_ctx = ptls_cipher_new (aead->ctr_cipher, is_enc, hpkey);
178 ret = PTLS_ERROR_NO_MEMORY;
184 *aead_ctx = ptls_aead_new (aead, hash, is_enc, secret,
185 QUICLY_AEAD_BASE_LABEL);
186 if (NULL == *aead_ctx)
188 ret = PTLS_ERROR_NO_MEMORY;
208 if (*aead_ctx != NULL)
210 ptls_aead_free (*aead_ctx);
213 if (hp_ctx && *hp_ctx != NULL)
215 ptls_cipher_free (*hp_ctx);
219 ptls_clear_memory (hpkey,
sizeof (hpkey));
225 *engine, quicly_conn_t * conn,
226 ptls_cipher_context_t * hp,
227 ptls_aead_context_t * aead,
228 quicly_datagram_t *
packet,
229 size_t first_byte_at,
230 size_t payload_from,
int coalesced)
246 ptls_cipher_context_t *header_protection = NULL;
247 ptls_aead_context_t *aead = NULL;
251 if (QUICLY_PACKET_IS_LONG_HEADER (pctx->
packet.octets.base[0]))
254 uint64_t next_expected_packet_number =
255 quicly_get_next_expected_packet_number (qctx->
conn);
256 if (next_expected_packet_number == UINT64_MAX)
262 if (!aead || !header_protection)
265 size_t encrypted_len = pctx->
packet.octets.len - pctx->
packet.encrypted_off;
266 uint8_t hpmask[5] = { 0 };
268 size_t pnlen, ptlen,
i;
271 if (encrypted_len < header_protection->algo->iv_size + QUICLY_MAX_PN_SIZE)
273 ptls_cipher_init (header_protection,
276 ptls_cipher_encrypt (header_protection, hpmask, hpmask,
sizeof (hpmask));
277 pctx->
packet.octets.base[0] ^=
278 hpmask[0] & (QUICLY_PACKET_IS_LONG_HEADER (pctx->
packet.octets.base[0]) ?
280 pnlen = (pctx->
packet.octets.base[0] & 0x3) + 1;
281 for (i = 0; i != pnlen; ++
i)
286 (pnbits << 8) | pctx->
packet.octets.base[pctx->
packet.encrypted_off +
290 size_t aead_off = pctx->
packet.encrypted_off + pnlen;
293 quicly_determine_packet_number (pnbits, pnlen * 8,
294 next_expected_packet_number);
297 (pctx->
packet.octets.base[0] & QUICLY_KEY_PHASE_BIT) != 0;
301 pctx->
packet.octets.base[0] ^=
303 (QUICLY_PACKET_IS_LONG_HEADER (pctx->
packet.octets.base[0]) ? 0xf :
305 for (i = 0; i != pnlen; ++
i)
315 pctx->
packet.octets.base + aead_off,
316 pctx->
packet.octets.base + aead_off,
317 pctx->
packet.octets.len - aead_off,
318 pn, pctx->
packet.octets.base,
319 aead_off)) == SIZE_MAX)
322 "%s: aead decryption failure (pn: %d)\n", __FUNCTION__, pn);
326 pctx->
packet.encrypted_off = aead_off;
327 pctx->
packet.octets.len = ptlen + aead_off;
329 pctx->
packet.decrypted.pn = pn;
333 #ifdef QUIC_HP_CRYPTO 335 quic_crypto_cipher_do_init (ptls_cipher_context_t * _ctx,
const void *
iv)
339 if (!strcmp (ctx->
super.algo->name,
"AES128-CTR"))
341 id = VNET_CRYPTO_OP_AES_128_CTR_ENC;
343 else if (!strcmp (ctx->
super.algo->name,
"AES256-CTR"))
345 id = VNET_CRYPTO_OP_AES_256_CTR_ENC;
349 QUIC_DBG (1,
"%s, Invalid crypto cipher : ", __FUNCTION__,
359 quic_crypto_cipher_dispose (ptls_cipher_context_t * _ctx)
365 quic_crypto_cipher_encrypt (ptls_cipher_context_t * _ctx,
void *output,
366 const void *input,
size_t _len)
372 ctx->
op.
dst = output;
379 quic_crypto_cipher_setup_crypto (ptls_cipher_context_t * _ctx,
int is_enc,
380 const void *
key,
const EVP_CIPHER * cipher,
385 ctx->
super.do_dispose = quic_crypto_cipher_dispose;
386 ctx->
super.do_init = quic_crypto_cipher_do_init;
387 ctx->
super.do_transform = do_transform;
391 if (!strcmp (ctx->
super.algo->name,
"AES128-CTR"))
393 algo = VNET_CRYPTO_ALG_AES_128_CTR;
395 else if (!strcmp (ctx->
super.algo->name,
"AES256-CTR"))
397 algo = VNET_CRYPTO_ALG_AES_256_CTR;
401 QUIC_DBG (1,
"%s, Invalid crypto cipher : ", __FUNCTION__,
407 (
u8 *) key, _ctx->algo->key_size);
413 quic_crypto_aes128ctr_setup_crypto (ptls_cipher_context_t *
ctx,
int is_enc,
416 return quic_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_128_ctr (),
417 quic_crypto_cipher_encrypt);
421 quic_crypto_aes256ctr_setup_crypto (ptls_cipher_context_t * ctx,
int is_enc,
424 return quic_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_256_ctr (),
425 quic_crypto_cipher_encrypt);
428 #endif // QUIC_HP_CRYPTO 432 const void *aad,
size_t aadlen)
440 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
442 id = VNET_CRYPTO_OP_AES_128_GCM_ENC;
444 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
446 id = VNET_CRYPTO_OP_AES_256_GCM_ENC;
460 vnet_op->
aad = (
u8 *) aad;
469 const void *input,
size_t inlen)
481 vnet_op->
src = (
u8 *) input;
482 vnet_op->
dst = output;
483 vnet_op->
len = inlen;
486 vnet_op->
tag = vnet_op->
src + inlen;
500 &quic_crypto_batch_ctx->
501 aead_crypto_tx_packets_ops[quic_crypto_batch_ctx->
nb_tx_packets];
508 const void *input,
size_t inlen,
const void *iv,
509 const void *aad,
size_t aadlen)
515 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
517 id = VNET_CRYPTO_OP_AES_128_GCM_DEC;
519 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
521 id = VNET_CRYPTO_OP_AES_256_GCM_DEC;
534 ctx->
op.
dst = _output;
536 ctx->
op.
len = inlen - ctx->
super.algo->tag_size;
543 if (ctx->
op.
status != VNET_CRYPTO_OP_STATUS_COMPLETED)
551 ptls_aead_context_t * _ctx,
void *_output,
552 const void *input,
size_t inlen,
553 uint64_t decrypted_pn,
const void *aad,
558 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
560 id = VNET_CRYPTO_OP_AES_128_GCM_DEC;
562 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
564 id = VNET_CRYPTO_OP_AES_256_GCM_DEC;
580 vnet_op->
aad = (
u8 *) aad;
584 vnet_op->
src = (
u8 *) input;
585 vnet_op->
dst = _output;
587 vnet_op->
len = inlen - ctx->
super.algo->tag_size;
589 vnet_op->
tag = vnet_op->
src + vnet_op->
len;
602 const void *key,
const EVP_CIPHER * cipher)
608 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
610 algo = VNET_CRYPTO_ALG_AES_128_GCM;
612 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
614 algo = VNET_CRYPTO_ALG_AES_256_GCM;
618 QUIC_DBG (1,
"%s, invalied aead cipher %s", __FUNCTION__,
634 (
u8 *) key, _ctx->algo->key_size);
639 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
640 ptls_openssl_aes128gcm.setup_crypto (_ctx, is_enc, key);
641 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
642 ptls_openssl_aes256gcm.setup_crypto (_ctx, is_enc, key);
650 int is_enc,
const void *key)
657 int is_enc,
const void *key)
662 #ifdef QUIC_HP_CRYPTO 663 ptls_cipher_algorithm_t quic_crypto_aes128ctr = {
665 PTLS_AES128_KEY_SIZE,
670 ptls_cipher_algorithm_t quic_crypto_aes256ctr = {
671 "AES256-CTR", PTLS_AES256_KEY_SIZE, 1 ,
676 ptls_aead_algorithm_t quic_crypto_aes128gcm = {
678 #ifdef QUIC_HP_CRYPTO 679 &quic_crypto_aes128ctr,
681 &ptls_openssl_aes128ctr,
683 &ptls_openssl_aes128ecb,
684 PTLS_AES128_KEY_SIZE,
686 PTLS_AESGCM_TAG_SIZE,
688 quic_crypto_aead_aes128gcm_setup_crypto
691 ptls_aead_algorithm_t quic_crypto_aes256gcm = {
693 #ifdef QUIC_HP_CRYPTO 694 &quic_crypto_aes256ctr,
696 &ptls_openssl_aes256ctr,
698 &ptls_openssl_aes256ecb,
699 PTLS_AES256_KEY_SIZE,
701 PTLS_AESGCM_TAG_SIZE,
703 quic_crypto_aead_aes256gcm_setup_crypto
706 ptls_cipher_suite_t quic_crypto_aes128gcmsha256 = {
707 PTLS_CIPHER_SUITE_AES_128_GCM_SHA256,
711 ptls_cipher_suite_t quic_crypto_aes256gcmsha384 = {
712 PTLS_CIPHER_SUITE_AES_256_GCM_SHA384,
716 ptls_cipher_suite_t *quic_crypto_cipher_suites[] = {
720 quicly_crypto_engine_t quic_crypto_engine = {
726 int is_encrypt, ptls_buffer_t *
dst, ptls_iovec_t
src)
737 return PTLS_ERROR_NO_MEMORY;
739 ptls_get_context (tls)->random_bytes (self->id, sizeof (self->id));
741 self->data.len = src.len;
744 if ((ret = ptls_buffer_reserve (dst,
sizeof (self->id))) != 0)
746 clib_memcpy (dst->base + dst->off, self->id, sizeof (self->id));
747 dst->off +=
sizeof (
self->id);
754 if (src.len != sizeof (self->id))
755 return PTLS_ERROR_SESSION_NOT_FOUND;
756 if (
clib_memcmp (self->id, src.base, sizeof (self->id)) != 0)
757 return PTLS_ERROR_SESSION_NOT_FOUND;
760 if ((ret = ptls_buffer_reserve (dst, self->data.len)) != 0)
762 clib_memcpy (dst->base + dst->off, self->data.base, self->data.len);
763 dst->off +=
self->data.len;
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
static void clib_rwlock_reader_lock(clib_rwlock_t *p)
ptls_cipher_context_t super
quic_worker_ctx_t * wrk_ctx
static void clib_rwlock_writer_lock(clib_rwlock_t *p)
static void do_finalize_send_packet(ptls_cipher_context_t *hp, quicly_datagram_t *packet, size_t first_byte_at, size_t payload_from)
ptls_cipher_context_t * hp_ctx
size_t quic_crypto_aead_decrypt(ptls_aead_context_t *_ctx, void *_output, const void *input, size_t inlen, const void *iv, const void *aad, size_t aadlen)
#define QUIC_DBG(_lvl, _fmt, _args...)
size_t quic_crypto_aead_encrypt_update(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen)
#define clib_memcpy(d, s, n)
clib_rwlock_t crypto_keys_quic_rw_lock
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
struct quic_ctx_::@710 ingress_keys
size_t quic_crypto_aead_encrypt_final(ptls_aead_context_t *_ctx, void *output)
static int quic_crypto_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key, const EVP_CIPHER *cipher)
static size_t quic_crypto_offload_aead_decrypt(quic_ctx_t *qctx, ptls_aead_context_t *_ctx, void *_output, const void *input, size_t inlen, uint64_t decrypted_pn, const void *aad, size_t aadlen)
ptls_cipher_context_t * hp
struct quic_encrypt_cb_ctx_::quic_finalize_send_packet_cb_ctx_ snd_ctx[QUIC_MAX_COALESCED_PACKET]
static int quic_crypto_aead_aes256gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key)
vnet_crypto_op_t aead_crypto_rx_packets_ops[QUIC_RCV_MAX_BATCH_PACKETS]
u32 vnet_crypto_key_add(vlib_main_t *vm, vnet_crypto_alg_t alg, u8 *data, u16 length)
ptls_cipher_suite_t quic_crypto_aes256gcmsha384
static void clib_rwlock_reader_unlock(clib_rwlock_t *p)
void quic_crypto_batch_rx_packets(quic_crypto_batch_ctx_t *batch_ctx)
description malformed packet
void quic_crypto_aead_encrypt_init(ptls_aead_context_t *_ctx, const void *iv, const void *aad, size_t aadlen)
static int quic_crypto_aead_aes128gcm_setup_crypto(ptls_aead_context_t *ctx, int is_enc, const void *key)
static void clib_rwlock_writer_unlock(clib_rwlock_t *p)
quicly_conn_t * conn
QUIC ctx case.
static_always_inline uword vlib_get_thread_index(void)
#define clib_memcmp(s1, s2, m1)
sll srl srl sll sra u16x4 i
void(* quicly_do_transform_fn)(ptls_cipher_context_t *, void *, const void *, size_t)
void quic_crypto_decrypt_packet(quic_ctx_t *qctx, quic_rx_packet_ctx_t *pctx)
ptls_cipher_suite_t quic_crypto_aes128gcmsha256
static void clib_mem_free(void *p)
#define QUICLY_EPOCH_1RTT
static void * clib_mem_alloc(uword size)
static vlib_main_t * vlib_get_main(void)
vnet_crypto_op_t aead_crypto_tx_packets_ops[QUIC_SEND_MAX_BATCH_PACKETS]
static void quic_crypto_aead_dispose_crypto(ptls_aead_context_t *_ctx)
void quic_crypto_batch_tx_packets(quic_crypto_batch_ctx_t *batch_ctx)
ptls_aead_context_t * aead_ctx
quicly_decoded_packet_t packet
ptls_aead_algorithm_t quic_crypto_aes256gcm
ptls_aead_context_t super
void quic_crypto_finalize_send_packet_cb(struct st_quicly_crypto_engine_t *engine, quicly_conn_t *conn, ptls_cipher_context_t *hp, ptls_aead_context_t *aead, quicly_datagram_t *packet, size_t first_byte_at, size_t payload_from, int coalesced)
vnet_crypto_op_status_t status
static int quic_crypto_setup_cipher(quicly_crypto_engine_t *engine, quicly_conn_t *conn, size_t epoch, int is_enc, ptls_cipher_context_t **hp_ctx, ptls_aead_context_t **aead_ctx, ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash, const void *secret)
void build_iv(ptls_aead_context_t *ctx, uint8_t *iv, uint64_t seq)
quic_crypto_batch_ctx_t crypto_context_batch
void quic_crypto_finalize_send_packet(quicly_datagram_t *packet)
int quic_encrypt_ticket_cb(ptls_encrypt_ticket_t *_self, ptls_t *tls, int is_encrypt, ptls_buffer_t *dst, ptls_iovec_t src)
vnet_crypto_main_t crypto_main
ptls_aead_algorithm_t quic_crypto_aes128gcm
quic_ctx_t * quic_get_conn_ctx(quicly_conn_t *conn)