From 3b37cc56e43447a0190e2240bb132588bc7be2b4 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 21 Oct 2020 01:08:40 -0500 Subject: [PATCH 01/33] fully functional crypto shim for wolfcrypt in wireguard --- src/Kbuild | 6 +- src/cookie.c | 2 + src/main.c | 2 + src/messages.h | 2 + src/wolfcrypto_shim.c | 215 ++++++++++++++++++++++++++++++++++++++++++ src/wolfcrypto_shim.h | 175 ++++++++++++++++++++++++++++++++++ 6 files changed, 401 insertions(+), 1 deletion(-) create mode 100644 src/wolfcrypto_shim.c create mode 100644 src/wolfcrypto_shim.h diff --git a/src/Kbuild b/src/Kbuild index a0d433f2..c02690ed 100644 --- a/src/Kbuild +++ b/src/Kbuild @@ -10,7 +10,11 @@ ccflags-$(if $(WIREGUARD_VERSION),y,) += -D'WIREGUARD_VERSION="$(WIREGUARD_VERSI wireguard-y := main.o noise.o device.o peer.o timers.o queueing.o send.o receive.o socket.o peerlookup.o allowedips.o ratelimiter.o cookie.o netlink.o -include $(src)/crypto/Kbuild.include +# include $(src)/crypto/Kbuild.include include $(src)/compat/Kbuild.include obj-$(if $(KBUILD_EXTMOD),m,$(CONFIG_WIREGUARD)) := wireguard.o + +ccflags-y += -I$(src)/../../../../wolfssl -include $(src)/wolfcrypto_shim.h +wireguard-y += wolfcrypto_shim.o +KBUILD_EXTRA_SYMBOLS := $(src)/../../../../wolfssl/linuxkm/Module.symvers diff --git a/src/cookie.c b/src/cookie.c index 8b7d1fe0..9e88a7d6 100644 --- a/src/cookie.c +++ b/src/cookie.c @@ -10,8 +10,10 @@ #include "ratelimiter.h" #include "timers.h" +#ifndef WOLFCRYPTO_SHIM_H #include #include +#endif #include #include diff --git a/src/main.c b/src/main.c index 54350115..05c97e8e 100644 --- a/src/main.c +++ b/src/main.c @@ -21,10 +21,12 @@ static int __init mod_init(void) { int ret; +#ifndef WOLFCRYPTO_SHIM_H if ((ret = chacha20_mod_init()) || (ret = poly1305_mod_init()) || (ret = chacha20poly1305_mod_init()) || (ret = blake2s_mod_init()) || (ret = curve25519_mod_init())) return ret; +#endif #ifdef DEBUG if (!wg_allowedips_selftest() || !wg_packet_counter_selftest() || diff --git a/src/messages.h b/src/messages.h index 1d1ed18f..811617cf 100644 --- a/src/messages.h +++ b/src/messages.h @@ -6,9 +6,11 @@ #ifndef _WG_MESSAGES_H #define _WG_MESSAGES_H +#ifndef WOLFCRYPTO_SHIM_H #include #include #include +#endif #include #include diff --git a/src/wolfcrypto_shim.c b/src/wolfcrypto_shim.c new file mode 100644 index 00000000..548c53ae --- /dev/null +++ b/src/wolfcrypto_shim.c @@ -0,0 +1,215 @@ +#include "wolfcrypto_shim.h" +#include + +#ifdef MODULE_IMPORT_NS +MODULE_IMPORT_NS(WOLFSSL); +#endif + +int curve25519_generate_public(uint8_t pub[static CURVE25519_KEY_SIZE], const uint8_t secret[static CURVE25519_KEY_SIZE]) { + uint8_t secret_copy[CURVE25519_KEY_SIZE]; /* pubkey_main() calls curve25519_generate_public() with pub == secret, which doesn't work for wc_curve25519_make_pub(). */ + XMEMCPY(secret_copy, secret, CURVE25519_KEY_SIZE); + return !DBG_PRNT_NZ(wc_curve25519_make_pub(CURVE25519_KEY_SIZE, pub, CURVE25519_KEY_SIZE, secret_copy)); +} + +int curve25519_generate_secret(u8 secret[CURVE25519_KEY_SIZE]) { + WC_RNG *gRng = wc_rng_new(NULL /* nonce */, 0 /* nonceSz */, NULL /*heap */); + if (gRng) { + (void)DBG_PRNT_NZ(wc_curve25519_make_priv(gRng, (int)CURVE25519_KEY_SIZE, (byte *)secret)); + wc_rng_free(gRng); + return 0; + } else + return -ENOMEM; +} + +int blake2s(byte *out, const void *in, const void *key, const byte outlen, + const word32 inlen, byte keylen) +{ + Blake2s state; + + if ((in == NULL) || (out == NULL)) + return -1; + + if (DBG_PRNT_NZ(wc_InitBlake2s_WithKey(&state, (word32)outlen, (const byte *)key, (word32)keylen)) < 0) + return -1; + if (DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)in, inlen)) < 0) + return -1; + return DBG_PRNT_NZ(wc_Blake2sFinal(&state, out, (word32)outlen)); +} + +void blake2s_hmac(byte *out, const byte *in, const byte *key, size_t outlen, size_t inlen, size_t keylen) { + Blake2s state; + word32 x_key[BLAKE2S_BLOCK_SIZE / sizeof(word32)]; + word32 i_hash[BLAKE2S_HASH_SIZE / sizeof(word32)]; + int i; + + if (outlen != BLAKE2S_HASH_SIZE) + return; + + if (keylen > BLAKE2S_BLOCK_SIZE) { + DBG_PRNT_NZ(wc_InitBlake2s(&state, BLAKE2S_HASH_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, key, keylen)); + DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)x_key, 0)); + } else { + XMEMCPY(x_key, key, keylen); + XMEMSET((byte *)x_key + keylen, 0, BLAKE2S_BLOCK_SIZE - keylen); + } + + for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) + ((byte *)x_key)[i] ^= 0x36; + + DBG_PRNT_NZ(wc_InitBlake2s(&state, BLAKE2S_HASH_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)x_key, BLAKE2S_BLOCK_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, in, inlen)); + DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)i_hash, 0)); + + for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) + ((byte *)x_key)[i] ^= 0x5c ^ 0x36; + + DBG_PRNT_NZ(wc_InitBlake2s(&state, BLAKE2S_HASH_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)x_key, BLAKE2S_BLOCK_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)i_hash, BLAKE2S_HASH_SIZE)); + DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)i_hash, 0)); + + XMEMCPY(out, i_hash, BLAKE2S_HASH_SIZE); + XMEMSET(x_key, 0, BLAKE2S_BLOCK_SIZE); + XMEMSET(i_hash, 0, BLAKE2S_HASH_SIZE); +} + +void blake2s256_hmac(byte *out, const byte *in, const byte *key, size_t inlen, size_t keylen) { + blake2s_hmac(out, in, key, BLAKE2S_HASH_SIZE, inlen, keylen); +} + +static bool chacha20poly1305_crypt_sg_inplace(struct scatterlist *src, + const size_t src_len, + const u8 *ad, const size_t ad_len, + const u64 nonce, + const u8 key[CHACHA20POLY1305_KEY_SIZE], + int isEncrypt) +{ + int ret = -1; + struct sg_mapping_iter miter; + unsigned int flags; + int sl; + ChaChaPoly_Aead *aead = (ChaChaPoly_Aead *)XMALLOC(sizeof *aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if (WARN_ON(src_len > INT_MAX)) { + ret = BAD_FUNC_ARG; + goto out; + } + + { + byte IV[CHACHA20_POLY1305_AEAD_IV_SIZE] = {}; + memcpy(IV + 4, (byte *)&nonce, sizeof nonce); + if (WARN_ON(wc_ChaCha20Poly1305_Init(aead, key, IV, isEncrypt) < 0)) + goto out; + XMEMSET(IV, 0, sizeof IV); + } + + flags = SG_MITER_TO_SG; + if (!preemptible()) + flags |= SG_MITER_ATOMIC; + + sg_miter_start(&miter, src, sg_nents(src), flags); + + for (sl = src_len; sl > 0 && sg_miter_next(&miter); sl -= miter.length) { + size_t length = min_t(size_t, sl, miter.length); + + if (! isEncrypt) { + if ((ret = wc_Poly1305Update(&aead->poly, miter.addr, length)) < 0) + goto out; + } + + if ((ret = wc_Chacha_Process(&aead->chacha, miter.addr, miter.addr, length)) < 0) + goto out; + + if (isEncrypt) { + if ((ret = wc_Poly1305Update(&aead->poly, miter.addr, length)) < 0) + goto out; + } + } + + if (aead->poly.leftover) { + if ((ret = wc_Poly1305_Pad(&aead->poly, (word32)aead->poly.leftover)) < 0) + goto out; + } + + if ((ret = wc_Poly1305_EncodeSizes(&aead->poly, ad_len, src_len)) < 0) + goto out; + + if (sl <= -POLY1305_DIGEST_SIZE) { + + if (isEncrypt) { + if ((ret = wc_Poly1305Final(&aead->poly, miter.addr + miter.length + sl)) < 0) + goto out; + } else { + byte outAuthTag[POLY1305_DIGEST_SIZE]; + + if ((ret = wc_Poly1305Final(&aead->poly, outAuthTag)) < 0) + goto out; + + if (ConstantCompare(outAuthTag, miter.addr + miter.length + sl, POLY1305_DIGEST_SIZE) != 0) { + ret = MAC_CMP_FAILED_E; + goto out; + } + } + } + + sg_miter_stop(&miter); + + if (sl > -POLY1305_DIGEST_SIZE) { + byte outAuthTag[POLY1305_DIGEST_SIZE]; + wc_Poly1305Final(&aead->poly, outAuthTag); + if (isEncrypt) { + scatterwalk_map_and_copy(outAuthTag, src, src_len, + sizeof outAuthTag, isEncrypt); + } else { + byte refAuthTag[POLY1305_DIGEST_SIZE]; + scatterwalk_map_and_copy(refAuthTag, src, src_len, + sizeof outAuthTag, isEncrypt); + if (ConstantCompare(outAuthTag, refAuthTag, POLY1305_DIGEST_SIZE) != 0) { + ret = MAC_CMP_FAILED_E; + goto out; + } + } + } + + ret = 0; + + out: + + if (aead) { + XMEMSET(&aead, 0, sizeof aead); + XFREE(aead, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + (void)DBG_PRNT_NZ(ret); + + return ret == 0; +} + +bool chacha20poly1305_encrypt_sg_inplace(struct scatterlist *src, size_t src_len, + const u8 *ad, const size_t ad_len, + const u64 nonce, + const u8 key[CHACHA20POLY1305_KEY_SIZE], + simd_context_t *simd_context) +{ + (void)simd_context; + return chacha20poly1305_crypt_sg_inplace(src, src_len, ad, ad_len, + nonce, key, 1); +} + +bool chacha20poly1305_decrypt_sg_inplace(struct scatterlist *src, size_t src_len, + const u8 *ad, const size_t ad_len, + const u64 nonce, + const u8 key[CHACHA20POLY1305_KEY_SIZE], + simd_context_t *simd_context) +{ + (void)simd_context; + + if (unlikely(src_len < POLY1305_DIGEST_SIZE)) + return false; + + return chacha20poly1305_crypt_sg_inplace(src, + src_len - POLY1305_DIGEST_SIZE, + ad, ad_len, nonce, key, 0); +} diff --git a/src/wolfcrypto_shim.h b/src/wolfcrypto_shim.h new file mode 100644 index 00000000..c6159ee8 --- /dev/null +++ b/src/wolfcrypto_shim.h @@ -0,0 +1,175 @@ +#ifndef WOLFCRYPTO_SHIM_H +#define WOLFCRYPTO_SHIM_H + +#include +#ifndef WOLFSSL_LINUXKM +#error libwolfssl configured without --enable-linuxkm +#endif +#ifndef HAVE_CURVE25519 +#error libwolfssl missing HAVE_CURVE25519 +#endif +#ifndef HAVE_BLAKE2S +#error libwolfssl missing HAVE_BLAKE2S +#endif +#ifndef HAVE_CHACHA +#error libwolfssl missing HAVE_CHACHA +#endif +#ifndef HAVE_POLY1305 +#error libwolfssl missing HAVE_POLY1305 +#endif + +#undef SHA256_BLOCK_SIZE +#undef SHA256_DIGEST_SIZE +#undef SHA224_BLOCK_SIZE +#undef SHA224_DIGEST_SIZE +#undef CURVE25519_KEYSIZE + +#include +#include +#define WOLFSSL_MISC_INCLUDED +#undef min +#undef max +#include + +#include +#define CURVE25519_KEY_SIZE CURVE25519_KEYSIZE + +#include + +#include +#define CHACHA20POLY1305_KEY_SIZE CHACHA20_POLY1305_AEAD_KEYSIZE +#define CHACHA20POLY1305_AUTHTAG_SIZE CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE +#define XCHACHA20POLY1305_NONCE_SIZE 24 /* CHACHA20_POLY1305_AEAD_IV_SIZE * 2 */ + +#include + +#include +#define BLAKE2S_HASH_SIZE BLAKE2S_256 +#define BLAKE2S_BLOCK_SIZE 64 + +#include +#include +#include +#include + +#ifdef DEBUG +#define DBG_PRNT_NZ(...) ({ int _ret = (__VA_ARGS__); if (_ret) printk(KERN_NOTICE "%s@%d: %d\n", __FILE__, __LINE__, _ret); _ret; }) +#else +#define DBG_PRNT_NZ(...) (__VA_ARGS__) +#endif + +struct blake2s_state { + Blake2s blake2s; +}; +#define blake2s_init(...) wc_wg_blake2s_init(__VA_ARGS__) +static void __attribute__((unused)) inline blake2s_init(struct blake2s_state *state, size_t outlen) { + DBG_PRNT_NZ(wc_InitBlake2s(&state->blake2s, (word32)outlen)); +} +#define blake2s_init_key(...) wc_wg_blake2s_init_key(__VA_ARGS__) +static void __attribute__((unused)) inline blake2s_init_key(struct blake2s_state *state, size_t outlen, const void *key, + const size_t keylen) { + DBG_PRNT_NZ(wc_InitBlake2s_WithKey(&state->blake2s, (word32)outlen, (const byte *)key, (word32)keylen)); +} +#define blake2s_update(...) wc_wg_blake2s_update(__VA_ARGS__) +static void __attribute__((unused)) inline blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen) { + DBG_PRNT_NZ(wc_Blake2sUpdate(&state->blake2s, (const byte *)in, (word32)inlen)); +} +#define blake2s_final(...) wc_wg_blake2s_final(__VA_ARGS__) +static void __attribute__((unused)) inline blake2s_final(struct blake2s_state *state, const u8 *out) { + DBG_PRNT_NZ(wc_Blake2sFinal(&state->blake2s, (byte *)out, 0)); +} + +#define blake2s(...) wc_wg_simple_blake2s(__VA_ARGS__) +extern int blake2s(byte *out, const void *in, const void *key, const byte outlen, + const word32 inlen, byte keylen); + +#define blake2s256_hmac(...) wc_wg_blake2s256_hmac(__VA_ARGS__) +extern void blake2s256_hmac(byte *out, const byte *in, const byte *key, size_t inlen, size_t keylen); + +#define blake2s_hmac(...) wc_wg_blake2s_hmac(__VA_ARGS__) +extern void blake2s_hmac(byte *out, const byte *in, const byte *key, size_t outlen, size_t inlen, size_t keylen); + +#define curve25519_generate_public(...) curve25519_generate_public_wolfshim(__VA_ARGS__) +extern int curve25519_generate_public(uint8_t pub[static CURVE25519_KEYSIZE], const uint8_t secret[static CURVE25519_KEYSIZE]); + +#define curve25519_generate_secret(...) curve25519_generate_secret_wolfshim(__VA_ARGS__) +extern int curve25519_generate_secret(u8 secret[CURVE25519_KEY_SIZE]); + +#define curve25519_clamp_secret(...) curve25519_clamp_secret_wolfshim(__VA_ARGS__) +static inline void curve25519_clamp_secret(u8 key[CURVE25519_KEY_SIZE]) +{ + key[0] &= 248; + key[CURVE25519_KEY_SIZE-1] &= 63; /* same &=127 because |=64 after */ + key[CURVE25519_KEY_SIZE-1] |= 64; +} + +#define curve25519(...) curve25519_wolfshim(__VA_ARGS__) +static inline bool curve25519(uint8_t mypublic[static CURVE25519_KEY_SIZE], const uint8_t secret[static CURVE25519_KEY_SIZE], const uint8_t basepoint[static CURVE25519_KEY_SIZE]) { + return (wc_curve25519_generic(CURVE25519_KEY_SIZE, (byte *)mypublic, CURVE25519_KEY_SIZE, (byte *)secret, CURVE25519_KEY_SIZE, (byte *)basepoint) == 0 ? true : false); +} + +static __attribute__((unused)) inline void +chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len, + const u8 *ad, const size_t ad_len, + const u64 nonce, + const u8 key[CHACHA20POLY1305_KEY_SIZE]) { + word64 inIV[2] = { 0, cpu_to_le64(nonce) }; + ChaChaPoly_Aead aead; + + if (DBG_PRNT_NZ(wc_ChaCha20Poly1305_Init(&aead, key, (const byte *)inIV, + CHACHA20_POLY1305_AEAD_ENCRYPT))) + return; + + DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateAad(&aead, ad, (u32)ad_len)); + if (src_len) + DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateData(&aead, src, dst, + (u32)src_len)); + DBG_PRNT_NZ(wc_ChaCha20Poly1305_Final(&aead, dst + src_len)); +} + +static __attribute__((unused)) inline bool +chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len, + const u8 *ad, const size_t ad_len, + const u64 nonce, + const u8 key[CHACHA20POLY1305_KEY_SIZE]) { + word64 inIV[2] = { 0, cpu_to_le64(nonce) }; + + int ret = 0; + ChaChaPoly_Aead aead; + byte calculatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE] = {}; + + if (DBG_PRNT_NZ + (wc_ChaCha20Poly1305_Init(&aead, key, (const u8 *)inIV + sizeof inIV - CHACHA20_POLY1305_AEAD_IV_SIZE, + CHACHA20_POLY1305_AEAD_DECRYPT))) + return false; + ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateAad(&aead, ad, (u32)ad_len)); + if (dst) + ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateData(&aead, src, dst, src_len - CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE)); + ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_Final(&aead, calculatedAuthTag)); + ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_CheckTag(src + src_len - CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, calculatedAuthTag)); + + return ret == 0; +} + +#define xchacha20poly1305_encrypt(dst, src, src_len, ad, ad_len, nonce, key) \ + DBG_PRNT_NZ(wc_XChaCha20Poly1305_encrypt_oneshot(dst, (src_len) + POLY1305_DIGEST_SIZE, src, src_len, ad, ad_len, nonce, XCHACHA20POLY1305_NONCE_SIZE, key, CHACHA20POLY1305_KEY_SIZE)) +#define xchacha20poly1305_decrypt(dst, src, src_len, ad, ad_len, nonce, key) \ + (DBG_PRNT_NZ(wc_XChaCha20Poly1305_decrypt_oneshot(dst, (src_len) - POLY1305_DIGEST_SIZE, src, src_len, ad, ad_len, nonce, XCHACHA20POLY1305_NONCE_SIZE, key, CHACHA20POLY1305_KEY_SIZE)) == 0) + +#define chacha20poly1305_encrypt_sg_inplace(...) \ + chacha20poly1305_encrypt_sg_inplace_wolfshim(__VA_ARGS__) +extern bool chacha20poly1305_encrypt_sg_inplace(struct scatterlist *src, size_t src_len, + const u8 *ad, const size_t ad_len, + const u64 nonce, + const u8 key[CHACHA20POLY1305_KEY_SIZE], + simd_context_t *simd_context); + +#define chacha20poly1305_decrypt_sg_inplace(...) \ + chacha20poly1305_decrypt_sg_inplace_wolfshim(__VA_ARGS__) +extern bool chacha20poly1305_decrypt_sg_inplace(struct scatterlist *src, size_t src_len, + const u8 *ad, const size_t ad_len, + const u64 nonce, + const u8 key[CHACHA20POLY1305_KEY_SIZE], + simd_context_t *simd_context); + +#endif From 8bedf4468d26ca8b925f8747069e850f77686e7d Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 21 Oct 2020 14:47:23 -0500 Subject: [PATCH 02/33] rename API wc_XChaCha20Poly1305_{encrypt,decrypt}_oneshot to wc_XChaCha20Poly1305_{Encrypt,Decrypt}. --- src/wolfcrypto_shim.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wolfcrypto_shim.h b/src/wolfcrypto_shim.h index c6159ee8..482580a0 100644 --- a/src/wolfcrypto_shim.h +++ b/src/wolfcrypto_shim.h @@ -152,9 +152,9 @@ chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len, } #define xchacha20poly1305_encrypt(dst, src, src_len, ad, ad_len, nonce, key) \ - DBG_PRNT_NZ(wc_XChaCha20Poly1305_encrypt_oneshot(dst, (src_len) + POLY1305_DIGEST_SIZE, src, src_len, ad, ad_len, nonce, XCHACHA20POLY1305_NONCE_SIZE, key, CHACHA20POLY1305_KEY_SIZE)) + DBG_PRNT_NZ(wc_XChaCha20Poly1305_Encrypt(dst, (src_len) + POLY1305_DIGEST_SIZE, src, src_len, ad, ad_len, nonce, XCHACHA20POLY1305_NONCE_SIZE, key, CHACHA20POLY1305_KEY_SIZE)) #define xchacha20poly1305_decrypt(dst, src, src_len, ad, ad_len, nonce, key) \ - (DBG_PRNT_NZ(wc_XChaCha20Poly1305_decrypt_oneshot(dst, (src_len) - POLY1305_DIGEST_SIZE, src, src_len, ad, ad_len, nonce, XCHACHA20POLY1305_NONCE_SIZE, key, CHACHA20POLY1305_KEY_SIZE)) == 0) + (DBG_PRNT_NZ(wc_XChaCha20Poly1305_Decrypt(dst, (src_len) - POLY1305_DIGEST_SIZE, src, src_len, ad, ad_len, nonce, XCHACHA20POLY1305_NONCE_SIZE, key, CHACHA20POLY1305_KEY_SIZE)) == 0) #define chacha20poly1305_encrypt_sg_inplace(...) \ chacha20poly1305_encrypt_sg_inplace_wolfshim(__VA_ARGS__) From 65ae51cac66be6cf481e4c2a3077895b00087222 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 23 Oct 2020 17:01:43 -0500 Subject: [PATCH 03/33] pivot wolfcryptified build of wireguard.ko on `make WOLFCRYPT=1` (as already for wireguard-tools); tweak compat.h to allow building on kernels >= 5.6.0. --- src/Kbuild | 8 ++++++-- src/compat/compat.h | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Kbuild b/src/Kbuild index c02690ed..1fd6a385 100644 --- a/src/Kbuild +++ b/src/Kbuild @@ -10,11 +10,15 @@ ccflags-$(if $(WIREGUARD_VERSION),y,) += -D'WIREGUARD_VERSION="$(WIREGUARD_VERSI wireguard-y := main.o noise.o device.o peer.o timers.o queueing.o send.o receive.o socket.o peerlookup.o allowedips.o ratelimiter.o cookie.o netlink.o -# include $(src)/crypto/Kbuild.include +ifndef WOLFCRYPT +include $(src)/crypto/Kbuild.include +endif include $(src)/compat/Kbuild.include obj-$(if $(KBUILD_EXTMOD),m,$(CONFIG_WIREGUARD)) := wireguard.o -ccflags-y += -I$(src)/../../../../wolfssl -include $(src)/wolfcrypto_shim.h +ifdef WOLFCRYPT +ccflags-y += -DUSE_WOLFCRYPT -I$(src)/../../../../wolfssl -include $(src)/wolfcrypto_shim.h wireguard-y += wolfcrypto_shim.o KBUILD_EXTRA_SYMBOLS := $(src)/../../../../wolfssl/linuxkm/Module.symvers +endif diff --git a/src/compat/compat.h b/src/compat/compat.h index 9f6e725d..1aeaa217 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -42,9 +42,9 @@ #error "WireGuard requires Linux >= 3.10" #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) -#error "WireGuard has been merged into Linux >= 5.6 and therefore this compatibility module is no longer required." -#endif +/* #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) */ +/* #error "WireGuard has been merged into Linux >= 5.6 and therefore this compatibility module is no longer required." */ +/* #endif */ #if defined(ISRHEL7) #include @@ -872,7 +872,7 @@ static inline void skb_mark_not_on_list(struct sk_buff *skb) #endif #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0) +#if !defined(USE_WOLFCRYPT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)) #define blake2s_init zinc_blake2s_init #define blake2s_init_key zinc_blake2s_init_key #define blake2s_update zinc_blake2s_update From f7a021e616106edd6eb143602379c83412968bc3 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 30 Oct 2020 14:25:58 -0500 Subject: [PATCH 04/33] move MODULE_IMPORT_NS(WOLFSSL) from wolfcrypto_shim.c to main.c. --- src/main.c | 4 ++++ src/wolfcrypto_shim.c | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 05c97e8e..33992f9e 100644 --- a/src/main.c +++ b/src/main.c @@ -69,3 +69,7 @@ MODULE_VERSION(WIREGUARD_VERSION); MODULE_ALIAS_RTNL_LINK(KBUILD_MODNAME); MODULE_ALIAS_GENL_FAMILY(WG_GENL_NAME); MODULE_INFO(intree, "Y"); + +#if defined(WOLFCRYPTO_SHIM_H) && defined(MODULE_IMPORT_NS) +MODULE_IMPORT_NS(WOLFSSL); +#endif diff --git a/src/wolfcrypto_shim.c b/src/wolfcrypto_shim.c index 548c53ae..bdcd143a 100644 --- a/src/wolfcrypto_shim.c +++ b/src/wolfcrypto_shim.c @@ -1,10 +1,6 @@ #include "wolfcrypto_shim.h" #include -#ifdef MODULE_IMPORT_NS -MODULE_IMPORT_NS(WOLFSSL); -#endif - int curve25519_generate_public(uint8_t pub[static CURVE25519_KEY_SIZE], const uint8_t secret[static CURVE25519_KEY_SIZE]) { uint8_t secret_copy[CURVE25519_KEY_SIZE]; /* pubkey_main() calls curve25519_generate_public() with pub == secret, which doesn't work for wc_curve25519_make_pub(). */ XMEMCPY(secret_copy, secret, CURVE25519_KEY_SIZE); From 296192c79b321c56d97ccb84d9ee1932fb8ad5e1 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 30 Oct 2020 23:08:04 -0500 Subject: [PATCH 05/33] move SHA macro undefs to prevent redefines in include/crypto/sha.h, included by include/linux/filter.h since kernel 5.8. --- src/wolfcrypto_shim.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/wolfcrypto_shim.h b/src/wolfcrypto_shim.h index 482580a0..a7fe41a0 100644 --- a/src/wolfcrypto_shim.h +++ b/src/wolfcrypto_shim.h @@ -18,12 +18,6 @@ #error libwolfssl missing HAVE_POLY1305 #endif -#undef SHA256_BLOCK_SIZE -#undef SHA256_DIGEST_SIZE -#undef SHA224_BLOCK_SIZE -#undef SHA224_DIGEST_SIZE -#undef CURVE25519_KEYSIZE - #include #include #define WOLFSSL_MISC_INCLUDED @@ -47,6 +41,11 @@ #define BLAKE2S_HASH_SIZE BLAKE2S_256 #define BLAKE2S_BLOCK_SIZE 64 +#undef SHA256_BLOCK_SIZE +#undef SHA256_DIGEST_SIZE +#undef SHA224_BLOCK_SIZE +#undef SHA224_DIGEST_SIZE + #include #include #include From cc2fcaf0cbf08978843278573b242dd927f58387 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 30 Oct 2020 23:10:47 -0500 Subject: [PATCH 06/33] compat.h: add 5.4-LTS gate coverage to ip_tunnel_parse_protocol() backport. --- src/compat/compat.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compat/compat.h b/src/compat/compat.h index 1aeaa217..91492027 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -1043,7 +1043,8 @@ static inline void skb_reset_redirect(struct sk_buff *skb) #define pre_exit exit #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) +/* note, somewhere >5.4.0 and <=5.4.72, ip_tunnel_parse_protocol() was backported to the 5.4-LTS kernel. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0) && ! (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 72))) #include #include #include From 77123b36b7e520f25aaf4a66fe1aaa8c1ff1af6b Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 30 Oct 2020 23:13:47 -0500 Subject: [PATCH 07/33] add support for WOLFSSL_ROOT make parameter. --- src/Kbuild | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Kbuild b/src/Kbuild index 1fd6a385..89e3aaa2 100644 --- a/src/Kbuild +++ b/src/Kbuild @@ -18,7 +18,10 @@ include $(src)/compat/Kbuild.include obj-$(if $(KBUILD_EXTMOD),m,$(CONFIG_WIREGUARD)) := wireguard.o ifdef WOLFCRYPT -ccflags-y += -DUSE_WOLFCRYPT -I$(src)/../../../../wolfssl -include $(src)/wolfcrypto_shim.h +ifndef WOLFSSL_ROOT +WOLFSSL_ROOT = $(src)/../../../../wolfssl +endif +ccflags-y += -DUSE_WOLFCRYPT -I$(WOLFSSL_ROOT) -include $(src)/wolfcrypto_shim.h wireguard-y += wolfcrypto_shim.o -KBUILD_EXTRA_SYMBOLS := $(src)/../../../../wolfssl/linuxkm/Module.symvers +KBUILD_EXTRA_SYMBOLS := $(WOLFSSL_ROOT)/linuxkm/Module.symvers endif From 187e823d2070f80f003bb0bb9f1380b9e55cc987 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 2 Nov 2020 12:47:58 -0600 Subject: [PATCH 08/33] Formatting, indentation, clarifying comments. --- src/wolfcrypto_shim.c | 114 ++++++++++++++------------ src/wolfcrypto_shim.h | 183 +++++++++++++++++++++++++++++------------- 2 files changed, 187 insertions(+), 110 deletions(-) diff --git a/src/wolfcrypto_shim.c b/src/wolfcrypto_shim.c index bdcd143a..805494d4 100644 --- a/src/wolfcrypto_shim.c +++ b/src/wolfcrypto_shim.c @@ -1,74 +1,80 @@ #include "wolfcrypto_shim.h" #include -int curve25519_generate_public(uint8_t pub[static CURVE25519_KEY_SIZE], const uint8_t secret[static CURVE25519_KEY_SIZE]) { - uint8_t secret_copy[CURVE25519_KEY_SIZE]; /* pubkey_main() calls curve25519_generate_public() with pub == secret, which doesn't work for wc_curve25519_make_pub(). */ +int curve25519_generate_public( + uint8_t pub[static CURVE25519_KEY_SIZE], + const uint8_t secret[static CURVE25519_KEY_SIZE]) +{ + /* pubkey_main() calls curve25519_generate_public() with pub == secret, + * which doesn't work for wc_curve25519_make_pub(). + */ + uint8_t secret_copy[CURVE25519_KEY_SIZE]; XMEMCPY(secret_copy, secret, CURVE25519_KEY_SIZE); return !DBG_PRNT_NZ(wc_curve25519_make_pub(CURVE25519_KEY_SIZE, pub, CURVE25519_KEY_SIZE, secret_copy)); } int curve25519_generate_secret(u8 secret[CURVE25519_KEY_SIZE]) { - WC_RNG *gRng = wc_rng_new(NULL /* nonce */, 0 /* nonceSz */, NULL /*heap */); - if (gRng) { - (void)DBG_PRNT_NZ(wc_curve25519_make_priv(gRng, (int)CURVE25519_KEY_SIZE, (byte *)secret)); - wc_rng_free(gRng); - return 0; - } else - return -ENOMEM; + WC_RNG *gRng = wc_rng_new(NULL /* nonce */, 0 /* nonceSz */, NULL /*heap */); + if (gRng) { + (void)DBG_PRNT_NZ(wc_curve25519_make_priv(gRng, (int)CURVE25519_KEY_SIZE, (byte *)secret)); + wc_rng_free(gRng); + return 0; + } else + return -ENOMEM; } int blake2s(byte *out, const void *in, const void *key, const byte outlen, - const word32 inlen, byte keylen) + const word32 inlen, byte keylen) { - Blake2s state; + Blake2s state; - if ((in == NULL) || (out == NULL)) - return -1; + if ((in == NULL) || (out == NULL)) + return -1; - if (DBG_PRNT_NZ(wc_InitBlake2s_WithKey(&state, (word32)outlen, (const byte *)key, (word32)keylen)) < 0) - return -1; - if (DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)in, inlen)) < 0) - return -1; - return DBG_PRNT_NZ(wc_Blake2sFinal(&state, out, (word32)outlen)); + if (DBG_PRNT_NZ(wc_InitBlake2s_WithKey(&state, (word32)outlen, (const byte *)key, (word32)keylen)) < 0) + return -1; + if (DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)in, inlen)) < 0) + return -1; + return DBG_PRNT_NZ(wc_Blake2sFinal(&state, out, (word32)outlen)); } void blake2s_hmac(byte *out, const byte *in, const byte *key, size_t outlen, size_t inlen, size_t keylen) { - Blake2s state; - word32 x_key[BLAKE2S_BLOCK_SIZE / sizeof(word32)]; - word32 i_hash[BLAKE2S_HASH_SIZE / sizeof(word32)]; - int i; + Blake2s state; + word32 x_key[BLAKE2S_BLOCK_SIZE / sizeof(word32)]; + word32 i_hash[BLAKE2S_HASH_SIZE / sizeof(word32)]; + int i; + + if (outlen != BLAKE2S_HASH_SIZE) + return; + + if (keylen > BLAKE2S_BLOCK_SIZE) { + DBG_PRNT_NZ(wc_InitBlake2s(&state, BLAKE2S_HASH_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, key, keylen)); + DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)x_key, 0)); + } else { + XMEMCPY(x_key, key, keylen); + XMEMSET((byte *)x_key + keylen, 0, BLAKE2S_BLOCK_SIZE - keylen); + } - if (outlen != BLAKE2S_HASH_SIZE) - return; + for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) + ((byte *)x_key)[i] ^= 0x36; - if (keylen > BLAKE2S_BLOCK_SIZE) { DBG_PRNT_NZ(wc_InitBlake2s(&state, BLAKE2S_HASH_SIZE)); - DBG_PRNT_NZ(wc_Blake2sUpdate(&state, key, keylen)); - DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)x_key, 0)); - } else { - XMEMCPY(x_key, key, keylen); - XMEMSET((byte *)x_key + keylen, 0, BLAKE2S_BLOCK_SIZE - keylen); - } - - for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) - ((byte *)x_key)[i] ^= 0x36; - - DBG_PRNT_NZ(wc_InitBlake2s(&state, BLAKE2S_HASH_SIZE)); - DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)x_key, BLAKE2S_BLOCK_SIZE)); - DBG_PRNT_NZ(wc_Blake2sUpdate(&state, in, inlen)); - DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)i_hash, 0)); - - for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) - ((byte *)x_key)[i] ^= 0x5c ^ 0x36; - - DBG_PRNT_NZ(wc_InitBlake2s(&state, BLAKE2S_HASH_SIZE)); - DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)x_key, BLAKE2S_BLOCK_SIZE)); - DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)i_hash, BLAKE2S_HASH_SIZE)); - DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)i_hash, 0)); - - XMEMCPY(out, i_hash, BLAKE2S_HASH_SIZE); - XMEMSET(x_key, 0, BLAKE2S_BLOCK_SIZE); - XMEMSET(i_hash, 0, BLAKE2S_HASH_SIZE); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)x_key, BLAKE2S_BLOCK_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, in, inlen)); + DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)i_hash, 0)); + + for (i = 0; i < BLAKE2S_BLOCK_SIZE; ++i) + ((byte *)x_key)[i] ^= 0x5c ^ 0x36; + + DBG_PRNT_NZ(wc_InitBlake2s(&state, BLAKE2S_HASH_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)x_key, BLAKE2S_BLOCK_SIZE)); + DBG_PRNT_NZ(wc_Blake2sUpdate(&state, (byte *)i_hash, BLAKE2S_HASH_SIZE)); + DBG_PRNT_NZ(wc_Blake2sFinal(&state, (byte *)i_hash, 0)); + + XMEMCPY(out, i_hash, BLAKE2S_HASH_SIZE); + XMEMSET(x_key, 0, BLAKE2S_BLOCK_SIZE); + XMEMSET(i_hash, 0, BLAKE2S_HASH_SIZE); } void blake2s256_hmac(byte *out, const byte *in, const byte *key, size_t inlen, size_t keylen) { @@ -132,8 +138,12 @@ static bool chacha20poly1305_crypt_sg_inplace(struct scatterlist *src, if ((ret = wc_Poly1305_EncodeSizes(&aead->poly, ad_len, src_len)) < 0) goto out; + /* the remaining length (sl) really will be conditionally negative after + * iteration -- this is Jason Donenfeld's algorithm from + * chacha20poly1305_crypt_sg_inplace() in Linux + * lib/crypto/chacha20poly1305.c. + */ if (sl <= -POLY1305_DIGEST_SIZE) { - if (isEncrypt) { if ((ret = wc_Poly1305Final(&aead->poly, miter.addr + miter.length + sl)) < 0) goto out; diff --git a/src/wolfcrypto_shim.h b/src/wolfcrypto_shim.h index a7fe41a0..34d08ef5 100644 --- a/src/wolfcrypto_shim.h +++ b/src/wolfcrypto_shim.h @@ -52,30 +52,50 @@ #include #ifdef DEBUG -#define DBG_PRNT_NZ(...) ({ int _ret = (__VA_ARGS__); if (_ret) printk(KERN_NOTICE "%s@%d: %d\n", __FILE__, __LINE__, _ret); _ret; }) +#define DBG_PRNT_NZ(...) ({ int _ret = (__VA_ARGS__); \ + if (_ret) \ + printk(KERN_NOTICE "%s@%d: %d\n", __FILE__, __LINE__, _ret); _ret; \ + }) #else #define DBG_PRNT_NZ(...) (__VA_ARGS__) #endif struct blake2s_state { - Blake2s blake2s; + Blake2s blake2s; }; #define blake2s_init(...) wc_wg_blake2s_init(__VA_ARGS__) -static void __attribute__((unused)) inline blake2s_init(struct blake2s_state *state, size_t outlen) { - DBG_PRNT_NZ(wc_InitBlake2s(&state->blake2s, (word32)outlen)); +static void __attribute__((unused)) inline blake2s_init( + struct blake2s_state *state, + size_t outlen) +{ + DBG_PRNT_NZ(wc_InitBlake2s(&state->blake2s, (word32)outlen)); } #define blake2s_init_key(...) wc_wg_blake2s_init_key(__VA_ARGS__) -static void __attribute__((unused)) inline blake2s_init_key(struct blake2s_state *state, size_t outlen, const void *key, - const size_t keylen) { - DBG_PRNT_NZ(wc_InitBlake2s_WithKey(&state->blake2s, (word32)outlen, (const byte *)key, (word32)keylen)); +static void __attribute__((unused)) inline blake2s_init_key( + struct blake2s_state *state, + size_t outlen, + const void *key, + const size_t keylen) +{ + DBG_PRNT_NZ(wc_InitBlake2s_WithKey( + &state->blake2s, + (word32)outlen, + (const byte *)key, + (word32)keylen)); } #define blake2s_update(...) wc_wg_blake2s_update(__VA_ARGS__) -static void __attribute__((unused)) inline blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen) { - DBG_PRNT_NZ(wc_Blake2sUpdate(&state->blake2s, (const byte *)in, (word32)inlen)); +static void __attribute__((unused)) inline blake2s_update( + struct blake2s_state *state, + const u8 *in, + size_t inlen) +{ + DBG_PRNT_NZ(wc_Blake2sUpdate(&state->blake2s, (const byte *)in, (word32)inlen)); } #define blake2s_final(...) wc_wg_blake2s_final(__VA_ARGS__) -static void __attribute__((unused)) inline blake2s_final(struct blake2s_state *state, const u8 *out) { - DBG_PRNT_NZ(wc_Blake2sFinal(&state->blake2s, (byte *)out, 0)); +static void __attribute__((unused)) inline blake2s_final( + struct blake2s_state *state, + const u8 *out) { + DBG_PRNT_NZ(wc_Blake2sFinal(&state->blake2s, (byte *)out, 0)); } #define blake2s(...) wc_wg_simple_blake2s(__VA_ARGS__) @@ -83,13 +103,26 @@ extern int blake2s(byte *out, const void *in, const void *key, const byte outlen const word32 inlen, byte keylen); #define blake2s256_hmac(...) wc_wg_blake2s256_hmac(__VA_ARGS__) -extern void blake2s256_hmac(byte *out, const byte *in, const byte *key, size_t inlen, size_t keylen); +extern void blake2s256_hmac( + byte *out, + const byte *in, + const byte *key, + size_t inlen, + size_t keylen); #define blake2s_hmac(...) wc_wg_blake2s_hmac(__VA_ARGS__) -extern void blake2s_hmac(byte *out, const byte *in, const byte *key, size_t outlen, size_t inlen, size_t keylen); +extern void blake2s_hmac( + byte *out, + const byte *in, + const byte *key, + size_t outlen, + size_t inlen, + size_t keylen); #define curve25519_generate_public(...) curve25519_generate_public_wolfshim(__VA_ARGS__) -extern int curve25519_generate_public(uint8_t pub[static CURVE25519_KEYSIZE], const uint8_t secret[static CURVE25519_KEYSIZE]); +extern int curve25519_generate_public( + uint8_t pub[static CURVE25519_KEYSIZE], + const uint8_t secret[static CURVE25519_KEYSIZE]); #define curve25519_generate_secret(...) curve25519_generate_secret_wolfshim(__VA_ARGS__) extern int curve25519_generate_secret(u8 secret[CURVE25519_KEY_SIZE]); @@ -97,14 +130,22 @@ extern int curve25519_generate_secret(u8 secret[CURVE25519_KEY_SIZE]); #define curve25519_clamp_secret(...) curve25519_clamp_secret_wolfshim(__VA_ARGS__) static inline void curve25519_clamp_secret(u8 key[CURVE25519_KEY_SIZE]) { - key[0] &= 248; - key[CURVE25519_KEY_SIZE-1] &= 63; /* same &=127 because |=64 after */ - key[CURVE25519_KEY_SIZE-1] |= 64; + key[0] &= 248; + key[CURVE25519_KEY_SIZE-1] &= 63; /* same &=127 because |=64 after */ + key[CURVE25519_KEY_SIZE-1] |= 64; } #define curve25519(...) curve25519_wolfshim(__VA_ARGS__) -static inline bool curve25519(uint8_t mypublic[static CURVE25519_KEY_SIZE], const uint8_t secret[static CURVE25519_KEY_SIZE], const uint8_t basepoint[static CURVE25519_KEY_SIZE]) { - return (wc_curve25519_generic(CURVE25519_KEY_SIZE, (byte *)mypublic, CURVE25519_KEY_SIZE, (byte *)secret, CURVE25519_KEY_SIZE, (byte *)basepoint) == 0 ? true : false); +static inline bool curve25519( + uint8_t mypublic[static CURVE25519_KEY_SIZE], + const uint8_t secret[static CURVE25519_KEY_SIZE], + const uint8_t basepoint[static CURVE25519_KEY_SIZE]) +{ + return (wc_curve25519_generic( + CURVE25519_KEY_SIZE, (byte *)mypublic, + CURVE25519_KEY_SIZE, (byte *)secret, + CURVE25519_KEY_SIZE, (byte *)basepoint) + == 0 ? true : false); } static __attribute__((unused)) inline void @@ -112,17 +153,17 @@ chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len, const u8 *ad, const size_t ad_len, const u64 nonce, const u8 key[CHACHA20POLY1305_KEY_SIZE]) { - word64 inIV[2] = { 0, cpu_to_le64(nonce) }; + word64 inIV[2] = { 0, cpu_to_le64(nonce) }; ChaChaPoly_Aead aead; if (DBG_PRNT_NZ(wc_ChaCha20Poly1305_Init(&aead, key, (const byte *)inIV, - CHACHA20_POLY1305_AEAD_ENCRYPT))) - return; + CHACHA20_POLY1305_AEAD_ENCRYPT))) + return; DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateAad(&aead, ad, (u32)ad_len)); if (src_len) DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateData(&aead, src, dst, - (u32)src_len)); + (u32)src_len)); DBG_PRNT_NZ(wc_ChaCha20Poly1305_Final(&aead, dst + src_len)); } @@ -131,44 +172,70 @@ chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len, const u8 *ad, const size_t ad_len, const u64 nonce, const u8 key[CHACHA20POLY1305_KEY_SIZE]) { - word64 inIV[2] = { 0, cpu_to_le64(nonce) }; - - int ret = 0; - ChaChaPoly_Aead aead; - byte calculatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE] = {}; - - if (DBG_PRNT_NZ - (wc_ChaCha20Poly1305_Init(&aead, key, (const u8 *)inIV + sizeof inIV - CHACHA20_POLY1305_AEAD_IV_SIZE, - CHACHA20_POLY1305_AEAD_DECRYPT))) - return false; - ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateAad(&aead, ad, (u32)ad_len)); - if (dst) - ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateData(&aead, src, dst, src_len - CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE)); - ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_Final(&aead, calculatedAuthTag)); - ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_CheckTag(src + src_len - CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, calculatedAuthTag)); - - return ret == 0; + word64 inIV[2] = { 0, cpu_to_le64(nonce) }; + + int ret = 0; + ChaChaPoly_Aead aead; + byte calculatedAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE] = {}; + + if (DBG_PRNT_NZ + (wc_ChaCha20Poly1305_Init( + &aead, + key, + (const u8 *)inIV + sizeof inIV - CHACHA20_POLY1305_AEAD_IV_SIZE, + CHACHA20_POLY1305_AEAD_DECRYPT))) + return false; + ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateAad(&aead, ad, (u32)ad_len)); + if (dst) + ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateData( + &aead, + src, + dst, + src_len - CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE)); + ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_Final(&aead, calculatedAuthTag)); + ret |= DBG_PRNT_NZ(wc_ChaCha20Poly1305_CheckTag( + src + src_len - CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE, + calculatedAuthTag)); + + return ret == 0; } #define xchacha20poly1305_encrypt(dst, src, src_len, ad, ad_len, nonce, key) \ - DBG_PRNT_NZ(wc_XChaCha20Poly1305_Encrypt(dst, (src_len) + POLY1305_DIGEST_SIZE, src, src_len, ad, ad_len, nonce, XCHACHA20POLY1305_NONCE_SIZE, key, CHACHA20POLY1305_KEY_SIZE)) + DBG_PRNT_NZ(wc_XChaCha20Poly1305_Encrypt( \ + dst, \ + (src_len) + POLY1305_DIGEST_SIZE, \ + src, src_len, \ + ad, ad_len, \ + nonce, XCHACHA20POLY1305_NONCE_SIZE, \ + key, CHACHA20POLY1305_KEY_SIZE)) + #define xchacha20poly1305_decrypt(dst, src, src_len, ad, ad_len, nonce, key) \ - (DBG_PRNT_NZ(wc_XChaCha20Poly1305_Decrypt(dst, (src_len) - POLY1305_DIGEST_SIZE, src, src_len, ad, ad_len, nonce, XCHACHA20POLY1305_NONCE_SIZE, key, CHACHA20POLY1305_KEY_SIZE)) == 0) - -#define chacha20poly1305_encrypt_sg_inplace(...) \ - chacha20poly1305_encrypt_sg_inplace_wolfshim(__VA_ARGS__) -extern bool chacha20poly1305_encrypt_sg_inplace(struct scatterlist *src, size_t src_len, - const u8 *ad, const size_t ad_len, - const u64 nonce, - const u8 key[CHACHA20POLY1305_KEY_SIZE], - simd_context_t *simd_context); - -#define chacha20poly1305_decrypt_sg_inplace(...) \ - chacha20poly1305_decrypt_sg_inplace_wolfshim(__VA_ARGS__) -extern bool chacha20poly1305_decrypt_sg_inplace(struct scatterlist *src, size_t src_len, - const u8 *ad, const size_t ad_len, - const u64 nonce, - const u8 key[CHACHA20POLY1305_KEY_SIZE], - simd_context_t *simd_context); + (DBG_PRNT_NZ(wc_XChaCha20Poly1305_Decrypt( \ + dst, \ + (src_len) - POLY1305_DIGEST_SIZE, \ + src, src_len, \ + ad, ad_len, \ + nonce, XCHACHA20POLY1305_NONCE_SIZE, \ + key, CHACHA20POLY1305_KEY_SIZE)) == 0) + +#define chacha20poly1305_encrypt_sg_inplace(...) \ + chacha20poly1305_encrypt_sg_inplace_wolfshim(__VA_ARGS__) +extern bool chacha20poly1305_encrypt_sg_inplace( \ + struct scatterlist *src, \ + size_t src_len, \ + const u8 *ad, const size_t ad_len, \ + const u64 nonce, \ + const u8 key[CHACHA20POLY1305_KEY_SIZE], \ + simd_context_t *simd_context); + +#define chacha20poly1305_decrypt_sg_inplace(...) \ + chacha20poly1305_decrypt_sg_inplace_wolfshim(__VA_ARGS__) +extern bool chacha20poly1305_decrypt_sg_inplace( \ + struct scatterlist *src, \ + size_t src_len, \ + const u8 *ad, const size_t ad_len, \ + const u64 nonce, \ + const u8 key[CHACHA20POLY1305_KEY_SIZE], \ + simd_context_t *simd_context); #endif From ee2d5aa0fbc99718d5961ca547c7a31de8390af9 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 2 Nov 2020 23:29:05 -0600 Subject: [PATCH 09/33] Makefile: pass INSTALL_MOD_DIR=wolfssl to Kbuild make ifdef WOLFCRYPT. --- src/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Makefile b/src/Makefile index b35ddbbc..2437fff2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -32,7 +32,11 @@ clean: @$(MAKE) -C $(KERNELDIR) M=$(PWD) clean module-install: +ifdef WOLFCRYPT + @$(MAKE) -C $(KERNELDIR) M=$(PWD) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" INSTALL_MOD_DIR=wolfssl modules_install +else @$(MAKE) -C $(KERNELDIR) M=$(PWD) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" modules_install +endif $(DEPMOD) -b "$(DEPMODBASEDIR)" -a $(KERNELRELEASE) install: module-install From 2a6632cdce61dcd53f0a28f84b60572d34867766 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 4 May 2022 12:15:59 -0500 Subject: [PATCH 10/33] fix build for kernels 5.11-5.18. --- .gitignore | 1 + src/device.c | 9 +++++++++ src/queueing.h | 7 +++++++ src/socket.c | 8 ++++++++ 4 files changed, 25 insertions(+) diff --git a/.gitignore b/.gitignore index 8f4ce963..cb1e5d94 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ cscope.out *.d *.dwo *.ko +*.mod *.mod.c *.a Module.symvers diff --git a/src/device.c b/src/device.c index 1155783a..9c1e405e 100644 --- a/src/device.c +++ b/src/device.c @@ -219,6 +219,15 @@ static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev) return ret; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +static void ip_tunnel_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *tot) +{ + netdev_stats_to_stats64(tot, &dev->stats); + dev_fetch_sw_netstats(tot, dev->tstats); +} +#endif + static const struct net_device_ops netdev_ops = { .ndo_open = wg_open, .ndo_stop = wg_stop, diff --git a/src/queueing.h b/src/queueing.h index bab170b9..1427994f 100644 --- a/src/queueing.h +++ b/src/queueing.h @@ -80,9 +80,16 @@ static inline void wg_reset_packet(struct sk_buff *skb, bool encapsulating) u8 sw_hash = skb->sw_hash; skb_scrub_packet(skb, true); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) + memset(&skb->headers, 0, + sizeof skb->headers); +#else memset(&skb->headers_start, 0, offsetof(struct sk_buff, headers_end) - offsetof(struct sk_buff, headers_start)); +#endif + skb->pfmemalloc = pfmemalloc; if (encapsulating) { skb->hash = hash; diff --git a/src/socket.c b/src/socket.c index c33e2c81..8251add8 100644 --- a/src/socket.c +++ b/src/socket.c @@ -49,7 +49,11 @@ static int send4(struct wg_device *wg, struct sk_buff *skb, rt = dst_cache_get_ip4(cache, &fl.saddr); if (!rt) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + security_sk_classify_flow(sock, flowi4_to_flowi_common(&fl)); +#else security_sk_classify_flow(sock, flowi4_to_flowi(&fl)); +#endif if (unlikely(!inet_confirm_addr(sock_net(sock), NULL, 0, fl.saddr, RT_SCOPE_HOST))) { endpoint->src4.s_addr = 0; @@ -129,7 +133,11 @@ static int send6(struct wg_device *wg, struct sk_buff *skb, dst = dst_cache_get_ip6(cache, &fl.saddr); if (!dst) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + security_sk_classify_flow(sock, flowi6_to_flowi_common(&fl)); +#else security_sk_classify_flow(sock, flowi6_to_flowi(&fl)); +#endif if (unlikely(!ipv6_addr_any(&fl.saddr) && !ipv6_chk_addr(sock_net(sock), &fl.saddr, NULL, 0))) { endpoint->src6 = fl.saddr = in6addr_any; From 70491d4bee1e0fe552f2478ae617e4111babfa24 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 4 Oct 2022 09:46:26 -0500 Subject: [PATCH 11/33] receive.c:update_rx_stats(): for kernel >= 6.0, use abstracted accessors for tstats->rx_packets and ->rx_bytes. --- src/receive.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/receive.c b/src/receive.c index 172ef823..49b9d1f7 100644 --- a/src/receive.c +++ b/src/receive.c @@ -24,8 +24,13 @@ static void update_rx_stats(struct wg_peer *peer, size_t len) get_cpu_ptr(peer->device->dev->tstats); u64_stats_update_begin(&tstats->syncp); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) + u64_stats_inc(&tstats->rx_packets); + u64_stats_add(&tstats->rx_bytes, len); +#else ++tstats->rx_packets; tstats->rx_bytes += len; +#endif peer->rx_bytes += len; u64_stats_update_end(&tstats->syncp); put_cpu_ptr(tstats); From bbd6ceef97ca2b14b7077881f37f58986fd426bc Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 13 Dec 2022 10:53:39 -0600 Subject: [PATCH 12/33] peer.c:wg_peer_create(): for kernel >= 6.1, use netif_napi_add_weight(). --- src/peer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/peer.c b/src/peer.c index b3b6370e..e5cef799 100644 --- a/src/peer.c +++ b/src/peer.c @@ -58,8 +58,13 @@ struct wg_peer *wg_peer_create(struct wg_device *wg, skb_queue_head_init(&peer->staged_packet_queue); wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake); set_bit(NAPI_STATE_NO_BUSY_POLL, &peer->napi.state); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) netif_napi_add(wg->dev, &peer->napi, wg_packet_rx_poll, NAPI_POLL_WEIGHT); +#else + netif_napi_add_weight(wg->dev, &peer->napi, wg_packet_rx_poll, + NAPI_POLL_WEIGHT); +#endif napi_enable(&peer->napi); list_add_tail(&peer->peer_list, &wg->peer_list); INIT_LIST_HEAD(&peer->allowedips_list); From 9ab54aebcc6aa7106d1fce7e6ab2b06d4ac03a60 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 21 Feb 2023 11:14:22 -0600 Subject: [PATCH 13/33] src/timers.c:wg_timers_data_sent() and wg_timers_handshake_initiated(): for kernel >= 6.2, use get_random_u32_below() rather than prandom_u32_max(). --- src/timers.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/timers.c b/src/timers.c index d54d32ac..9995be94 100644 --- a/src/timers.c +++ b/src/timers.c @@ -8,7 +8,6 @@ #include "peer.h" #include "queueing.h" #include "socket.h" - /* * - Timer for retransmitting the handshake if we don't hear back after * `REKEY_TIMEOUT + jitter` ms. @@ -147,7 +146,12 @@ void wg_timers_data_sent(struct wg_peer *peer) if (!timer_pending(&peer->timer_new_handshake)) mod_peer_timer(peer, &peer->timer_new_handshake, jiffies + (KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) * HZ + - prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)) + get_random_u32_below(REKEY_TIMEOUT_JITTER_MAX_JIFFIES) +#else + prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES) +#endif + ); } /* Should be called after an authenticated data packet is received. */ @@ -183,7 +187,12 @@ void wg_timers_handshake_initiated(struct wg_peer *peer) { mod_peer_timer(peer, &peer->timer_retransmit_handshake, jiffies + REKEY_TIMEOUT * HZ + - prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)) + get_random_u32_below(REKEY_TIMEOUT_JITTER_MAX_JIFFIES) +#else + prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES) +#endif + ); } /* Should be called after a handshake response message is received and processed From 361d17b2d6b8bf9f43565f26539de4dc65b3ea36 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sun, 21 May 2023 10:44:23 -0500 Subject: [PATCH 14/33] Kbuild: add compiler intrinsic header path to ccflags. --- src/Kbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kbuild b/src/Kbuild index 89e3aaa2..8772824d 100644 --- a/src/Kbuild +++ b/src/Kbuild @@ -21,7 +21,7 @@ ifdef WOLFCRYPT ifndef WOLFSSL_ROOT WOLFSSL_ROOT = $(src)/../../../../wolfssl endif -ccflags-y += -DUSE_WOLFCRYPT -I$(WOLFSSL_ROOT) -include $(src)/wolfcrypto_shim.h +ccflags-y += -DUSE_WOLFCRYPT -I$(shell $(CC) -print-file-name=include) -I$(WOLFSSL_ROOT) -include $(src)/wolfcrypto_shim.h wireguard-y += wolfcrypto_shim.o KBUILD_EXTRA_SYMBOLS := $(WOLFSSL_ROOT)/linuxkm/Module.symvers endif From c221f4c3896c7959ed3d3177333775aecf347858 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 5 Jul 2023 15:31:58 -0500 Subject: [PATCH 15/33] src/compat/Kbuild.include: update crypto_memneq sensing to check include/crypto/utils.h too. --- src/compat/Kbuild.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compat/Kbuild.include b/src/compat/Kbuild.include index e9376712..d7077cae 100644 --- a/src/compat/Kbuild.include +++ b/src/compat/Kbuild.include @@ -42,7 +42,7 @@ ccflags-y += -I$(kbuild-dir)/compat/udp_tunnel/include wireguard-y += compat/udp_tunnel/udp_tunnel.o endif -ifeq ($(shell grep -s -F "int crypto_memneq" "$(srctree)/include/crypto/algapi.h"),) +ifeq ($(shell grep -s -F "int crypto_memneq" "$(srctree)/include/crypto/algapi.h" "$(srctree)/include/crypto/utils.h"),) ccflags-y += -include $(kbuild-dir)/compat/memneq/include.h wireguard-y += compat/memneq/memneq.o endif From 1578b03ada3a6d2b9e9d51ab586e7d5c5b6b548b Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sun, 16 Jul 2023 09:20:44 -0500 Subject: [PATCH 16/33] src/crypto/Kbuild.include: remove .SECONDARY pseudotarget (breaks on kernel 6.4). --- src/crypto/Kbuild.include | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/crypto/Kbuild.include b/src/crypto/Kbuild.include index f2a312e9..2a5db4e9 100644 --- a/src/crypto/Kbuild.include +++ b/src/crypto/Kbuild.include @@ -45,7 +45,8 @@ kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) targets := $(patsubst $(kbuild-dir)/%.pl,%.S,$(wildcard $(patsubst %.o,$(kbuild-dir)/crypto/zinc/%.pl,$(zinc-y) $(zinc-m) $(zinc-)))) # Old kernels don't set this, which causes trouble. -.SECONDARY: +# breaks "make clean" on kernel 6.4 with ".NOTINTERMEDIATE and .SECONDARY are mutually exclusive." +# .SECONDARY: wireguard-y += $(addprefix crypto/zinc/,$(zinc-y)) ccflags-y += -I$(kbuild-dir)/crypto/include From 0c0e5de46b2004bd7eff6733187a3add3059fb54 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 12 Aug 2023 13:01:19 -0500 Subject: [PATCH 17/33] src/device.c: #include in kernel 6.4.10+, to accommodate linux commit d457a0e329. --- src/device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/device.c b/src/device.c index 9c1e405e..f26b3a73 100644 --- a/src/device.c +++ b/src/device.c @@ -23,6 +23,9 @@ #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 10) +#include +#endif static LIST_HEAD(device_list); From 1611efb9c21bab692b63f87a3ac44a0c6b4728bf Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 1 Nov 2023 11:23:37 -0500 Subject: [PATCH 18/33] src/netlink.c: in wg_get_device_start(), use genl_info_dump(), not genl_dumpit_info(), when kernel >= 6.6.0. --- src/netlink.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/netlink.c b/src/netlink.c index ef239ab1..16ac7269 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -198,7 +198,11 @@ static int wg_get_device_start(struct netlink_callback *cb) { struct wg_device *wg; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) wg = lookup_interface(genl_dumpit_info(cb)->attrs, cb->skb); +#else + wg = lookup_interface(genl_info_dump(cb)->attrs, cb->skb); +#endif if (IS_ERR(wg)) return PTR_ERR(wg); DUMP_CTX(cb)->wg = wg; From 8c144c6985a8887ce2f06fce95f3d372724becd9 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 20 May 2024 13:10:53 -0500 Subject: [PATCH 19/33] src/wolfcrypto_shim.h: include linux/slab.h so that wolfcrypt/src/misc.c at >=d9f7629296 can be compiled in the wireguard module. --- src/wolfcrypto_shim.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wolfcrypto_shim.h b/src/wolfcrypto_shim.h index 34d08ef5..e50b0cd1 100644 --- a/src/wolfcrypto_shim.h +++ b/src/wolfcrypto_shim.h @@ -18,6 +18,10 @@ #error libwolfssl missing HAVE_POLY1305 #endif +/* internal file misc.c at commit d9f7629296 has inline CopyString() that calls + * XMALLOC(). + */ +#include #include #include #define WOLFSSL_MISC_INCLUDED From 9688839f2980d1d4892527a9655f04fd61d3932f Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 31 May 2024 12:28:52 -0500 Subject: [PATCH 20/33] src/main.c and src/wolfcrypto_shim.h: fixes for kernel 6.10. --- src/main.c | 2 +- src/wolfcrypto_shim.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 33992f9e..00a8e5d4 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include static int __init mod_init(void) diff --git a/src/wolfcrypto_shim.h b/src/wolfcrypto_shim.h index e50b0cd1..a969fcbc 100644 --- a/src/wolfcrypto_shim.h +++ b/src/wolfcrypto_shim.h @@ -68,14 +68,14 @@ struct blake2s_state { Blake2s blake2s; }; #define blake2s_init(...) wc_wg_blake2s_init(__VA_ARGS__) -static void __attribute__((unused)) inline blake2s_init( +static inline __attribute__((unused)) void blake2s_init( struct blake2s_state *state, size_t outlen) { DBG_PRNT_NZ(wc_InitBlake2s(&state->blake2s, (word32)outlen)); } #define blake2s_init_key(...) wc_wg_blake2s_init_key(__VA_ARGS__) -static void __attribute__((unused)) inline blake2s_init_key( +static inline __attribute__((unused)) void blake2s_init_key( struct blake2s_state *state, size_t outlen, const void *key, @@ -88,7 +88,7 @@ static void __attribute__((unused)) inline blake2s_init_key( (word32)keylen)); } #define blake2s_update(...) wc_wg_blake2s_update(__VA_ARGS__) -static void __attribute__((unused)) inline blake2s_update( +static inline __attribute__((unused)) void blake2s_update( struct blake2s_state *state, const u8 *in, size_t inlen) @@ -96,7 +96,7 @@ static void __attribute__((unused)) inline blake2s_update( DBG_PRNT_NZ(wc_Blake2sUpdate(&state->blake2s, (const byte *)in, (word32)inlen)); } #define blake2s_final(...) wc_wg_blake2s_final(__VA_ARGS__) -static void __attribute__((unused)) inline blake2s_final( +static inline __attribute__((unused)) void blake2s_final( struct blake2s_state *state, const u8 *out) { DBG_PRNT_NZ(wc_Blake2sFinal(&state->blake2s, (byte *)out, 0)); @@ -152,7 +152,7 @@ static inline bool curve25519( == 0 ? true : false); } -static __attribute__((unused)) inline void +static inline __attribute__((unused)) void chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len, const u8 *ad, const size_t ad_len, const u64 nonce, @@ -171,7 +171,7 @@ chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len, DBG_PRNT_NZ(wc_ChaCha20Poly1305_Final(&aead, dst + src_len)); } -static __attribute__((unused)) inline bool +static inline __attribute__((unused)) bool chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len, const u8 *ad, const size_t ad_len, const u64 nonce, From dfc7b25433a4d41884896a06ea81ce42cf2b7b6c Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 7 Oct 2024 15:06:11 -0500 Subject: [PATCH 21/33] src/device.c: fixes for kernel 6.12 --- src/device.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/device.c b/src/device.c index f26b3a73..1f77b2fc 100644 --- a/src/device.c +++ b/src/device.c @@ -11,6 +11,11 @@ #include "peer.h" #include "messages.h" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) + /* kludge to work around broken pagemap.h, re min() and max(), due to 84429b675bcfd */ + #define _LINUX_PAGEMAP_H +#endif /* >= 6.12.0 */ + #include #include #include @@ -294,7 +299,11 @@ static void wg_setup(struct net_device *dev) #else dev->tx_queue_len = 0; #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) + dev->lltx = true; +#else dev->features |= NETIF_F_LLTX; +#endif dev->features |= WG_NETDEV_FEATURES; dev->hw_features |= WG_NETDEV_FEATURES; dev->hw_enc_features |= WG_NETDEV_FEATURES; From 905eb339b96384272205a925d3909cdea737e074 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 29 Oct 2024 12:15:12 -0500 Subject: [PATCH 22/33] src/timers.c: in pr_debug() calls, cast ulong args to int to avoid -Wformats (likely necessitated by gcc-13). --- src/timers.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/timers.c b/src/timers.c index 9995be94..f0c53813 100644 --- a/src/timers.c +++ b/src/timers.c @@ -45,7 +45,7 @@ static void wg_expired_retransmit_handshake(struct timer_list *timer) if (peer->timer_handshake_attempts > MAX_TIMER_HANDSHAKES) { pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d attempts, giving up\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, MAX_TIMER_HANDSHAKES + 2); + &peer->endpoint.addr, (int)(MAX_TIMER_HANDSHAKES + 2)); del_timer(&peer->timer_send_keepalive); /* We drop all packets without a keypair and don't try again, @@ -63,7 +63,7 @@ static void wg_expired_retransmit_handshake(struct timer_list *timer) ++peer->timer_handshake_attempts; pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, REKEY_TIMEOUT, + &peer->endpoint.addr, (int)REKEY_TIMEOUT, peer->timer_handshake_attempts + 1); /* We clear the endpoint address src address, in case this is @@ -93,7 +93,7 @@ static void wg_expired_new_handshake(struct timer_list *timer) pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, KEEPALIVE_TIMEOUT + REKEY_TIMEOUT); + &peer->endpoint.addr, (int)(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT)); /* We clear the endpoint address src address, in case this is the cause * of trouble. */ @@ -125,7 +125,7 @@ static void wg_queued_expired_zero_key_material(struct work_struct *work) pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, REJECT_AFTER_TIME * 3); + &peer->endpoint.addr, (int)(REJECT_AFTER_TIME * 3)); wg_noise_handshake_clear(&peer->handshake); wg_noise_keypairs_clear(&peer->keypairs); wg_peer_put(peer); From e0e40e83c469d71408ffe4948066b4ee3155cfcd Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 5 Dec 2024 09:58:16 -0600 Subject: [PATCH 23/33] src/compat/Kbuild.include: set +kbuild-dir to $(src) unconditionally, for compatibility with kernel 6.13. --- src/compat/Kbuild.include | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compat/Kbuild.include b/src/compat/Kbuild.include index d7077cae..d5bdaf4d 100644 --- a/src/compat/Kbuild.include +++ b/src/compat/Kbuild.include @@ -2,7 +2,8 @@ # # Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. -kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +#kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +kbuild-dir := $(src) ccflags-y += -include $(kbuild-dir)/compat/compat.h asflags-y += -include $(kbuild-dir)/compat/compat-asm.h From 992b696c12c51db0e57c32dff49d5d4693146ad0 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 17 Dec 2024 13:57:08 -0600 Subject: [PATCH 24/33] src/main.c: update MODULE_IMPORT_NS() for kernel 6.13 (namespaces as quoted strings). --- src/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.c b/src/main.c index 00a8e5d4..860e8925 100644 --- a/src/main.c +++ b/src/main.c @@ -71,5 +71,9 @@ MODULE_ALIAS_GENL_FAMILY(WG_GENL_NAME); MODULE_INFO(intree, "Y"); #if defined(WOLFCRYPTO_SHIM_H) && defined(MODULE_IMPORT_NS) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +MODULE_IMPORT_NS("WOLFSSL"); +#else MODULE_IMPORT_NS(WOLFSSL); #endif +#endif From b3bc2275e70af47fe57cf32ead0d09f6d51e6174 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 21 Feb 2025 22:19:28 -0600 Subject: [PATCH 25/33] src/wolfcrypto_shim.h: include linux/mm.h, not linux/slab.h, to get kvmalloc_node prototype on earlier kernels (e.g. 5.14). --- src/wolfcrypto_shim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wolfcrypto_shim.h b/src/wolfcrypto_shim.h index a969fcbc..f6c56fd4 100644 --- a/src/wolfcrypto_shim.h +++ b/src/wolfcrypto_shim.h @@ -21,7 +21,7 @@ /* internal file misc.c at commit d9f7629296 has inline CopyString() that calls * XMALLOC(). */ -#include +#include #include #include #define WOLFSSL_MISC_INCLUDED From 987a2fea0296780b07f10697288eb852cd0353f9 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 3 Apr 2025 19:51:31 -0500 Subject: [PATCH 26/33] src/wolfcrypto_shim.h: in chacha20poly1305_encrypt(), always log error if wc_ChaCha20Poly1305_Final() returns nonzero. fixes new -Wunused-result. --- src/wolfcrypto_shim.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/wolfcrypto_shim.h b/src/wolfcrypto_shim.h index f6c56fd4..0c84b816 100644 --- a/src/wolfcrypto_shim.h +++ b/src/wolfcrypto_shim.h @@ -55,11 +55,17 @@ #include #include +#define PRNT_NZ(...) \ + ({ \ + int _ret = (__VA_ARGS__); \ + if (_ret) { \ + printk(KERN_NOTICE "%s@%d: %d\n", __FILE__, __LINE__, _ret); \ + } \ + _ret; \ + }) + #ifdef DEBUG -#define DBG_PRNT_NZ(...) ({ int _ret = (__VA_ARGS__); \ - if (_ret) \ - printk(KERN_NOTICE "%s@%d: %d\n", __FILE__, __LINE__, _ret); _ret; \ - }) +#define DBG_PRNT_NZ(...) PRNT_NZ(__VA_ARGS__) #else #define DBG_PRNT_NZ(...) (__VA_ARGS__) #endif @@ -168,7 +174,7 @@ chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len, if (src_len) DBG_PRNT_NZ(wc_ChaCha20Poly1305_UpdateData(&aead, src, dst, (u32)src_len)); - DBG_PRNT_NZ(wc_ChaCha20Poly1305_Final(&aead, dst + src_len)); + PRNT_NZ(wc_ChaCha20Poly1305_Final(&aead, dst + src_len)); } static inline __attribute__((unused)) bool From f78d38a1e0360bc06f051756291ac5f749dc9d27 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 14 Apr 2025 11:05:10 -0500 Subject: [PATCH 27/33] -* src/timers.c and src/device.c: map del_timer[_sync] to timer_delete[_sync] on kernel >= 6.15, per linux 326534e837 and 8fa7292fee. --- src/device.c | 6 ++++++ src/timers.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/device.c b/src/device.c index 1f77b2fc..5e046ea6 100644 --- a/src/device.c +++ b/src/device.c @@ -32,6 +32,12 @@ #include #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + /* see linux 326534e837 and 8fa7292fee */ + #define del_timer timer_delete + #define del_timer_sync timer_delete_sync +#endif + static LIST_HEAD(device_list); static int wg_open(struct net_device *dev) diff --git a/src/timers.c b/src/timers.c index f0c53813..aeb0e69f 100644 --- a/src/timers.c +++ b/src/timers.c @@ -26,6 +26,12 @@ * specified seconds. */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + /* see linux 326534e837 and 8fa7292fee */ + #define del_timer timer_delete + #define del_timer_sync timer_delete_sync +#endif + static inline void mod_peer_timer(struct wg_peer *peer, struct timer_list *timer, unsigned long expires) From 7c02f0d794ee3cc3eee8d44bf970ea076f0b8e27 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 14 Apr 2025 11:15:41 -0500 Subject: [PATCH 28/33] src/device.c: fix wg_newlink() for linux 69c7be1b903fc and cf517ac16ad96. --- src/device.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/device.c b/src/device.c index 5e046ea6..fd9b33ab 100644 --- a/src/device.c +++ b/src/device.c @@ -327,14 +327,27 @@ static void wg_setup(struct net_device *dev) wg->dev = dev; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) +static int wg_newlink(struct net_device *dev, + struct rtnl_newlink_params *params, + struct netlink_ext_ack *extack) +#else static int wg_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) +#endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + struct net *link_net = rtnl_newlink_link_net(params); +#endif struct wg_device *wg = netdev_priv(dev); int ret = -ENOMEM; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) + rcu_assign_pointer(wg->creating_net, link_net); +#else rcu_assign_pointer(wg->creating_net, src_net); +#endif init_rwsem(&wg->static_identity.lock); mutex_init(&wg->socket_update_lock); mutex_init(&wg->device_update_lock); From c3a1d7181fa9a47237b600f26772009fa6b19e08 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 7 May 2025 17:31:55 -0500 Subject: [PATCH 29/33] add kernel version gate coverage for RHEL 9.5+. --- src/device.c | 3 ++- src/netlink.c | 7 ++++--- src/peer.c | 7 ++++--- src/queueing.h | 3 ++- src/receive.c | 3 ++- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/device.c b/src/device.c index fd9b33ab..bbd0ee74 100644 --- a/src/device.c +++ b/src/device.c @@ -28,7 +28,8 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 10) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 10)) || \ + (defined(RHEL_MAJOR) && ((RHEL_MAJOR > 9) || ((RHEL_MAJOR == 9) && (RHEL_MINOR >= 5)))) #include #endif diff --git a/src/netlink.c b/src/netlink.c index 16ac7269..ca3f91f5 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -198,10 +198,11 @@ static int wg_get_device_start(struct netlink_callback *cb) { struct wg_device *wg; -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) - wg = lookup_interface(genl_dumpit_info(cb)->attrs, cb->skb); -#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)) || \ + (defined(RHEL_MAJOR) && ((RHEL_MAJOR > 9) || ((RHEL_MAJOR == 9) && (RHEL_MINOR >= 5)))) wg = lookup_interface(genl_info_dump(cb)->attrs, cb->skb); +#else + wg = lookup_interface(genl_dumpit_info(cb)->attrs, cb->skb); #endif if (IS_ERR(wg)) return PTR_ERR(wg); diff --git a/src/peer.c b/src/peer.c index e5cef799..430d26b1 100644 --- a/src/peer.c +++ b/src/peer.c @@ -58,11 +58,12 @@ struct wg_peer *wg_peer_create(struct wg_device *wg, skb_queue_head_init(&peer->staged_packet_queue); wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake); set_bit(NAPI_STATE_NO_BUSY_POLL, &peer->napi.state); -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) - netif_napi_add(wg->dev, &peer->napi, wg_packet_rx_poll, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)) || \ + (defined(RHEL_MAJOR) && ((RHEL_MAJOR > 9) || ((RHEL_MAJOR == 9) && (RHEL_MINOR >= 5)))) + netif_napi_add_weight(wg->dev, &peer->napi, wg_packet_rx_poll, NAPI_POLL_WEIGHT); #else - netif_napi_add_weight(wg->dev, &peer->napi, wg_packet_rx_poll, + netif_napi_add(wg->dev, &peer->napi, wg_packet_rx_poll, NAPI_POLL_WEIGHT); #endif napi_enable(&peer->napi); diff --git a/src/queueing.h b/src/queueing.h index 1427994f..3991e5d3 100644 --- a/src/queueing.h +++ b/src/queueing.h @@ -81,7 +81,8 @@ static inline void wg_reset_packet(struct sk_buff *skb, bool encapsulating) skb_scrub_packet(skb, true); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)) || \ + (defined(RHEL_MAJOR) && ((RHEL_MAJOR > 9) || ((RHEL_MAJOR == 9) && (RHEL_MINOR >= 5)))) memset(&skb->headers, 0, sizeof skb->headers); #else diff --git a/src/receive.c b/src/receive.c index 49b9d1f7..16d92c57 100644 --- a/src/receive.c +++ b/src/receive.c @@ -24,7 +24,8 @@ static void update_rx_stats(struct wg_peer *peer, size_t len) get_cpu_ptr(peer->device->dev->tstats); u64_stats_update_begin(&tstats->syncp); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || \ + (defined(RHEL_MAJOR) && ((RHEL_MAJOR > 9) || ((RHEL_MAJOR == 9) && (RHEL_MINOR >= 5)))) u64_stats_inc(&tstats->rx_packets); u64_stats_add(&tstats->rx_bytes, len); #else From 5cbf6c157a4b5e2d954f00a7aafeb8de95db87ef Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 21 Jun 2025 11:00:27 -0500 Subject: [PATCH 30/33] src/timers.c: fixes for linux 6.16. --- src/timers.c | 69 +++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/src/timers.c b/src/timers.c index aeb0e69f..24986e8c 100644 --- a/src/timers.c +++ b/src/timers.c @@ -8,6 +8,7 @@ #include "peer.h" #include "queueing.h" #include "socket.h" + /* * - Timer for retransmitting the handshake if we don't hear back after * `REKEY_TIMEOUT + jitter` ms. @@ -26,10 +27,19 @@ * specified seconds. */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)) + #define get_random_u32_below prandom_u32_max +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 15, 0) /* see linux 326534e837 and 8fa7292fee */ - #define del_timer timer_delete - #define del_timer_sync timer_delete_sync + #define timer_delete del_timer + #define timer_delete_sync del_timer_sync +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0) + /* see linux 41cb08555c and be54f8c558 */ + #define timer_container_of from_timer #endif static inline void mod_peer_timer(struct wg_peer *peer, @@ -45,15 +55,15 @@ static inline void mod_peer_timer(struct wg_peer *peer, static void wg_expired_retransmit_handshake(struct timer_list *timer) { - struct wg_peer *peer = from_timer(peer, timer, - timer_retransmit_handshake); + struct wg_peer *peer = timer_container_of(peer, timer, + timer_retransmit_handshake); if (peer->timer_handshake_attempts > MAX_TIMER_HANDSHAKES) { pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d attempts, giving up\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, (int)(MAX_TIMER_HANDSHAKES + 2)); + &peer->endpoint.addr, (int)MAX_TIMER_HANDSHAKES + 2); - del_timer(&peer->timer_send_keepalive); + timer_delete(&peer->timer_send_keepalive); /* We drop all packets without a keypair and don't try again, * if we try unsuccessfully for too long to make a handshake. */ @@ -83,7 +93,8 @@ static void wg_expired_retransmit_handshake(struct timer_list *timer) static void wg_expired_send_keepalive(struct timer_list *timer) { - struct wg_peer *peer = from_timer(peer, timer, timer_send_keepalive); + struct wg_peer *peer = timer_container_of(peer, timer, + timer_send_keepalive); wg_packet_send_keepalive(peer); if (peer->timer_need_another_keepalive) { @@ -95,7 +106,8 @@ static void wg_expired_send_keepalive(struct timer_list *timer) static void wg_expired_new_handshake(struct timer_list *timer) { - struct wg_peer *peer = from_timer(peer, timer, timer_new_handshake); + struct wg_peer *peer = timer_container_of(peer, timer, + timer_new_handshake); pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n", peer->device->dev->name, peer->internal_id, @@ -109,7 +121,8 @@ static void wg_expired_new_handshake(struct timer_list *timer) static void wg_expired_zero_key_material(struct timer_list *timer) { - struct wg_peer *peer = from_timer(peer, timer, timer_zero_key_material); + struct wg_peer *peer = timer_container_of(peer, timer, + timer_zero_key_material); rcu_read_lock_bh(); if (!READ_ONCE(peer->is_dead)) { @@ -131,7 +144,7 @@ static void wg_queued_expired_zero_key_material(struct work_struct *work) pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, (int)(REJECT_AFTER_TIME * 3)); + &peer->endpoint.addr, (int)REJECT_AFTER_TIME * 3); wg_noise_handshake_clear(&peer->handshake); wg_noise_keypairs_clear(&peer->keypairs); wg_peer_put(peer); @@ -139,8 +152,8 @@ static void wg_queued_expired_zero_key_material(struct work_struct *work) static void wg_expired_send_persistent_keepalive(struct timer_list *timer) { - struct wg_peer *peer = from_timer(peer, timer, - timer_persistent_keepalive); + struct wg_peer *peer = timer_container_of(peer, timer, + timer_persistent_keepalive); if (likely(peer->persistent_keepalive_interval)) wg_packet_send_keepalive(peer); @@ -152,12 +165,7 @@ void wg_timers_data_sent(struct wg_peer *peer) if (!timer_pending(&peer->timer_new_handshake)) mod_peer_timer(peer, &peer->timer_new_handshake, jiffies + (KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) * HZ + -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)) - get_random_u32_below(REKEY_TIMEOUT_JITTER_MAX_JIFFIES) -#else - prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES) -#endif - ); + get_random_u32_below(REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); } /* Should be called after an authenticated data packet is received. */ @@ -177,7 +185,7 @@ void wg_timers_data_received(struct wg_peer *peer) */ void wg_timers_any_authenticated_packet_sent(struct wg_peer *peer) { - del_timer(&peer->timer_send_keepalive); + timer_delete(&peer->timer_send_keepalive); } /* Should be called after any type of authenticated packet is received, whether @@ -185,7 +193,7 @@ void wg_timers_any_authenticated_packet_sent(struct wg_peer *peer) */ void wg_timers_any_authenticated_packet_received(struct wg_peer *peer) { - del_timer(&peer->timer_new_handshake); + timer_delete(&peer->timer_new_handshake); } /* Should be called after a handshake initiation message is sent. */ @@ -193,12 +201,7 @@ void wg_timers_handshake_initiated(struct wg_peer *peer) { mod_peer_timer(peer, &peer->timer_retransmit_handshake, jiffies + REKEY_TIMEOUT * HZ + -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)) - get_random_u32_below(REKEY_TIMEOUT_JITTER_MAX_JIFFIES) -#else - prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES) -#endif - ); + get_random_u32_below(REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); } /* Should be called after a handshake response message is received and processed @@ -206,7 +209,7 @@ void wg_timers_handshake_initiated(struct wg_peer *peer) */ void wg_timers_handshake_complete(struct wg_peer *peer) { - del_timer(&peer->timer_retransmit_handshake); + timer_delete(&peer->timer_retransmit_handshake); peer->timer_handshake_attempts = 0; peer->sent_lastminute_handshake = false; ktime_get_real_ts64(&peer->walltime_last_handshake); @@ -249,10 +252,10 @@ void wg_timers_init(struct wg_peer *peer) void wg_timers_stop(struct wg_peer *peer) { - del_timer_sync(&peer->timer_retransmit_handshake); - del_timer_sync(&peer->timer_send_keepalive); - del_timer_sync(&peer->timer_new_handshake); - del_timer_sync(&peer->timer_zero_key_material); - del_timer_sync(&peer->timer_persistent_keepalive); + timer_delete_sync(&peer->timer_retransmit_handshake); + timer_delete_sync(&peer->timer_send_keepalive); + timer_delete_sync(&peer->timer_new_handshake); + timer_delete_sync(&peer->timer_zero_key_material); + timer_delete_sync(&peer->timer_persistent_keepalive); flush_work(&peer->clear_peer_work); } From 9873d99e1eb363b824c3bf8f7530d84639e34491 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 5 Sep 2025 16:42:32 -0500 Subject: [PATCH 31/33] src/socket.c: fix for kernel 6.17. --- src/socket.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/socket.c b/src/socket.c index 8251add8..e80b0c6e 100644 --- a/src/socket.c +++ b/src/socket.c @@ -86,9 +86,15 @@ static int send4(struct wg_device *wg, struct sk_buff *skb, } skb->ignore_df = 1; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 17, 0) udp_tunnel_xmit_skb(rt, sock, skb, fl.saddr, fl.daddr, ds, ip4_dst_hoplimit(&rt->dst), 0, fl.fl4_sport, fl.fl4_dport, false, false); +#else + udp_tunnel_xmit_skb(rt, sock, skb, fl.saddr, fl.daddr, ds, + ip4_dst_hoplimit(&rt->dst), 0, fl.fl4_sport, + fl.fl4_dport, false, false, 0); +#endif goto out; err: @@ -157,9 +163,15 @@ static int send6(struct wg_device *wg, struct sk_buff *skb, } skb->ignore_df = 1; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 17, 0) udp_tunnel6_xmit_skb(dst, sock, skb, skb->dev, &fl.saddr, &fl.daddr, ds, ip6_dst_hoplimit(dst), 0, fl.fl6_sport, fl.fl6_dport, false); +#else + udp_tunnel6_xmit_skb(dst, sock, skb, skb->dev, &fl.saddr, &fl.daddr, ds, + ip6_dst_hoplimit(dst), 0, fl.fl6_sport, + fl.fl6_dport, false, 0); +#endif goto out; err: From c249eb7184b032a8c8d9ed87f0b1f8fba2d9f80d Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sun, 3 May 2026 21:48:00 -0500 Subject: [PATCH 32/33] cherry pick 11f896ace0 from WolfGuard: kernel-src/socket.c: use ip6_dst_lookup_flow(), not ipv6_stub->ipv6_dst_lookup_flow. --- src/socket.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/socket.c b/src/socket.c index e80b0c6e..15d0981f 100644 --- a/src/socket.c +++ b/src/socket.c @@ -150,7 +150,13 @@ static int send6(struct wg_device *wg, struct sk_buff *skb, if (cache) dst_cache_reset(cache); } - dst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(sock), sock, &fl, + /* 343d60aada (v4.16) adds net arg to ipv6_stub_impl.ipv6_dst_lookup, + * c4e85f73af (v5.5) adds it to ip6_dst_lookup_flow() (sunrise for the + * below code pattern), and ipv6_stub is slated for removal (along + * with net/ipv6_stubs.h) circa v7.1, linux-next commit + * 964870b4b9. + */ + dst = ip6_dst_lookup_flow(sock_net(sock), sock, &fl, NULL); if (unlikely(IS_ERR(dst))) { ret = PTR_ERR(dst); From f6998f5f0c0f9aa053da97014d4486634b574be6 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 4 Jul 2026 13:17:37 -0500 Subject: [PATCH 33/33] cherry pick 70cca27b from WolfGuard: kernel-src/socket.c: port fixes from linux-next (future kernel 7.2) "udp_tunnel: Pass struct sock to udp_tunnel_sock_release()." and "udp_tunnel: Pass struct sock to setup_udp_tunnel_sock()." (both by Kuniyuki Iwashima ). --- src/socket.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/socket.c b/src/socket.c index 15d0981f..44051b89 100644 --- a/src/socket.c +++ b/src/socket.c @@ -361,7 +361,11 @@ static void sock_free(struct sock *sock) if (unlikely(!sock)) return; sk_clear_memalloc(sock); +#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 2, 0) udp_tunnel_sock_release(sock->sk_socket); +#else + udp_tunnel_sock_release(sock); +#endif } static void set_sock_opts(struct socket *sock) @@ -415,14 +419,22 @@ int wg_socket_init(struct wg_device *wg, u16 port) goto out; } set_sock_opts(new4); +#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 2, 0) setup_udp_tunnel_sock(net, new4, &cfg); +#else + setup_udp_tunnel_sock(net, new4->sk, &cfg); +#endif #if IS_ENABLED(CONFIG_IPV6) if (ipv6_mod_enabled()) { port6.local_udp_port = inet_sk(new4->sk)->inet_sport; ret = udp_sock_create(net, &port6, &new6); if (ret < 0) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 2, 0) udp_tunnel_sock_release(new4); +#else + udp_tunnel_sock_release(new4->sk); +#endif if (ret == -EADDRINUSE && !port && retries++ < 100) goto retry; pr_err("%s: Could not create IPv6 socket\n", @@ -430,7 +442,11 @@ int wg_socket_init(struct wg_device *wg, u16 port) goto out; } set_sock_opts(new6); +#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 2, 0) setup_udp_tunnel_sock(net, new6, &cfg); +#else + setup_udp_tunnel_sock(net, new6->sk, &cfg); +#endif } #endif