Compare commits

...

6 Commits

Author SHA1 Message Date
9d2db2eb2e wireguard: fix passing argument
Fixed coverity-issue CID 248456.
Originally passing argument of type "uint64_t *" to function:
"memcopy_s_inline".
This patch fixes the problem by changing type of passing argument and
make a portable assumption.

Type: fix

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I17e4583a05ea1263e4d8a4acc9949454e5fd92c0
(cherry picked from commit ffd9057493)
2022-01-25 11:36:28 +00:00
e3d36d18c1 dpdk-cryptodev: add support chacha20-poly1305
Originally cryptodev doesn't support chacha20-poly1305 with aad length
0.

This patch add support in cryptodev for chacha20-poly1305 with aad
length 0. This length is using in Wireguard.

Type: improvement

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I0608920bb557d7d071e7f9f37c80cf50bad81dcc
2022-01-25 11:32:52 +01:00
0fb3a93a03 wireguard: add async mode for decryption packets
Originally wireguard doesn't support async mode for decryption packets.

This patch add async mode for decryption in wireguard.
In addition, it contains some performance improvement such as
prefetching packet header and reducing the number of current time
function calls.

Type: improvement

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: Ieba6ae0078f3ff140c05b517891afb57232b3b7d
(cherry picked from commit 77e69ae2d1)
2022-01-25 11:25:16 +01:00
65c070f9da wireguard: add async mode for encryption packets
Originally wireguard doesn't support async mode for encryption packets.

This patch add async mode for encryption in wireguard and also adds
support chacha20-poly1305 algorithm in cryptodev for async handler.
In addition it contains new command line to activate async mode for wireguard:
  set wireguard async mode on|off

and also add new command to check active mode for wireguard:
  show wireguard mode

Type: improvement

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I141d48b42ee8dbff0112b8542ab5205268089da6
(cherry picked from commit 492d7790ff)
2022-01-25 11:04:23 +01:00
ab2478ceed wireguard: add burst mode
Originally wireguard does packet by packet encryption and decryption.

This patch adds burst mode for encryption and decryption packets. In
addition, it contains some performance improvement such as prefetching
packet header and reducing the number of current time function calls.

Type: improvement

Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: I04c7daa9b6dc56cd15c789661a64ec642b35aa3f
(cherry picked from commit 8ca08496a4)
2022-01-24 10:01:42 +00:00
93e5bea2d3 misc: Initial changes for stable/2202 branch
Change-Id: I23e72a788d6f382601945986c8cb8cfc3bb9da8e
Type: docs
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2022-01-19 13:48:39 +01:00
17 changed files with 1435 additions and 302 deletions

View File

@ -2,3 +2,4 @@
host=gerrit.fd.io
port=29418
project=vpp
defaultbranch=stable/2202

View File

