diff options
Diffstat (limited to 'src/plugins/quic/quic_crypto.c')
-rw-r--r-- | src/plugins/quic/quic_crypto.c | 684 |
1 files changed, 212 insertions, 472 deletions
diff --git a/src/plugins/quic/quic_crypto.c b/src/plugins/quic/quic_crypto.c index 35dddf63c71..5e90563885e 100644 --- a/src/plugins/quic/quic_crypto.c +++ b/src/plugins/quic/quic_crypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -12,8 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include <vnet/crypto/crypto.h> -#include <vppinfra/lock.h> #include <quic/quic.h> #include <quic/quic_crypto.h> @@ -25,14 +23,13 @@ extern quic_main_t quic_main; extern quic_ctx_t *quic_get_conn_ctx (quicly_conn_t * conn); - -typedef void (*quicly_do_transform_fn) (ptls_cipher_context_t *, void *, - const void *, size_t); +vnet_crypto_main_t *cm = &crypto_main; struct cipher_context_t { ptls_cipher_context_t super; vnet_crypto_op_t op; + vnet_crypto_op_id_t id; u32 key_index; }; @@ -41,139 +38,35 @@ struct aead_crypto_context_t ptls_aead_context_t super; vnet_crypto_op_t op; u32 key_index; + vnet_crypto_op_id_t id; + uint8_t iv[PTLS_MAX_IV_SIZE]; + uint8_t static_iv[PTLS_MAX_IV_SIZE]; }; -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); - -vnet_crypto_main_t *cm = &crypto_main; - -void -quic_crypto_batch_tx_packets (quic_crypto_batch_ctx_t * batch_ctx) -{ - vlib_main_t *vm = vlib_get_main (); - - if (batch_ctx->nb_tx_packets <= 0) - return; - - clib_rwlock_reader_lock (&quic_main.crypto_keys_quic_rw_lock); - vnet_crypto_process_ops (vm, batch_ctx->aead_crypto_tx_packets_ops, - batch_ctx->nb_tx_packets); - clib_rwlock_reader_unlock (&quic_main.crypto_keys_quic_rw_lock); - - for (int i = 0; i < batch_ctx->nb_tx_packets; i++) - clib_mem_free (batch_ctx->aead_crypto_tx_packets_ops[i].iv); - - batch_ctx->nb_tx_packets = 0; -} - -void -quic_crypto_batch_rx_packets (quic_crypto_batch_ctx_t * batch_ctx) -{ - vlib_main_t *vm = vlib_get_main (); - - if (batch_ctx->nb_rx_packets <= 0) - return; - - clib_rwlock_reader_lock (&quic_main.crypto_keys_quic_rw_lock); - vnet_crypto_process_ops (vm, batch_ctx->aead_crypto_rx_packets_ops, - batch_ctx->nb_rx_packets); - clib_rwlock_reader_unlock (&quic_main.crypto_keys_quic_rw_lock); - - for (int i = 0; i < batch_ctx->nb_rx_packets; i++) - clib_mem_free (batch_ctx->aead_crypto_rx_packets_ops[i].iv); - - batch_ctx->nb_rx_packets = 0; -} - -void -build_iv (ptls_aead_context_t * ctx, uint8_t * iv, uint64_t seq) -{ - size_t iv_size = ctx->algo->iv_size, i; - const uint8_t *s = ctx->static_iv; - uint8_t *d = iv; - /* build iv */ - for (i = iv_size - 8; i != 0; --i) - *d++ = *s++; - i = 64; - do - { - i -= 8; - *d++ = *s++ ^ (uint8_t) (seq >> i); - } - while (i != 0); -} - -static void -do_finalize_send_packet (ptls_cipher_context_t * hp, - quicly_datagram_t * packet, - size_t first_byte_at, size_t payload_from) -{ - uint8_t hpmask[1 + QUICLY_SEND_PN_SIZE] = { - 0 - }; - size_t i; - - ptls_cipher_init (hp, - packet->data.base + payload_from - QUICLY_SEND_PN_SIZE + - QUICLY_MAX_PN_SIZE); - ptls_cipher_encrypt (hp, hpmask, hpmask, sizeof (hpmask)); - - packet->data.base[first_byte_at] ^= - hpmask[0] & - (QUICLY_PACKET_IS_LONG_HEADER (packet->data.base[first_byte_at]) ? 0xf : - 0x1f); - - for (i = 0; i != QUICLY_SEND_PN_SIZE; ++i) - packet->data.base[payload_from + i - QUICLY_SEND_PN_SIZE] ^= - hpmask[i + 1]; -} - -void -quic_crypto_finalize_send_packet (quicly_datagram_t * packet) -{ - quic_encrypt_cb_ctx *encrypt_cb_ctx = - (quic_encrypt_cb_ctx *) ((uint8_t *) packet + sizeof (*packet)); - - for (int i = 0; i < encrypt_cb_ctx->snd_ctx_count; i++) - { - do_finalize_send_packet (encrypt_cb_ctx->snd_ctx[i].hp, - packet, - encrypt_cb_ctx->snd_ctx[i].first_byte_at, - encrypt_cb_ctx->snd_ctx[i].payload_from); - } - encrypt_cb_ctx->snd_ctx_count = 0; -} - 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) +quic_crypto_setup_cipher (quicly_crypto_engine_t *engine, quicly_conn_t *conn, + size_t epoch, int is_enc, + ptls_cipher_context_t **header_protect_ctx, + ptls_aead_context_t **packet_protect_ctx, + ptls_aead_algorithm_t *aead, + ptls_hash_algorithm_t *hash, const void *secret) { uint8_t hpkey[PTLS_MAX_SECRET_SIZE]; int ret; - *aead_ctx = NULL; + *packet_protect_ctx = NULL; + /* generate new header protection key */ - if (hp_ctx != NULL) + if (header_protect_ctx != NULL) { - *hp_ctx = NULL; - ret = ptls_hkdf_expand_label (hash, hpkey, aead->ctr_cipher->key_size, - ptls_iovec_init (secret, - hash->digest_size), - "quic hp", ptls_iovec_init (NULL, 0), - NULL); - if (ret) + *header_protect_ctx = NULL; + if ((ret = ptls_hkdf_expand_label ( + hash, hpkey, aead->ctr_cipher->key_size, + ptls_iovec_init (secret, hash->digest_size), "quic hp", + ptls_iovec_init (NULL, 0), NULL)) != 0) goto Exit; - *hp_ctx = ptls_cipher_new (aead->ctr_cipher, is_enc, hpkey); - if (NULL == *hp_ctx) + if ((*header_protect_ctx = + ptls_cipher_new (aead->ctr_cipher, is_enc, hpkey)) == NULL) { ret = PTLS_ERROR_NO_MEMORY; goto Exit; @@ -181,9 +74,8 @@ quic_crypto_setup_cipher (quicly_crypto_engine_t * engine, } /* generate new AEAD context */ - *aead_ctx = ptls_aead_new (aead, hash, is_enc, secret, - QUICLY_AEAD_BASE_LABEL); - if (NULL == *aead_ctx) + if ((*packet_protect_ctx = ptls_aead_new (aead, hash, is_enc, secret, + QUICLY_AEAD_BASE_LABEL)) == NULL) { ret = PTLS_ERROR_NO_MEMORY; goto Exit; @@ -195,9 +87,9 @@ quic_crypto_setup_cipher (quicly_crypto_engine_t * engine, if (qctx->ingress_keys.aead_ctx != NULL) qctx->key_phase_ingress++; - qctx->ingress_keys.aead_ctx = *aead_ctx; - if (hp_ctx != NULL) - qctx->ingress_keys.hp_ctx = *hp_ctx; + qctx->ingress_keys.aead_ctx = *packet_protect_ctx; + if (header_protect_ctx != NULL) + qctx->ingress_keys.hp_ctx = *header_protect_ctx; } ret = 0; @@ -205,39 +97,47 @@ quic_crypto_setup_cipher (quicly_crypto_engine_t * engine, Exit: if (ret) { - if (*aead_ctx != NULL) + if (packet_protect_ctx && *packet_protect_ctx != NULL) { - ptls_aead_free (*aead_ctx); - *aead_ctx = NULL; + ptls_aead_free (*packet_protect_ctx); + *packet_protect_ctx = NULL; } - if (hp_ctx && *hp_ctx != NULL) + if (header_protect_ctx && *header_protect_ctx != NULL) { - ptls_cipher_free (*hp_ctx); - *hp_ctx = NULL; + ptls_cipher_free (*header_protect_ctx); + *header_protect_ctx = NULL; } } ptls_clear_memory (hpkey, sizeof (hpkey)); return ret; } -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) +static size_t +quic_crypto_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) { - quic_encrypt_cb_ctx *encrypt_cb_ctx = - (quic_encrypt_cb_ctx *) ((uint8_t *) packet + sizeof (*packet)); - - encrypt_cb_ctx->snd_ctx[encrypt_cb_ctx->snd_ctx_count].hp = hp; - encrypt_cb_ctx->snd_ctx[encrypt_cb_ctx->snd_ctx_count].first_byte_at = - first_byte_at; - encrypt_cb_ctx->snd_ctx[encrypt_cb_ctx->snd_ctx_count].payload_from = - payload_from; - encrypt_cb_ctx->snd_ctx_count++; + vlib_main_t *vm = vlib_get_main (); + + struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *) _ctx; + + vnet_crypto_op_init (&ctx->op, ctx->id); + ctx->op.aad = (u8 *) aad; + ctx->op.aad_len = aadlen; + ctx->op.iv = ctx->iv; + ptls_aead__build_iv (ctx->super.algo, ctx->op.iv, ctx->static_iv, + decrypted_pn); + ctx->op.src = (u8 *) input; + ctx->op.dst = _output; + ctx->op.key_index = ctx->key_index; + ctx->op.len = inlen - ctx->super.algo->tag_size; + ctx->op.tag_len = ctx->super.algo->tag_size; + ctx->op.tag = ctx->op.src + ctx->op.len; + + vnet_crypto_process_ops (vm, &(ctx->op), 1); + + return ctx->op.len; } void @@ -310,13 +210,11 @@ quic_crypto_decrypt_packet (quic_ctx_t * qctx, quic_rx_packet_ctx_t * pctx) return; } - if ((ptlen = - quic_crypto_offload_aead_decrypt (qctx, aead, - pctx->packet.octets.base + aead_off, - pctx->packet.octets.base + aead_off, - pctx->packet.octets.len - aead_off, - pn, pctx->packet.octets.base, - aead_off)) == SIZE_MAX) + if ((ptlen = quic_crypto_aead_decrypt ( + qctx, aead, pctx->packet.octets.base + aead_off, + pctx->packet.octets.base + aead_off, + pctx->packet.octets.len - aead_off, pn, pctx->packet.octets.base, + aead_off)) == SIZE_MAX) { fprintf (stderr, "%s: aead decryption failure (pn: %d)\n", __FUNCTION__, pn); @@ -330,71 +228,92 @@ quic_crypto_decrypt_packet (quic_ctx_t * qctx, quic_rx_packet_ctx_t * pctx) pctx->packet.decrypted.key_phase = qctx->key_phase_ingress; } -#ifdef QUIC_HP_CRYPTO -static void -quic_crypto_cipher_do_init (ptls_cipher_context_t * _ctx, const void *iv) -{ - struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx; - vnet_crypto_op_id_t id; - if (!strcmp (ctx->super.algo->name, "AES128-CTR")) - { - id = VNET_CRYPTO_OP_AES_128_CTR_ENC; - } - else if (!strcmp (ctx->super.algo->name, "AES256-CTR")) - { - id = VNET_CRYPTO_OP_AES_256_CTR_ENC; - } - else - { - QUIC_DBG (1, "%s, Invalid crypto cipher : ", __FUNCTION__, - _ctx->algo->name); - assert (0); - } - vnet_crypto_op_init (&ctx->op, id); - ctx->op.iv = (u8 *) iv; - ctx->op.key_index = ctx->key_index; -} - -static void -quic_crypto_cipher_dispose (ptls_cipher_context_t * _ctx) -{ - /* Do nothing */ -} - -static void -quic_crypto_cipher_encrypt (ptls_cipher_context_t * _ctx, void *output, - const void *input, size_t _len) +void +quic_crypto_encrypt_packet (struct st_quicly_crypto_engine_t *engine, + quicly_conn_t *conn, + ptls_cipher_context_t *header_protect_ctx, + ptls_aead_context_t *packet_protect_ctx, + ptls_iovec_t datagram, size_t first_byte_at, + size_t payload_from, uint64_t packet_number, + int coalesced) { vlib_main_t *vm = vlib_get_main (); - struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx; - ctx->op.src = (u8 *) input; - ctx->op.dst = output; - ctx->op.len = _len; + struct cipher_context_t *hp_ctx = + (struct cipher_context_t *) header_protect_ctx; + struct aead_crypto_context_t *aead_ctx = + (struct aead_crypto_context_t *) packet_protect_ctx; + + void *input = datagram.base + payload_from; + void *output = input; + size_t inlen = + datagram.len - payload_from - packet_protect_ctx->algo->tag_size; + const void *aad = datagram.base + first_byte_at; + size_t aadlen = payload_from - first_byte_at; + + /* Build AEAD encrypt crypto operation */ + vnet_crypto_op_init (&aead_ctx->op, aead_ctx->id); + aead_ctx->op.aad = (u8 *) aad; + aead_ctx->op.aad_len = aadlen; + aead_ctx->op.iv = aead_ctx->iv; + ptls_aead__build_iv (aead_ctx->super.algo, aead_ctx->op.iv, + aead_ctx->static_iv, packet_number); + aead_ctx->op.key_index = aead_ctx->key_index; + aead_ctx->op.src = (u8 *) input; + aead_ctx->op.dst = output; + aead_ctx->op.len = inlen; + aead_ctx->op.tag_len = aead_ctx->super.algo->tag_size; + aead_ctx->op.tag = aead_ctx->op.src + inlen; + vnet_crypto_process_ops (vm, &(aead_ctx->op), 1); + assert (aead_ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED); + + /* Build Header protection crypto operation */ + ptls_aead_supplementary_encryption_t supp = { + .ctx = header_protect_ctx, + .input = + datagram.base + payload_from - QUICLY_SEND_PN_SIZE + QUICLY_MAX_PN_SIZE + }; - vnet_crypto_process_ops (vm, &ctx->op, 1); + /* Build Header protection crypto operation */ + vnet_crypto_op_init (&hp_ctx->op, hp_ctx->id); + memset (supp.output, 0, sizeof (supp.output)); + hp_ctx->op.iv = (u8 *) supp.input; + hp_ctx->op.key_index = hp_ctx->key_index; + hp_ctx->op.src = (u8 *) supp.output; + hp_ctx->op.dst = (u8 *) supp.output; + hp_ctx->op.len = sizeof (supp.output); + vnet_crypto_process_ops (vm, &(hp_ctx->op), 1); + assert (hp_ctx->op.status == VNET_CRYPTO_OP_STATUS_COMPLETED); + + datagram.base[first_byte_at] ^= + supp.output[0] & + (QUICLY_PACKET_IS_LONG_HEADER (datagram.base[first_byte_at]) ? 0xf : 0x1f); + for (size_t i = 0; i != QUICLY_SEND_PN_SIZE; ++i) + datagram.base[payload_from + i - QUICLY_SEND_PN_SIZE] ^= + supp.output[i + 1]; } static int -quic_crypto_cipher_setup_crypto (ptls_cipher_context_t * _ctx, int is_enc, - const void *key, const EVP_CIPHER * cipher, - quicly_do_transform_fn do_transform) +quic_crypto_cipher_setup_crypto (ptls_cipher_context_t *_ctx, int is_enc, + const void *key, const EVP_CIPHER *cipher) { struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx; - ctx->super.do_dispose = quic_crypto_cipher_dispose; - ctx->super.do_init = quic_crypto_cipher_do_init; - ctx->super.do_transform = do_transform; - vlib_main_t *vm = vlib_get_main (); vnet_crypto_alg_t algo; if (!strcmp (ctx->super.algo->name, "AES128-CTR")) { algo = VNET_CRYPTO_ALG_AES_128_CTR; + ctx->id = is_enc ? VNET_CRYPTO_OP_AES_128_CTR_ENC : + VNET_CRYPTO_OP_AES_128_CTR_DEC; + ptls_openssl_aes128ctr.setup_crypto (_ctx, is_enc, key); } else if (!strcmp (ctx->super.algo->name, "AES256-CTR")) { algo = VNET_CRYPTO_ALG_AES_256_CTR; + ctx->id = is_enc ? VNET_CRYPTO_OP_AES_256_CTR_ENC : + VNET_CRYPTO_OP_AES_256_CTR_DEC; + ptls_openssl_aes256ctr.setup_crypto (_ctx, is_enc, key); } else { @@ -403,8 +322,13 @@ quic_crypto_cipher_setup_crypto (ptls_cipher_context_t * _ctx, int is_enc, assert (0); } - ctx->key_index = vnet_crypto_key_add (vm, algo, - (u8 *) key, _ctx->algo->key_size); + if (quic_main.vnet_crypto_enabled) + { + clib_rwlock_writer_lock (&quic_main.crypto_keys_quic_rw_lock); + ctx->key_index = + vnet_crypto_key_add (vm, algo, (u8 *) key, _ctx->algo->key_size); + clib_rwlock_writer_unlock (&quic_main.crypto_keys_quic_rw_lock); + } return 0; } @@ -413,193 +337,20 @@ static int quic_crypto_aes128ctr_setup_crypto (ptls_cipher_context_t * ctx, int is_enc, const void *key) { - return quic_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_128_ctr (), - quic_crypto_cipher_encrypt); + return quic_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_128_ctr ()); } static int quic_crypto_aes256ctr_setup_crypto (ptls_cipher_context_t * ctx, int is_enc, const void *key) { - return quic_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_256_ctr (), - quic_crypto_cipher_encrypt); -} - -#endif // QUIC_HP_CRYPTO - -void -quic_crypto_aead_encrypt_init (ptls_aead_context_t * _ctx, const void *iv, - const void *aad, size_t aadlen) -{ - quic_main_t *qm = &quic_main; - u32 thread_index = vlib_get_thread_index (); - - struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *) _ctx; - - vnet_crypto_op_id_t id; - if (!strcmp (ctx->super.algo->name, "AES128-GCM")) - { - id = VNET_CRYPTO_OP_AES_128_GCM_ENC; - } - else if (!strcmp (ctx->super.algo->name, "AES256-GCM")) - { - id = VNET_CRYPTO_OP_AES_256_GCM_ENC; - } - else - { - assert (0); - } - - quic_crypto_batch_ctx_t *quic_crypto_batch_ctx = - &qm->wrk_ctx[thread_index].crypto_context_batch; - - vnet_crypto_op_t *vnet_op = - &quic_crypto_batch_ctx->aead_crypto_tx_packets_ops - [quic_crypto_batch_ctx->nb_tx_packets]; - vnet_crypto_op_init (vnet_op, id); - vnet_op->aad = (u8 *) aad; - vnet_op->aad_len = aadlen; - vnet_op->iv = clib_mem_alloc (PTLS_MAX_IV_SIZE); - clib_memcpy (vnet_op->iv, iv, PTLS_MAX_IV_SIZE); - vnet_op->key_index = ctx->key_index; -} - -size_t -quic_crypto_aead_encrypt_update (ptls_aead_context_t * _ctx, void *output, - const void *input, size_t inlen) -{ - struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *) _ctx; - - quic_main_t *qm = &quic_main; - u32 thread_index = vlib_get_thread_index (); - quic_crypto_batch_ctx_t *quic_crypto_batch_ctx = - &qm->wrk_ctx[thread_index].crypto_context_batch; - - vnet_crypto_op_t *vnet_op = - &quic_crypto_batch_ctx->aead_crypto_tx_packets_ops - [quic_crypto_batch_ctx->nb_tx_packets]; - vnet_op->src = (u8 *) input; - vnet_op->dst = output; - vnet_op->len = inlen; - vnet_op->tag_len = ctx->super.algo->tag_size; - - vnet_op->tag = vnet_op->src + inlen; - - return 0; -} - -size_t -quic_crypto_aead_encrypt_final (ptls_aead_context_t * _ctx, void *output) -{ - quic_main_t *qm = &quic_main; - u32 thread_index = vlib_get_thread_index (); - quic_crypto_batch_ctx_t *quic_crypto_batch_ctx = - &qm->wrk_ctx[thread_index].crypto_context_batch; - - vnet_crypto_op_t *vnet_op = - &quic_crypto_batch_ctx-> - aead_crypto_tx_packets_ops[quic_crypto_batch_ctx->nb_tx_packets]; - quic_crypto_batch_ctx->nb_tx_packets++; - return vnet_op->len + vnet_op->tag_len; -} - -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) -{ - vlib_main_t *vm = vlib_get_main (); - struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *) _ctx; - - vnet_crypto_op_id_t id; - if (!strcmp (ctx->super.algo->name, "AES128-GCM")) - { - id = VNET_CRYPTO_OP_AES_128_GCM_DEC; - } - else if (!strcmp (ctx->super.algo->name, "AES256-GCM")) - { - id = VNET_CRYPTO_OP_AES_256_GCM_DEC; - } - else - { - assert (0); - } - - vnet_crypto_op_init (&ctx->op, id); - ctx->op.aad = (u8 *) aad; - ctx->op.aad_len = aadlen; - ctx->op.iv = (u8 *) iv; - - ctx->op.src = (u8 *) input; - ctx->op.dst = _output; - ctx->op.key_index = ctx->key_index; - ctx->op.len = inlen - ctx->super.algo->tag_size; - - ctx->op.tag_len = ctx->super.algo->tag_size; - ctx->op.tag = ctx->op.src + ctx->op.len; - - vnet_crypto_process_ops (vm, &ctx->op, 1); - - if (ctx->op.status != VNET_CRYPTO_OP_STATUS_COMPLETED) - return SIZE_MAX; - - return ctx->op.len; -} - -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) -{ - struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *) _ctx; - vnet_crypto_op_id_t id; - if (!strcmp (ctx->super.algo->name, "AES128-GCM")) - { - id = VNET_CRYPTO_OP_AES_128_GCM_DEC; - } - else if (!strcmp (ctx->super.algo->name, "AES256-GCM")) - { - id = VNET_CRYPTO_OP_AES_256_GCM_DEC; - } - else - { - return SIZE_MAX; - } - - quic_main_t *qm = &quic_main; - quic_crypto_batch_ctx_t *quic_crypto_batch_ctx = - &qm->wrk_ctx[qctx->c_thread_index].crypto_context_batch; - - vnet_crypto_op_t *vnet_op = - &quic_crypto_batch_ctx->aead_crypto_rx_packets_ops - [quic_crypto_batch_ctx->nb_rx_packets]; - - vnet_crypto_op_init (vnet_op, id); - vnet_op->aad = (u8 *) aad; - vnet_op->aad_len = aadlen; - vnet_op->iv = clib_mem_alloc (PTLS_MAX_IV_SIZE); - build_iv (_ctx, vnet_op->iv, decrypted_pn); - vnet_op->src = (u8 *) input; - vnet_op->dst = _output; - vnet_op->key_index = ctx->key_index; - vnet_op->len = inlen - ctx->super.algo->tag_size; - vnet_op->tag_len = ctx->super.algo->tag_size; - vnet_op->tag = vnet_op->src + vnet_op->len; - quic_crypto_batch_ctx->nb_rx_packets++; - return vnet_op->len; -} - -static void -quic_crypto_aead_dispose_crypto (ptls_aead_context_t * _ctx) -{ - + return quic_crypto_cipher_setup_crypto (ctx, 1, key, EVP_aes_256_ctr ()); } static int -quic_crypto_aead_setup_crypto (ptls_aead_context_t * _ctx, int is_enc, - const void *key, const EVP_CIPHER * cipher) +quic_crypto_aead_setup_crypto (ptls_aead_context_t *_ctx, int is_enc, + const void *key, const void *iv, + const EVP_CIPHER *cipher) { vlib_main_t *vm = vlib_get_main (); struct aead_crypto_context_t *ctx = (struct aead_crypto_context_t *) _ctx; @@ -608,10 +359,16 @@ quic_crypto_aead_setup_crypto (ptls_aead_context_t * _ctx, int is_enc, if (!strcmp (ctx->super.algo->name, "AES128-GCM")) { algo = VNET_CRYPTO_ALG_AES_128_GCM; + ctx->id = is_enc ? VNET_CRYPTO_OP_AES_128_GCM_ENC : + VNET_CRYPTO_OP_AES_128_GCM_DEC; + ptls_openssl_aes128gcm.setup_crypto (_ctx, is_enc, key, iv); } else if (!strcmp (ctx->super.algo->name, "AES256-GCM")) { algo = VNET_CRYPTO_ALG_AES_256_GCM; + ctx->id = is_enc ? VNET_CRYPTO_OP_AES_256_GCM_ENC : + VNET_CRYPTO_OP_AES_256_GCM_DEC; + ptls_openssl_aes256gcm.setup_crypto (_ctx, is_enc, key, iv); } else { @@ -622,64 +379,97 @@ quic_crypto_aead_setup_crypto (ptls_aead_context_t * _ctx, int is_enc, if (quic_main.vnet_crypto_enabled) { - ctx->super.do_decrypt = quic_crypto_aead_decrypt; - - ctx->super.do_encrypt_init = quic_crypto_aead_encrypt_init; - ctx->super.do_encrypt_update = quic_crypto_aead_encrypt_update; - ctx->super.do_encrypt_final = quic_crypto_aead_encrypt_final; - ctx->super.dispose_crypto = quic_crypto_aead_dispose_crypto; + clib_memcpy (ctx->static_iv, iv, ctx->super.algo->iv_size); clib_rwlock_writer_lock (&quic_main.crypto_keys_quic_rw_lock); ctx->key_index = vnet_crypto_key_add (vm, algo, (u8 *) key, _ctx->algo->key_size); clib_rwlock_writer_unlock (&quic_main.crypto_keys_quic_rw_lock); } - else - { - if (!strcmp (ctx->super.algo->name, "AES128-GCM")) - ptls_openssl_aes128gcm.setup_crypto (_ctx, is_enc, key); - else if (!strcmp (ctx->super.algo->name, "AES256-GCM")) - ptls_openssl_aes256gcm.setup_crypto (_ctx, is_enc, key); - } return 0; } static int -quic_crypto_aead_aes128gcm_setup_crypto (ptls_aead_context_t * ctx, - int is_enc, const void *key) +quic_crypto_aead_aes128gcm_setup_crypto (ptls_aead_context_t *ctx, int is_enc, + const void *key, const void *iv) { - return quic_crypto_aead_setup_crypto (ctx, is_enc, key, EVP_aes_128_gcm ()); + return quic_crypto_aead_setup_crypto (ctx, is_enc, key, iv, + EVP_aes_128_gcm ()); } static int -quic_crypto_aead_aes256gcm_setup_crypto (ptls_aead_context_t * ctx, - int is_enc, const void *key) +quic_crypto_aead_aes256gcm_setup_crypto (ptls_aead_context_t *ctx, int is_enc, + const void *key, const void *iv) +{ + return quic_crypto_aead_setup_crypto (ctx, is_enc, key, iv, + EVP_aes_256_gcm ()); +} + +int +quic_encrypt_ticket_cb (ptls_encrypt_ticket_t *_self, ptls_t *tls, + int is_encrypt, ptls_buffer_t *dst, ptls_iovec_t src) { - return quic_crypto_aead_setup_crypto (ctx, is_enc, key, EVP_aes_256_gcm ()); + quic_session_cache_t *self = (void *) _self; + int ret; + + if (is_encrypt) + { + + /* replace the cached entry along with a newly generated session id */ + clib_mem_free (self->data.base); + if ((self->data.base = clib_mem_alloc (src.len)) == NULL) + return PTLS_ERROR_NO_MEMORY; + + ptls_get_context (tls)->random_bytes (self->id, sizeof (self->id)); + clib_memcpy (self->data.base, src.base, src.len); + self->data.len = src.len; + + /* store the session id in buffer */ + if ((ret = ptls_buffer_reserve (dst, sizeof (self->id))) != 0) + return ret; + clib_memcpy (dst->base + dst->off, self->id, sizeof (self->id)); + dst->off += sizeof (self->id); + } + else + { + /* check if session id is the one stored in cache */ + if (src.len != sizeof (self->id)) + return PTLS_ERROR_SESSION_NOT_FOUND; + if (clib_memcmp (self->id, src.base, sizeof (self->id)) != 0) + return PTLS_ERROR_SESSION_NOT_FOUND; + + /* return the cached value */ + if ((ret = ptls_buffer_reserve (dst, self->data.len)) != 0) + return ret; + clib_memcpy (dst->base + dst->off, self->data.base, self->data.len); + dst->off += self->data.len; + } + + return 0; } -#ifdef QUIC_HP_CRYPTO ptls_cipher_algorithm_t quic_crypto_aes128ctr = { "AES128-CTR", PTLS_AES128_KEY_SIZE, - 1, PTLS_AES_IV_SIZE, - sizeof (struct cipher_context_t), aes128ctr_setup_crypto + 1, + PTLS_AES_IV_SIZE, + sizeof (struct cipher_context_t), + quic_crypto_aes128ctr_setup_crypto }; ptls_cipher_algorithm_t quic_crypto_aes256ctr = { - "AES256-CTR", PTLS_AES256_KEY_SIZE, 1 /* block size */ , - PTLS_AES_IV_SIZE, sizeof (struct cipher_context_t), aes256ctr_setup_crypto + "AES256-CTR", + PTLS_AES256_KEY_SIZE, + 1 /* block size */, + PTLS_AES_IV_SIZE, + sizeof (struct cipher_context_t), + quic_crypto_aes256ctr_setup_crypto }; -#endif ptls_aead_algorithm_t quic_crypto_aes128gcm = { "AES128-GCM", -#ifdef QUIC_HP_CRYPTO &quic_crypto_aes128ctr, -#else - &ptls_openssl_aes128ctr, -#endif &ptls_openssl_aes128ecb, PTLS_AES128_KEY_SIZE, PTLS_AESGCM_IV_SIZE, @@ -690,11 +480,7 @@ ptls_aead_algorithm_t quic_crypto_aes128gcm = { ptls_aead_algorithm_t quic_crypto_aes256gcm = { "AES256-GCM", -#ifdef QUIC_HP_CRYPTO &quic_crypto_aes256ctr, -#else - &ptls_openssl_aes256ctr, -#endif &ptls_openssl_aes256ecb, PTLS_AES256_KEY_SIZE, PTLS_AESGCM_IV_SIZE, @@ -717,54 +503,8 @@ ptls_cipher_suite_t *quic_crypto_cipher_suites[] = { &quic_crypto_aes256gcmsha384, &quic_crypto_aes128gcmsha256, NULL }; -quicly_crypto_engine_t quic_crypto_engine = { - quic_crypto_setup_cipher, quic_crypto_finalize_send_packet_cb -}; - -int -quic_encrypt_ticket_cb (ptls_encrypt_ticket_t * _self, ptls_t * tls, - int is_encrypt, ptls_buffer_t * dst, ptls_iovec_t src) -{ - quic_session_cache_t *self = (void *) _self; - int ret; - - if (is_encrypt) - { - - /* replace the cached entry along with a newly generated session id */ - clib_mem_free (self->data.base); - if ((self->data.base = clib_mem_alloc (src.len)) == NULL) - return PTLS_ERROR_NO_MEMORY; - - ptls_get_context (tls)->random_bytes (self->id, sizeof (self->id)); - clib_memcpy (self->data.base, src.base, src.len); - self->data.len = src.len; - - /* store the session id in buffer */ - if ((ret = ptls_buffer_reserve (dst, sizeof (self->id))) != 0) - return ret; - clib_memcpy (dst->base + dst->off, self->id, sizeof (self->id)); - dst->off += sizeof (self->id); - - } - else - { - - /* check if session id is the one stored in cache */ - if (src.len != sizeof (self->id)) - return PTLS_ERROR_SESSION_NOT_FOUND; - if (clib_memcmp (self->id, src.base, sizeof (self->id)) != 0) - return PTLS_ERROR_SESSION_NOT_FOUND; - - /* return the cached value */ - if ((ret = ptls_buffer_reserve (dst, self->data.len)) != 0) - return ret; - clib_memcpy (dst->base + dst->off, self->data.base, self->data.len); - dst->off += self->data.len; - } - - return 0; -} +quicly_crypto_engine_t quic_crypto_engine = { quic_crypto_setup_cipher, + quic_crypto_encrypt_packet }; /* * fd.io coding-style-patch-verification: ON |