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];
170 ptls_hkdf_expand_label (hash, hpkey, aead->ctr_cipher->key_size,
171 ptls_iovec_init (secret,
173 "quic hp", ptls_iovec_init (NULL, 0),
177 ptls_cipher_new (aead->ctr_cipher, is_enc, hpkey)) == NULL)
179 ret = PTLS_ERROR_NO_MEMORY;
186 ptls_aead_new (aead, hash, is_enc, secret,
187 QUICLY_AEAD_BASE_LABEL)) == NULL)
189 ret = PTLS_ERROR_NO_MEMORY;
211 if (aead_ctx && *aead_ctx != NULL)
213 ptls_aead_free (*aead_ctx);
216 if (hp_ctx && *hp_ctx != NULL)
218 ptls_cipher_free (*hp_ctx);
222 ptls_clear_memory (hpkey,
sizeof (hpkey));
228 *engine, quicly_conn_t * conn,
229 ptls_cipher_context_t * hp,
230 ptls_aead_context_t * aead,
231 quicly_datagram_t * packet,
232 size_t first_byte_at,
233 size_t payload_from,
int coalesced)
249 ptls_cipher_context_t *header_protection = NULL;
250 ptls_aead_context_t *aead = NULL;
254 if (QUICLY_PACKET_IS_LONG_HEADER (pctx->
packet.octets.base[0]))
257 uint64_t next_expected_packet_number =
258 quicly_get_next_expected_packet_number (qctx->
conn);
259 if (next_expected_packet_number == UINT64_MAX)
265 if (!aead || !header_protection)
268 size_t encrypted_len = pctx->
packet.octets.len - pctx->
packet.encrypted_off;
269 uint8_t hpmask[5] = { 0 };
271 size_t pnlen, ptlen,
i;
274 if (encrypted_len < header_protection->algo->iv_size + QUICLY_MAX_PN_SIZE)
276 ptls_cipher_init (header_protection,
279 ptls_cipher_encrypt (header_protection, hpmask, hpmask,
sizeof (hpmask));
280 pctx->
packet.octets.base[0] ^=
281 hpmask[0] & (QUICLY_PACKET_IS_LONG_HEADER (pctx->
packet.octets.base[0]) ?
283 pnlen = (pctx->
packet.octets.base[0] & 0x3) + 1;
284 for (i = 0; i != pnlen; ++
i)
289 (pnbits << 8) | pctx->
packet.octets.base[pctx->
packet.encrypted_off +
293 size_t aead_off = pctx->
packet.encrypted_off + pnlen;
296 quicly_determine_packet_number (pnbits, pnlen * 8,
297 next_expected_packet_number);
300 (pctx->
packet.octets.base[0] & QUICLY_KEY_PHASE_BIT) != 0;
304 pctx->
packet.octets.base[0] ^=
306 (QUICLY_PACKET_IS_LONG_HEADER (pctx->
packet.octets.base[0]) ? 0xf :
308 for (i = 0; i != pnlen; ++
i)
318 pctx->
packet.octets.base + aead_off,
319 pctx->
packet.octets.base + aead_off,
320 pctx->
packet.octets.len - aead_off,
321 pn, pctx->
packet.octets.base,
322 aead_off)) == SIZE_MAX)
325 "%s: aead decryption failure (pn: %d)\n", __FUNCTION__, pn);
329 pctx->
packet.encrypted_off = aead_off;
330 pctx->
packet.octets.len = ptlen + aead_off;
332 pctx->
packet.decrypted.pn = pn;
336 #ifdef QUIC_HP_CRYPTO 338 quic_crypto_cipher_do_init (ptls_cipher_context_t * _ctx,
const void *
iv)
342 if (!strcmp (ctx->
super.algo->name,
"AES128-CTR"))
344 id = VNET_CRYPTO_OP_AES_128_CTR_ENC;
346 else if (!strcmp (ctx->
super.algo->name,
"AES256-CTR"))
348 id = VNET_CRYPTO_OP_AES_256_CTR_ENC;
352 QUIC_DBG (1,
"%s, Invalid crypto cipher : ", __FUNCTION__,
362 quic_crypto_cipher_dispose (ptls_cipher_context_t * _ctx)
368 quic_crypto_cipher_encrypt (ptls_cipher_context_t * _ctx,
void *output,
369 const void *input,
size_t _len)
375 ctx->
op.
dst = output;
382 quic_crypto_cipher_setup_crypto (ptls_cipher_context_t * _ctx,
int is_enc,
383 const void *
key,
const EVP_CIPHER * cipher,
388 ctx->
super.do_dispose = quic_crypto_cipher_dispose;
389 ctx->
super.do_init = quic_crypto_cipher_do_init;
390 ctx->
super.do_transform = do_transform;
394 if (!strcmp (ctx->
super.algo->name,
"AES128-CTR"))
396 algo = VNET_CRYPTO_ALG_AES_128_CTR;
398 else if (!strcmp (ctx->
super.algo->name,
"AES256-CTR"))
400 algo = VNET_CRYPTO_ALG_AES_256_CTR;
404 QUIC_DBG (1,
"%s, Invalid crypto cipher : ", __FUNCTION__,
410 (
u8 *) key, _ctx->algo->key_size);
416 quic_crypto_aes128ctr_setup_crypto (ptls_cipher_context_t *
ctx,
int is_enc,
419 return quic_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_128_ctr (),
420 quic_crypto_cipher_encrypt);
424 quic_crypto_aes256ctr_setup_crypto (ptls_cipher_context_t * ctx,
int is_enc,
427 return quic_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_256_ctr (),
428 quic_crypto_cipher_encrypt);
431 #endif // QUIC_HP_CRYPTO 435 const void *aad,
size_t aadlen)
443 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
445 id = VNET_CRYPTO_OP_AES_128_GCM_ENC;
447 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
449 id = VNET_CRYPTO_OP_AES_256_GCM_ENC;
463 vnet_op->
aad = (
u8 *) aad;
472 const void *input,
size_t inlen)
484 vnet_op->
src = (
u8 *) input;
485 vnet_op->
dst = output;
486 vnet_op->
len = inlen;
489 vnet_op->
tag = vnet_op->
src + inlen;
503 &quic_crypto_batch_ctx->
504 aead_crypto_tx_packets_ops[quic_crypto_batch_ctx->
nb_tx_packets];
511 const void *input,
size_t inlen,
const void *iv,
512 const void *aad,
size_t aadlen)
518 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
520 id = VNET_CRYPTO_OP_AES_128_GCM_DEC;
522 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
524 id = VNET_CRYPTO_OP_AES_256_GCM_DEC;
537 ctx->
op.
dst = _output;
539 ctx->
op.
len = inlen - ctx->
super.algo->tag_size;
546 if (ctx->
op.
status != VNET_CRYPTO_OP_STATUS_COMPLETED)
554 ptls_aead_context_t * _ctx,
void *_output,
555 const void *input,
size_t inlen,
556 uint64_t decrypted_pn,
const void *aad,
561 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
563 id = VNET_CRYPTO_OP_AES_128_GCM_DEC;
565 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
567 id = VNET_CRYPTO_OP_AES_256_GCM_DEC;
583 vnet_op->
aad = (
u8 *) aad;
587 vnet_op->
src = (
u8 *) input;
588 vnet_op->
dst = _output;
590 vnet_op->
len = inlen - ctx->
super.algo->tag_size;
592 vnet_op->
tag = vnet_op->
src + vnet_op->
len;
605 const void *key,
const EVP_CIPHER * cipher)
611 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
613 algo = VNET_CRYPTO_ALG_AES_128_GCM;
615 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
617 algo = VNET_CRYPTO_ALG_AES_256_GCM;
621 QUIC_DBG (1,
"%s, invalied aead cipher %s", __FUNCTION__,
637 (
u8 *) key, _ctx->algo->key_size);
642 if (!strcmp (ctx->
super.algo->name,
"AES128-GCM"))
643 ptls_openssl_aes128gcm.setup_crypto (_ctx, is_enc, key);
644 else if (!strcmp (ctx->
super.algo->name,
"AES256-GCM"))
645 ptls_openssl_aes256gcm.setup_crypto (_ctx, is_enc, key);
653 int is_enc,
const void *key)
660 int is_enc,
const void *key)
665 #ifdef QUIC_HP_CRYPTO 666 ptls_cipher_algorithm_t quic_crypto_aes128ctr = {
668 PTLS_AES128_KEY_SIZE,
673 ptls_cipher_algorithm_t quic_crypto_aes256ctr = {
674 "AES256-CTR", PTLS_AES256_KEY_SIZE, 1 ,
679 ptls_aead_algorithm_t quic_crypto_aes128gcm = {
681 #ifdef QUIC_HP_CRYPTO 682 &quic_crypto_aes128ctr,
684 &ptls_openssl_aes128ctr,
686 &ptls_openssl_aes128ecb,
687 PTLS_AES128_KEY_SIZE,
689 PTLS_AESGCM_TAG_SIZE,
691 quic_crypto_aead_aes128gcm_setup_crypto
694 ptls_aead_algorithm_t quic_crypto_aes256gcm = {
696 #ifdef QUIC_HP_CRYPTO 697 &quic_crypto_aes256ctr,
699 &ptls_openssl_aes256ctr,
701 &ptls_openssl_aes256ecb,
702 PTLS_AES256_KEY_SIZE,
704 PTLS_AESGCM_TAG_SIZE,
706 quic_crypto_aead_aes256gcm_setup_crypto
709 ptls_cipher_suite_t quic_crypto_aes128gcmsha256 = {
710 PTLS_CIPHER_SUITE_AES_128_GCM_SHA256,
714 ptls_cipher_suite_t quic_crypto_aes256gcmsha384 = {
715 PTLS_CIPHER_SUITE_AES_256_GCM_SHA384,
719 ptls_cipher_suite_t *quic_crypto_cipher_suites[] = {
723 quicly_crypto_engine_t quic_crypto_engine = {
729 int is_encrypt, ptls_buffer_t *
dst, ptls_iovec_t
src)
740 return PTLS_ERROR_NO_MEMORY;
742 ptls_get_context (tls)->random_bytes (self->id, sizeof (self->id));
744 self->data.len = src.len;
747 if ((ret = ptls_buffer_reserve (dst,
sizeof (self->id))) != 0)
749 clib_memcpy (dst->base + dst->off, self->id, sizeof (self->id));
750 dst->off +=
sizeof (
self->id);
757 if (src.len != sizeof (self->id))
758 return PTLS_ERROR_SESSION_NOT_FOUND;
759 if (
clib_memcmp (self->id, src.base, sizeof (self->id)) != 0)
760 return PTLS_ERROR_SESSION_NOT_FOUND;
763 if ((ret = ptls_buffer_reserve (dst, self->data.len)) != 0)
765 clib_memcpy (dst->base + dst->off, self->data.base, self->data.len);
766 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
struct quic_ctx_::@650 ingress_keys
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)
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)
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)