@ -51,12 +51,19 @@ prepare_aead_xform (struct rte_crypto_sym_xform *xform,
xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
xform->next = 0;
if (key->alg != VNET_CRYPTO_ALG_AES_128_GCM &&
key->alg != VNET_CRYPTO_ALG_AES_192_GCM &&
key->alg != VNET_CRYPTO_ALG_AES_256_GCM)
if (key->alg == VNET_CRYPTO_ALG_AES_128_GCM ||
key->alg == VNET_CRYPTO_ALG_AES_192_GCM ||
key->alg == VNET_CRYPTO_ALG_AES_256_GCM)
{
aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
}
else if (key->alg == VNET_CRYPTO_ALG_CHACHA20_POLY1305)
{
aead_xform->algo = RTE_CRYPTO_AEAD_CHACHA20_POLY1305;
}
else
return -1;
aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
aead_xform->op = (op_type == CRYPTODEV_OP_TYPE_ENCRYPT) ?
RTE_CRYPTO_AEAD_OP_ENCRYPT : RTE_CRYPTO_AEAD_OP_DECRYPT;
aead_xform->aad_length = aad_len;

View File

@ -43,7 +43,10 @@
_ (AES_192_GCM, AEAD, AES_GCM, 12, 16, 8, 24) \
_ (AES_192_GCM, AEAD, AES_GCM, 12, 16, 12, 24) \
_ (AES_256_GCM, AEAD, AES_GCM, 12, 16, 8, 32) \
_ (AES_256_GCM, AEAD, AES_GCM, 12, 16, 12, 32)
_ (AES_256_GCM, AEAD, AES_GCM, 12, 16, 12, 32) \
_ (CHACHA20_POLY1305, AEAD, CHACHA20_POLY1305, 12, 16, 0, 32) \
_ (CHACHA20_POLY1305, AEAD, CHACHA20_POLY1305, 12, 16, 8, 32) \
_ (CHACHA20_POLY1305, AEAD, CHACHA20_POLY1305, 12, 16, 12, 32)
/**
* crypto (alg, cryptodev_alg, key_size), hash (alg, digest-size)

View File

@ -458,6 +458,13 @@ cryptodev_frame_dequeue (vlib_main_t *vm, u32 *nb_elts_processed,
return frame;
}
static_always_inline int
cryptodev_enqueue_aead_aad_0_enc (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
{
return cryptodev_frame_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_ENCRYPT,
0);
}
static_always_inline int
cryptodev_enqueue_aead_aad_8_enc (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
@ -473,6 +480,13 @@ cryptodev_enqueue_aead_aad_12_enc (vlib_main_t *vm,
12);
}
static_always_inline int
cryptodev_enqueue_aead_aad_0_dec (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
{
return cryptodev_frame_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_DECRYPT,
0);
}
static_always_inline int
cryptodev_enqueue_aead_aad_8_dec (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)

View File

@ -349,7 +349,7 @@ cryptodev_raw_aead_enqueue (vlib_main_t *vm, vnet_crypto_async_frame_t *frame,
if (aad_len == 8)
*(u64 *) (cet->aad_buf + aad_offset) = *(u64 *) fe->aad;
else
else if (aad_len != 0)
{
/* aad_len == 12 */
*(u64 *) (cet->aad_buf + aad_offset) = *(u64 *) fe->aad;
@ -591,6 +591,13 @@ end_deq:
return frame_ret;
}
static_always_inline int
cryptodev_raw_enq_aead_aad_0_enc (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
{
return cryptodev_raw_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_ENCRYPT, 0);
}
static_always_inline int
cryptodev_raw_enq_aead_aad_8_enc (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
@ -604,6 +611,13 @@ cryptodev_raw_enq_aead_aad_12_enc (vlib_main_t *vm,
return cryptodev_raw_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_ENCRYPT, 12);
}
static_always_inline int
cryptodev_raw_enq_aead_aad_0_dec (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)
{
return cryptodev_raw_aead_enqueue (vm, frame, CRYPTODEV_OP_TYPE_DECRYPT, 0);
}
static_always_inline int
cryptodev_raw_enq_aead_aad_8_dec (vlib_main_t *vm,
vnet_crypto_async_frame_t *frame)

View File

