aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAloys Augustin <aloaugus@cisco.com>2021-08-02 17:42:23 +0200
committerFlorin Coras <florin.coras@gmail.com>2021-08-03 17:09:18 +0000
commit7dbc8ebe54f4ddb83e337be152e9b8405f52e577 (patch)
tree3f11b93e346f7f4a686ada3448296e69f0d35fdb
parent8f174ad5b6ab472d7ee4cba61bc5f672bd6a3fbb (diff)
quic: do not update crypto keys from workers
The vnet_crypto_key_add should only be called from the main thread. This patch works around this limitation by allocating one key per worker and updating it on the fly everytime we need to do a crypto operation. This solution is far from ideal, but quicly has a strong assumption that it can use a key immediately after determining it, so making the key creation asynchronous is not a possibility. Signed-off-by: Aloys Augustin <aloaugus@cisco.com> Change-Id: I19fc5814195156003c36a73bb616738ba9d828f7 Type: fix
-rw-r--r--src/plugins/quic/quic.c9
-rw-r--r--src/plugins/quic/quic.h3
-rw-r--r--src/plugins/quic/quic_crypto.c67
3 files changed, 59 insertions, 20 deletions
diff --git a/src/plugins/quic/quic.c b/src/plugins/quic/quic.c
index 26f2216a3d8..499eb8bc776 100644
--- a/src/plugins/quic/quic.c
+++ b/src/plugins/quic/quic.c
@@ -2563,14 +2563,19 @@ quic_init (vlib_main_t * vm)
qm->vnet_crypto_enabled = 1;
if (qm->vnet_crypto_enabled == 1)
{
+ u8 empty_key[32] = {};
quic_register_cipher_suite (CRYPTO_ENGINE_VPP,
quic_crypto_cipher_suites);
qm->default_crypto_engine = CRYPTO_ENGINE_VPP;
+ vec_validate (qm->per_thread_crypto_key_indices, num_threads);
+ for (i = 0; i < num_threads; i++)
+ {
+ qm->per_thread_crypto_key_indices[i] = vnet_crypto_key_add (
+ vm, VNET_CRYPTO_ALG_AES_256_CTR, empty_key, 32);
+ }
}
qm->max_packets_per_key = DEFAULT_MAX_PACKETS_PER_KEY;
- clib_rwlock_init (&qm->crypto_keys_quic_rw_lock);
-
qm->default_quic_cc = QUIC_CC_RENO;
vec_free (a->name);
diff --git a/src/plugins/quic/quic.h b/src/plugins/quic/quic.h
index 901bdbc39b2..2c5a21c01a4 100644
--- a/src/plugins/quic/quic.h
+++ b/src/plugins/quic/quic.h
@@ -263,8 +263,7 @@ typedef struct quic_main_
u32 connection_timeout;
u8 vnet_crypto_enabled;
-
- clib_rwlock_t crypto_keys_quic_rw_lock;
+ u32 *per_thread_crypto_key_indices;
} quic_main_t;
#endif /* __included_quic_h__ */
diff --git a/src/plugins/quic/quic_crypto.c b/src/plugins/quic/quic_crypto.c
index 602b3f8570c..9931ab56b76 100644
--- a/src/plugins/quic/quic_crypto.c
+++ b/src/plugins/quic/quic_crypto.c
@@ -15,9 +15,11 @@
#include <quic/quic.h>
#include <quic/quic_crypto.h>
+#include <vnet/session/session.h>
#include <quicly.h>
#include <picotls/openssl.h>
+#include <pthread.h>
#define QUICLY_EPOCH_1RTT 3
@@ -25,12 +27,19 @@ extern quic_main_t quic_main;
extern quic_ctx_t *quic_get_conn_ctx (quicly_conn_t * conn);
vnet_crypto_main_t *cm = &crypto_main;
+typedef struct crypto_key_
+{
+ vnet_crypto_alg_t algo;
+ u8 key[32];
+ u16 key_len;
+} crypto_key_t;
+
struct cipher_context_t
{
ptls_cipher_context_t super;
vnet_crypto_op_t op;
vnet_crypto_op_id_t id;
- u32 key_index;
+ crypto_key_t key;
};
struct aead_crypto_context_t
@@ -39,7 +48,8 @@ struct aead_crypto_context_t
EVP_CIPHER_CTX *evp_ctx;
uint8_t static_iv[PTLS_MAX_IV_SIZE];
vnet_crypto_op_t op;
- u32 key_index;
+ crypto_key_t key;
+
vnet_crypto_op_id_t id;
uint8_t iv[PTLS_MAX_IV_SIZE];
};
@@ -114,6 +124,29 @@ Exit:
return ret;
}
+static u32
+quic_crypto_set_key (crypto_key_t *key)
+{
+ u8 thread_index = vlib_get_thread_index ();
+ u32 key_id = quic_main.per_thread_crypto_key_indices[thread_index];
+ vnet_crypto_key_t *vnet_key = vnet_crypto_get_key (key_id);
+ vlib_main_t *vm = vlib_get_main ();
+ vnet_crypto_engine_t *engine;
+
+ vec_foreach (engine, cm->engines)
+ if (engine->key_op_handler)
+ engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_DEL, key_id);
+
+ vnet_key->alg = key->algo;
+ clib_memcpy (vnet_key->data, key->key, key->key_len);
+
+ vec_foreach (engine, cm->engines)
+ if (engine->key_op_handler)
+ engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, key_id);
+
+ return key_id;
+}
+
static size_t
quic_crypto_aead_decrypt (quic_ctx_t *qctx, ptls_aead_context_t *_ctx,
void *_output, const void *input, size_t inlen,
@@ -132,7 +165,7 @@ quic_crypto_aead_decrypt (quic_ctx_t *qctx, ptls_aead_context_t *_ctx,
decrypted_pn);
ctx->op.src = (u8 *) input;
ctx->op.dst = _output;
- ctx->op.key_index = ctx->key_index;
+ ctx->op.key_index = quic_crypto_set_key (&ctx->key);
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;
@@ -260,7 +293,7 @@ quic_crypto_encrypt_packet (struct st_quicly_crypto_engine_t *engine,
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.key_index = quic_crypto_set_key (&aead_ctx->key);
aead_ctx->op.src = (u8 *) input;
aead_ctx->op.dst = output;
aead_ctx->op.len = inlen;
@@ -280,7 +313,8 @@ quic_crypto_encrypt_packet (struct st_quicly_crypto_engine_t *engine,
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.key_index = quic_crypto_set_key (&hp_ctx->key);
+ ;
hp_ctx->op.src = (u8 *) supp.output;
hp_ctx->op.dst = (u8 *) supp.output;
hp_ctx->op.len = sizeof (supp.output);
@@ -301,7 +335,6 @@ quic_crypto_cipher_setup_crypto (ptls_cipher_context_t *_ctx, int is_enc,
{
struct cipher_context_t *ctx = (struct cipher_context_t *) _ctx;
- vlib_main_t *vm = vlib_get_main ();
vnet_crypto_alg_t algo;
if (!strcmp (ctx->super.algo->name, "AES128-CTR"))
{
@@ -326,10 +359,12 @@ quic_crypto_cipher_setup_crypto (ptls_cipher_context_t *_ctx, int is_enc,
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);
+ // ctx->key_index =
+ // quic_crypto_go_setup_key (algo, key, _ctx->algo->key_size);
+ ctx->key.algo = algo;
+ ctx->key.key_len = _ctx->algo->key_size;
+ assert (ctx->key.key_len <= 32);
+ clib_memcpy (&ctx->key.key, key, ctx->key.key_len);
}
return 0;
@@ -354,7 +389,6 @@ 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;
vnet_crypto_alg_t algo;
@@ -382,11 +416,12 @@ quic_crypto_aead_setup_crypto (ptls_aead_context_t *_ctx, int is_enc,
if (quic_main.vnet_crypto_enabled)
{
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);
+ // ctx->key_index =
+ // quic_crypto_go_setup_key (algo, key, _ctx->algo->key_size);
+ ctx->key.algo = algo;
+ ctx->key.key_len = _ctx->algo->key_size;
+ assert (ctx->key.key_len <= 32);
+ clib_memcpy (&ctx->key.key, key, ctx->key.key_len);
}
return 0;