@ -195,6 +195,17 @@ define wireguard_peers_details {
vl_api_wireguard_peer_t peer;
};
/** \brief Wireguard Set Async mode
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param async_enable - wireguard async mode on or off
*/
autoreply define wg_set_async_mode {
u32 client_index;
u32 context;
bool async_enable;
};
/*
* Local Variables:
* eval: (c-set-style "gnu")

View File

@ -16,6 +16,7 @@
#include <vnet/vnet.h>
#include <vnet/plugin/plugin.h>
#include <vpp/app/version.h>
#include <vnet/crypto/crypto.h>
#include <wireguard/wireguard_send.h>
#include <wireguard/wireguard_key.h>
@ -23,6 +24,40 @@
#include <wireguard/wireguard.h>
wg_main_t wg_main;
wg_async_post_next_t wg_encrypt_async_next;
wg_async_post_next_t wg_decrypt_async_next;
void
wg_set_async_mode (u32 is_enabled)
{
vnet_crypto_request_async_mode (is_enabled);
if (is_enabled)
wg_op_mode_set_ASYNC ();
else
wg_op_mode_unset_ASYNC ();
}
static void
wireguard_register_post_node (vlib_main_t *vm)
{
wg_async_post_next_t *eit;
wg_async_post_next_t *dit;
eit = &wg_encrypt_async_next;
dit = &wg_decrypt_async_next;
eit->wg4_post_next =
vnet_crypto_register_post_node (vm, "wg4-output-tun-post-node");
eit->wg6_post_next =
vnet_crypto_register_post_node (vm, "wg6-output-tun-post-node");
dit->wg4_post_next =
vnet_crypto_register_post_node (vm, "wg4-input-post-node");
dit->wg6_post_next =
vnet_crypto_register_post_node (vm, "wg6-input-post-node");
}
static clib_error_t *
wg_init (vlib_main_t * vm)
@ -44,6 +79,8 @@ wg_init (vlib_main_t * vm)
CLIB_CACHE_LINE_BYTES);
wg_timer_wheel_init ();
wireguard_register_post_node (vm);
wmp->op_mode_flags = 0;
return (NULL);
}

View File

@ -28,6 +28,9 @@ extern vlib_node_registration_t wg6_output_tun_node;
typedef struct wg_per_thread_data_t_
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
vnet_crypto_op_t *crypto_ops;
vnet_crypto_async_frame_t **async_frames;
u8 data[WG_DEFAULT_DATA_SIZE];
} wg_per_thread_data_t;
typedef struct
@ -48,12 +51,70 @@ typedef struct
u8 feature_init;
tw_timer_wheel_16t_2w_512sl_t timer_wheel;
/* operation mode flags (e.g. async) */
u8 op_mode_flags;
} wg_main_t;
typedef struct
{
/* wg post node index for async crypto */
u32 wg4_post_next;
u32 wg6_post_next;
} wg_async_post_next_t;
extern wg_async_post_next_t wg_encrypt_async_next;
extern wg_async_post_next_t wg_decrypt_async_next;
extern wg_main_t wg_main;
/**
* Wireguard operation mode
**/
#define foreach_wg_op_mode_flags _ (0, ASYNC, "async")
/**
* Helper function to set/unset and check op modes
**/
typedef enum wg_op_mode_flags_t_
{
#define _(v, f, s) WG_OP_MODE_FLAG_##f = 1 << v,
foreach_wg_op_mode_flags
#undef _
} __clib_packed wg_op_mode_flags_t;
#define _(a, v, s) \
always_inline int wg_op_mode_set_##v (void) \
{ \
return (wg_main.op_mode_flags |= WG_OP_MODE_FLAG_##v); \
} \
always_inline int wg_op_mode_unset_##v (void) \
{ \
return (wg_main.op_mode_flags &= ~WG_OP_MODE_FLAG_##v); \
} \
always_inline int wg_op_mode_is_set_##v (void) \
{ \
return (wg_main.op_mode_flags & WG_OP_MODE_FLAG_##v); \
}
foreach_wg_op_mode_flags
#undef _
typedef struct
{
u8 __pad[22];
u16 next_index;
} wg_post_data_t;
STATIC_ASSERT (sizeof (wg_post_data_t) <=
STRUCT_SIZE_OF (vnet_buffer_opaque_t, unused),
"Custom meta-data too large for vnet_buffer_opaque_t");
#define wg_post_data(b) \
((wg_post_data_t *) ((u8 *) ((b)->opaque) + \
STRUCT_OFFSET_OF (vnet_buffer_opaque_t, unused)))
#define WG_START_EVENT 1
void wg_feature_init (wg_main_t * wmp);
void wg_set_async_mode (u32 is_enabled);
#endif /* __included_wg_h__ */

View File

@ -365,6 +365,18 @@ wg_api_peer_event (index_t peeri, wg_peer_flags flags)
};
}
static void
vl_api_wg_set_async_mode_t_handler (vl_api_wg_set_async_mode_t *mp)
{
wg_main_t *wmp = &wg_main;
vl_api_wg_set_async_mode_reply_t *rmp;
int rv = 0;
wg_set_async_mode (mp->async_enable);
REPLY_MACRO (VL_API_WG_SET_ASYNC_MODE_REPLY);
}
/* set tup the API message handling tables */
#include <wireguard/wireguard.api.c>
static clib_error_t *

View File

@ -356,6 +356,61 @@ VLIB_CLI_COMMAND (wg_show_itfs_command, static) =
.short_help = "show wireguard",
.function = wg_show_if_command_fn,
};
static clib_error_t *
wg_set_async_mode_command_fn (vlib_main_t *vm, unformat_input_t *input,
vlib_cli_command_t *cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
int async_enable = 0;
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (line_input, "on"))
async_enable = 1;
else if (unformat (line_input, "off"))
async_enable = 0;
else
return (clib_error_return (0, "unknown input '%U'",
format_unformat_error, line_input));
}
wg_set_async_mode (async_enable);
unformat_free (line_input);
return (NULL);
}
VLIB_CLI_COMMAND (wg_set_async_mode_command, static) = {
.path = "set wireguard async mode",
.short_help = "set wireguard async mode on|off",
.function = wg_set_async_mode_command_fn,
};
static clib_error_t *
wg_show_mode_command_fn (vlib_main_t *vm, unformat_input_t *input,
vlib_cli_command_t *cmd)
{
vlib_cli_output (vm, "Wireguard mode");
#define _(v, f, s) \
vlib_cli_output (vm, "\t%s: %s", s, \
(wg_op_mode_is_set_##f () ? "enabled" : "disabled"));
foreach_wg_op_mode_flags
#undef _
return (NULL);
}
VLIB_CLI_COMMAND (wg_show_modemode_command, static) = {
.path = "show wireguard mode",
.short_help = "show wireguard mode",
.function = wg_show_mode_command_fn,
};
/* *INDENT-ON* */
/*

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ static uint32_t noise_remote_handshake_index_get (noise_remote_t *);
static void noise_remote_handshake_index_drop (noise_remote_t *);
static uint64_t noise_counter_send (noise_counter_t *);
static bool noise_counter_recv (noise_counter_t *, uint64_t);
bool noise_counter_recv (noise_counter_t *, uint64_t);
static void noise_kdf (uint8_t *, uint8_t *, uint8_t *, const uint8_t *,
size_t, size_t, size_t, size_t,
@ -407,6 +407,8 @@ noise_remote_begin_session (vlib_main_t * vm, noise_remote_t * r)
/* Now we need to add_new_keypair */
clib_rwlock_writer_lock (&r->r_keypair_lock);
/* Activate barrier to synchronization keys between threads */
vlib_worker_thread_barrier_sync (vm);
next = r->r_next;
current = r->r_current;
previous = r->r_previous;
@ -438,6 +440,7 @@ noise_remote_begin_session (vlib_main_t * vm, noise_remote_t * r)
r->r_next = noise_remote_keypair_allocate (r);
*r->r_next = kp;
}
vlib_worker_thread_barrier_release (vm);
clib_rwlock_writer_unlock (&r->r_keypair_lock);
secure_zero_memory (&r->r_handshake, sizeof (r->r_handshake));
@ -591,88 +594,6 @@ error:
return ret;
}
enum noise_state_crypt
noise_remote_decrypt (vlib_main_t * vm, noise_remote_t * r, uint32_t r_idx,
uint64_t nonce, uint8_t * src, size_t srclen,
uint8_t * dst)
{
noise_keypair_t *kp;
enum noise_state_crypt ret = SC_FAILED;
if (r->r_current != NULL && r->r_current->kp_local_index == r_idx)
{
kp = r->r_current;
}
else if (r->r_previous != NULL && r->r_previous->kp_local_index == r_idx)
{
kp = r->r_previous;
}
else if (r->r_next != NULL && r->r_next->kp_local_index == r_idx)
{
kp = r->r_next;
}
else
{
goto error;
}
/* We confirm that our values are within our tolerances. These values
* are the same as the encrypt routine.
*
* kp_ctr isn't locked here, we're happy to accept a racy read. */
if (wg_birthdate_has_expired (kp->kp_birthdate, REJECT_AFTER_TIME) ||
kp->kp_ctr.c_recv >= REJECT_AFTER_MESSAGES)
goto error;
/* Decrypt, then validate the counter. We don't want to validate the
* counter before decrypting as we do not know the message is authentic
* prior to decryption. */
if (!chacha20poly1305_calc (vm, src, srclen, dst, NULL, 0, nonce,
VNET_CRYPTO_OP_CHACHA20_POLY1305_DEC,
kp->kp_recv_index))
goto error;
if (!noise_counter_recv (&kp->kp_ctr, nonce))
goto error;
/* If we've received the handshake confirming data packet then move the
* next keypair into current. If we do slide the next keypair in, then
* we skip the REKEY_AFTER_TIME_RECV check. This is safe to do as a
* data packet can't confirm a session that we are an INITIATOR of. */
if (kp == r->r_next)
{
clib_rwlock_writer_lock (&r->r_keypair_lock);
if (kp == r->r_next && kp->kp_local_index == r_idx)
{
noise_remote_keypair_free (vm, r, &r->r_previous);
r->r_previous = r->r_current;
r->r_current = r->r_next;
r->r_next = NULL;
ret = SC_CONN_RESET;
clib_rwlock_writer_unlock (&r->r_keypair_lock);
goto error;
}
clib_rwlock_writer_unlock (&r->r_keypair_lock);
}
/* Similar to when we encrypt, we want to notify the caller when we
* are approaching our tolerances. We notify if:
* - we're the initiator and the current keypair is older than
* REKEY_AFTER_TIME_RECV seconds. */
ret = SC_KEEP_KEY_FRESH;
kp = r->r_current;
if (kp != NULL &&
kp->kp_valid &&
kp->kp_is_initiator &&
wg_birthdate_has_expired (kp->kp_birthdate, REKEY_AFTER_TIME_RECV))
goto error;
ret = SC_OK;
error:
return ret;
}
/* Private functions - these should not be called outside this file under any
* circumstances. */
static noise_keypair_t *
@ -683,21 +604,6 @@ noise_remote_keypair_allocate (noise_remote_t * r)
return kp;
}
static void
noise_remote_keypair_free (vlib_main_t * vm, noise_remote_t * r,
noise_keypair_t ** kp)
{
noise_local_t *local = noise_local_get (r->r_local_idx);
struct noise_upcall *u = &local->l_upcall;
if (*kp)
{
u->u_index_drop ((*kp)->kp_local_index);
vnet_crypto_key_del (vm, (*kp)->kp_send_index);
vnet_crypto_key_del (vm, (*kp)->kp_recv_index);
clib_mem_free (*kp);
}
}
static uint32_t
noise_remote_handshake_index_get (noise_remote_t * r)
{
@ -716,55 +622,6 @@ noise_remote_handshake_index_drop (noise_remote_t * r)
u->u_index_drop (hs->hs_local_index);
}
static uint64_t
noise_counter_send (noise_counter_t * ctr)
{
uint64_t ret;
ret = ctr->c_send++;
return ret;
}
static bool
noise_counter_recv (noise_counter_t * ctr, uint64_t recv)
{
uint64_t i, top, index_recv, index_ctr;
unsigned long bit;
bool ret = false;
/* Check that the recv counter is valid */
if (ctr->c_recv >= REJECT_AFTER_MESSAGES || recv >= REJECT_AFTER_MESSAGES)
goto error;
/* If the packet is out of the window, invalid */
if (recv + COUNTER_WINDOW_SIZE < ctr->c_recv)
goto error;
/* If the new counter is ahead of the current counter, we'll need to
* zero out the bitmap that has previously been used */
index_recv = recv / COUNTER_BITS;
index_ctr = ctr->c_recv / COUNTER_BITS;
if (recv > ctr->c_recv)
{
top = clib_min (index_recv - index_ctr, COUNTER_NUM);
for (i = 1; i <= top; i++)
ctr->c_backtrack[(i + index_ctr) & (COUNTER_NUM - 1)] = 0;
ctr->c_recv = recv;
}
index_recv %= COUNTER_NUM;
bit = 1ul << (recv % COUNTER_BITS);
if (ctr->c_backtrack[index_recv] & bit)
goto error;
ctr->c_backtrack[index_recv] |= bit;
ret = true;
error:
return ret;
}
static void
noise_kdf (uint8_t * a, uint8_t * b, uint8_t * c, const uint8_t * x,
size_t a_len, size_t b_len, size_t c_len, size_t x_len,

View File

@ -136,6 +136,14 @@ noise_local_get (uint32_t locali)
return (pool_elt_at_index (noise_local_pool, locali));
}
static_always_inline uint64_t
noise_counter_send (noise_counter_t *ctr)
{
uint64_t ret;
ret = ctr->c_send++;
return ret;
}
void noise_local_init (noise_local_t *, struct noise_upcall *);
bool noise_local_set_private (noise_local_t *,
const uint8_t[NOISE_PUBLIC_KEY_LEN]);
@ -187,12 +195,83 @@ noise_remote_encrypt (vlib_main_t * vm, noise_remote_t *,
uint32_t * r_idx,
uint64_t * nonce,
uint8_t * src, size_t srclen, uint8_t * dst);
enum noise_state_crypt
noise_remote_decrypt (vlib_main_t * vm, noise_remote_t *,
uint32_t r_idx,
uint64_t nonce,
uint8_t * src, size_t srclen, uint8_t * dst);
static_always_inline noise_keypair_t *
wg_get_active_keypair (noise_remote_t *r, uint32_t r_idx)
{
if (r->r_current != NULL && r->r_current->kp_local_index == r_idx)
{
return r->r_current;
}
else if (r->r_previous != NULL && r->r_previous->kp_local_index == r_idx)
{
return r->r_previous;
}
else if (r->r_next != NULL && r->r_next->kp_local_index == r_idx)
{
return r->r_next;
}
else
{
return NULL;
}
}
inline bool
noise_counter_recv (noise_counter_t *ctr, uint64_t recv)
{
uint64_t i, top, index_recv, index_ctr;
unsigned long bit;
bool ret = false;
/* Check that the recv counter is valid */
if (ctr->c_recv >= REJECT_AFTER_MESSAGES || recv >= REJECT_AFTER_MESSAGES)
goto error;
/* If the packet is out of the window, invalid */
if (recv + COUNTER_WINDOW_SIZE < ctr->c_recv)
goto error;
/* If the new counter is ahead of the current counter, we'll need to
* zero out the bitmap that has previously been used */
index_recv = recv / COUNTER_BITS;
index_ctr = ctr->c_recv / COUNTER_BITS;
if (recv > ctr->c_recv)
{
top = clib_min (index_recv - index_ctr, COUNTER_NUM);
for (i = 1; i <= top; i++)
ctr->c_backtrack[(i + index_ctr) & (COUNTER_NUM - 1)] = 0;
ctr->c_recv = recv;
}
index_recv %= COUNTER_NUM;
bit = 1ul << (recv % COUNTER_BITS);
if (ctr->c_backtrack[index_recv] & bit)
goto error;
ctr->c_backtrack[index_recv] |= bit;
ret = true;
error:
return ret;
}
static_always_inline void
noise_remote_keypair_free (vlib_main_t *vm, noise_remote_t *r,
noise_keypair_t **kp)
{
noise_local_t *local = noise_local_get (r->r_local_idx);
struct noise_upcall *u = &local->l_upcall;
if (*kp)
{
u->u_index_drop ((*kp)->kp_local_index);
vnet_crypto_key_del (vm, (*kp)->kp_send_index);
vnet_crypto_key_del (vm, (*kp)->kp_recv_index);
clib_mem_free (*kp);
}
}
#endif /* __included_wg_noise_h__ */

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,13 @@ get_random_u32_max (u32 max)
return random_u32 (&seed) % max;
}
static u32
get_random_u32_max_opt (u32 max, f64 time)
{
u32 seed = (u32) (time * 1e6);
return random_u32 (&seed) % max;
}
static void
stop_timer (wg_peer_t * peer, u32 timer_id)
{
@ -66,7 +73,7 @@ start_timer_thread_fn (void *arg)
return 0;
}
static void
static_always_inline void
start_timer_from_mt (u32 peer_idx, u32 timer_id, u32 interval_ticks)
{
wg_timers_args a = {
@ -197,8 +204,8 @@ wg_expired_zero_key_material (vlib_main_t * vm, wg_peer_t * peer)
}
}
void
wg_timers_any_authenticated_packet_traversal (wg_peer_t * peer)
inline void
wg_timers_any_authenticated_packet_traversal (wg_peer_t *peer)
{
if (peer->persistent_keepalive_interval)
{
@ -214,6 +221,12 @@ wg_timers_any_authenticated_packet_sent (wg_peer_t * peer)
peer->last_sent_packet = vlib_time_now (vlib_get_main ());
}
inline void
wg_timers_any_authenticated_packet_sent_opt (wg_peer_t *peer, f64 time)
{
peer->last_sent_packet = time;
}
void
wg_timers_handshake_initiated (wg_peer_t * peer)
{
@ -246,6 +259,17 @@ wg_timers_data_sent (wg_peer_t * peer)
peer->new_handshake_interval_tick);
}
inline void
wg_timers_data_sent_opt (wg_peer_t *peer, f64 time)
{
peer->new_handshake_interval_tick =
(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) * WHZ +
get_random_u32_max_opt (REKEY_TIMEOUT_JITTER, time);
start_timer_from_mt (peer - wg_peer_pool, WG_TIMER_NEW_HANDSHAKE,
peer->new_handshake_interval_tick);
}
/* Should be called after an authenticated data packet is received. */
void
wg_timers_data_received (wg_peer_t * peer)
@ -275,6 +299,12 @@ wg_timers_any_authenticated_packet_received (wg_peer_t * peer)
peer->last_received_packet = vlib_time_now (vlib_get_main ());
}
inline void
wg_timers_any_authenticated_packet_received_opt (wg_peer_t *peer, f64 time)
{
peer->last_received_packet = time;
}
static vlib_node_registration_t wg_timer_mngr_node;
static void

View File

@ -41,9 +41,13 @@ typedef struct wg_peer wg_peer_t;
void wg_timer_wheel_init ();
void wg_timers_stop (wg_peer_t * peer);
void wg_timers_data_sent (wg_peer_t * peer);
void wg_timers_data_sent_opt (wg_peer_t *peer, f64 time);
void wg_timers_data_received (wg_peer_t * peer);
void wg_timers_any_authenticated_packet_sent (wg_peer_t * peer);
void wg_timers_any_authenticated_packet_sent_opt (wg_peer_t *peer, f64 time);
void wg_timers_any_authenticated_packet_received (wg_peer_t * peer);
void wg_timers_any_authenticated_packet_received_opt (wg_peer_t *peer,
f64 time);
void wg_timers_handshake_initiated (wg_peer_t * peer);
void wg_timers_handshake_complete (wg_peer_t * peer);
void wg_timers_session_derived (wg_peer_t * peer);
@ -57,6 +61,13 @@ wg_birthdate_has_expired (f64 birthday_seconds, f64 expiration_seconds)
return (birthday_seconds + expiration_seconds) < now_seconds;
}
static_always_inline bool
wg_birthdate_has_expired_opt (f64 birthday_seconds, f64 expiration_seconds,
f64 time)
{
return (birthday_seconds + expiration_seconds) < time;
}
#endif /* __included_wg_timer_h__ */
/*

View File

@ -82,15 +82,16 @@ typedef enum
/** async crypto **/
/* CRYPTO_ID, PRETTY_NAME, KEY_LENGTH_IN_BYTES, TAG_LEN, AAD_LEN */
#define foreach_crypto_aead_async_alg \
_(AES_128_GCM, "aes-128-gcm-aad8", 16, 16, 8) \
_(AES_128_GCM, "aes-128-gcm-aad12", 16, 16, 12) \
_(AES_192_GCM, "aes-192-gcm-aad8", 24, 16, 8) \
_(AES_192_GCM, "aes-192-gcm-aad12", 24, 16, 12) \
_(AES_256_GCM, "aes-256-gcm-aad8", 32, 16, 8) \
_(AES_256_GCM, "aes-256-gcm-aad12", 32, 16, 12) \
_(CHACHA20_POLY1305, "chacha20-poly1305-aad8", 32, 16, 8) \
_(CHACHA20_POLY1305, "chacha20-poly1305-aad12", 32, 16, 12)
#define foreach_crypto_aead_async_alg \
_ (AES_128_GCM, "aes-128-gcm-aad8", 16, 16, 8) \
_ (AES_128_GCM, "aes-128-gcm-aad12", 16, 16, 12) \
_ (AES_192_GCM, "aes-192-gcm-aad8", 24, 16, 8) \
_ (AES_192_GCM, "aes-192-gcm-aad12", 24, 16, 12) \
_ (AES_256_GCM, "aes-256-gcm-aad8", 32, 16, 8) \
_ (AES_256_GCM, "aes-256-gcm-aad12", 32, 16, 12) \
_ (CHACHA20_POLY1305, "chacha20-poly1305-aad8", 32, 16, 8) \
_ (CHACHA20_POLY1305, "chacha20-poly1305-aad12", 32, 16, 12) \
_ (CHACHA20_POLY1305, "chacha20-poly1305", 32, 16, 0)
/* CRYPTO_ID, INTEG_ID, PRETTY_NAME, KEY_LENGTH_IN_BYTES, DIGEST_LEN */
#define foreach_crypto_link_async_alg \