WolfGuard 是基于 wolfSSL FIPS 合规重构的 Linux 内核 WireGuard,最初由 Jason Donenfeld 设计并编写。用法基本相同。WolfGuard 有两个主要组件:wolfguard.ko 内核模块和 wg-fips 配置工具。wolfguard.ko 依赖于 libwolfssl.ko 内核模块,而 wg-fips 依赖于 libwolfssl.so 库 — 这些依赖项均从相同的 wolfSSL 源代码构建,分别配置为内核模块和用户库。wg-fips-quick 脚本的工作方式与 WireGuard 中的 wg-quick 完全相同,但配置文件位于 /etc/wolfguard 中,其中包含 SECP256R1 公钥和私钥。
安装二进制目录中会安装从 wg 到 wg-fips、从 wg-quick 到 wg-fips-quick 的符号链接,以实现对 WireGuard 的透明替换。如果在安装过程中发现现有的 WireGuard 可执行文件,它们将被重命名为 wg-wireguard 和 wg-wireguard-quick,并修改 wg-wireguard-quick 以调用 wg-wireguard,同时保留一份安全副本 wg-wireguard-quick.unpatched。
WolfGuard 对 WireGuard 的加密方式进行了如下映射:
| 算法类别 | WireGuard | WolfGuard |
|---|---|---|
| ECDH | Curve25519 | SECP256R1 |
| AEAD | XChaCha20-Poly1305 | AES-256-GCM |
| 摘要 | Blake2s | SHA2-256 |
| 身份验证摘要 | Blake2s-HMAC | SHA2-256-HMAC |
| 内部哈希 | SipHash | SHA2-256 |
| DRBG | ChaCha20 DRBG | SHA2-256 Hash-DRBG |
请注意,WolfGuard 和 WireGuard 可以在同一系统上共存,同时建立 WolfGuard 和 WireGuard 隧道。
如果 libwolfssl.ko 使用 --enable-intelasm 配置,WolfGuard 的性能将匹配或超过 CPU 加速的 WireGuard,这得益于 AES-256-GCM 和 SHA2-256 操作的 CPU 加速。如果不使用 --enable-intelasm,WolfGuard 比 CPU 加速的 WireGuard 稍慢,但仍能在现代 CPU 上达到千兆以太网的带宽饱和。
以下是两组说明,第一组适用于从非 FIPS 源代码构建,第二组适用于从 FIPS 认证源代码构建。在两种情况下,WolfGuard 用户工具和脚本均命名为 wg-fips 和 wg-fips-quick,以反映它们使用了 FIPS 批准的算法,无论 FIPS 认证状态如何。FIPS 认证和非认证版本的 WolfGuard 可以完全互操作,但不能与 WireGuard 互操作。
--enable-intelasm 选项仅适用于 x86 CPU 目标,对于 FIPS,仅适用于支持该选项的 FIPS 源代码。如需更多信息,请联系我们 [email protected]。
--enable-wolfguard 选项启用 WolfGuard 所需的最低库/模块功能集。如需更全面的功能集,请改用 --enable-all-crypto。
以 $ 开头的命令应由非特权用户执行,以 # 开头的命令需要 root 权限,但需在相同的工作目录上下文中执行。
请注意,如果使用 wolfSSL 发布存档而非 git 源代码,则发布版本必须为 5.8.4 或更新版本。
git 源代码构建和安装(1) 为源代码创建顶层目录并填充内容:
$ mkdir wolf-sources
$ cd wolf-sources
$ git clone https://github.com/wolfssl/wolfssl --branch nightly-snapshot
$ git clone https://github.com/wolfssl/wolfguard
$ (cd wolfssl && ./autogen.sh)
(2) 构建并安装 libwolfssl 用户库:
请注意,此步骤在 Linux 上是可选的,默认情况下 wg-fips 会将密钥生成和转换操作卸载到内核模块,而非内部执行。
$ cd wolfssl
$ ./configure --quiet --enable-wolfguard --enable-all-asm
$ make -j
$ ./wolfcrypt/test/testwolfcrypt
# make install
$ cd ..
(3) 构建并安装 wg-fips 用户工具 — 请注意,安装会将目标目录中现有的 WireGuard wg 和 wg-quick 可执行文件及手册页(如果存在)分别移动到 wg-wireguard 和 wg-wireguard-quick,并安装指向 WolfGuard 版本的 wg 和 wg-quick 符号链接。
$ cd wolfguard/user-src
$ make -j
# make install
$ cd ../..
要在 Linux 上强制使用内部密钥操作,而非默认卸载到内核模块,请将 make -j 替换为 make -j NO_IPC_LLCRYPTO=1。
支持压缩公钥,其 base64 导出长度与 WireGuard Curve25519 公钥相同。可通过在上述过程中替换以下内容来启用:
$ make -j EXTRA_CFLAGS=-DWG_USE_PUBLIC_KEY_COMPRESSION
但请注意,使用 WG_USE_PUBLIC_KEY_COMPRESSION 的 WolfGuard 与默认 WolfGuard 设置不兼容 — 设置后,需要在本地配置和在线协商中提供和期望压缩公钥。
(4) 构建并安装 libwolfssl 内核模块。将 /usr/src/linux 替换为实际目标内核源代码树的路径,该内核必须已完全配置并构建,且与目标系统将要启动的内核精确匹配。最后的 modprobe 假设目标是本地正在运行的系统。
$ cd wolfssl
$ ./configure --quiet --enable-wolfguard --enable-cryptonly --enable-intelasm \
--enable-linuxkm --with-linux-source=/usr/src/linux \
--prefix=$(pwd)/linuxkm/build
$ make -j module
# make install
# modprobe libwolfssl
在将 libwolfssl 内核模块投入生产之前,您应构建并加载启用了扩展自检的模块。将上面的 ./configure 配方替换为以下内容:
$ ./configure --quiet --enable-wolfguard --enable-cryptonly --enable-intelasm \
--enable-linuxkm --with-linux-source=/usr/src/linux \
--prefix=$(pwd)/linuxkm/build --enable-crypttests \
CFLAGS=-DWOLFSSL_LINUXKM_VERBOSE_DEBUG
额外的选项不适合生产环境,但使用这些选项配置的模块应在具有代表性的运行时环境中加载,以确认所有算法功能正常。
(5) 构建并安装 WolfGuard 内核模块。同样,将 /usr/src/linux 替换为实际目标内核源代码树的路径,并将 6.16.5-gentoo 替换为目标系统上 uname -r 返回的实际值。同样,构建后的 modprobe 假设目标是本地正在运行的系统。
$ cd ../wolfguard/kernel-src
$ make -j KERNELDIR=/usr/src/linux KERNELRELEASE=6.16.5-gentoo
# make install
# modprobe wolfguard
$ ../user-src/wg-fips genkey | ../user-src/wg-fips pubkey
KERNELRELEASE 值实际上是 /lib/modules/ 下目标内核模块安装目录的名称。
最后一行中的 genkey 和 pubkey 操作是基本功能测试。如果一切正常,它将成功并打印一个随机公钥。
与上面的 wg-fips 构建一样,可以通过在 make 配方中添加 EXTRA_CFLAGS=-DWG_USE_PUBLIC_KEY_COMPRESSION 来启用压缩公钥支持。WG_USE_PUBLIC_KEY_COMPRESSION 设置必须在整个生态系统中保持一致。
如果以上所有步骤都成功,那么您现在就可以启动 WolfGuard 隧道了。现有的 WireGuard playbook 和脚本可以直接使用,只需将 /etc/wolfguard 替换为 /etc/wireguard,并使用 WolfGuard 的 wg-fips 工具(此时 wg 将是 wg-fips 的链接)生成所有密钥。
FIPS 认证版本的 wolfssl 源代码存档单独提供。请联系 [email protected]。
(1) 为源代码创建顶层目录并填充内容。此过程假设使用 7z 格式的 wolfssl 存档 — 如果是 .tar.gz 存档,请替换为 tar -xf。无论哪种情况,调整 ln -s 配方以确保 wolfssl 是指向解压后的 wolfssl 目录的符号链接。另请注意,FIPS 内核模块存档与非内核存档不同,但它们可用于构建 FIPS 用户库,如下所示。
$ mkdir wolf-sources
$ cd wolf-sources
$ 7z x ~/Downloads/wolfssl-X-fips-linuxvX-kernel.7z
$ ln -s wolfssl-X-fips-linuxvX-kernel wolfssl
$ git clone https://github.com/wolfssl/wolfguard
(2) 构建并安装 libwolfssl 用户库。
请注意,此步骤在 Linux 上是可选的,默认情况下 wg-fips 会将密钥生成和转换操作卸载到内核模块,而非内部执行。
$ cd wolfssl
$ ./configure --quiet --enable-fips=vX --enable-wolfguard
$ make -j
$ ./fips-hash.sh
$ make -j
$ ./wolfcrypt/test/testwolfcrypt
# make install
$ cd ..
请注意,--enable-fips 的参数必须与存档的 FIPS 版本匹配。目前最适合 WolfGuard 使用的参数是 v5.2.4 和 v6。
(3) 构建并安装 wg-fips 用户工具 — 请注意,安装会将目标目录中现有的 WireGuard wg 和 wg-quick 可执行文件及手册页(如果存在)分别移动到 wg-wireguard 和 wg-wireguard-quick,并安装指向 WolfGuard 版本的 wg 和 wg-quick 符号链接。
$ cd wolfguard/user-src
$ make -j
# make install
$ cd ../..
要在 Linux 上强制使用内部密钥操作,而非默认卸载到内核模块,请将 make -j 替换为 make -j NO_IPC_LLCRYPTO=1。
(4) 构建并安装 libwolfssl 内核模块。将 /usr/src/linux 替换为实际目标内核源代码树的路径,该内核必须已完全配置并构建,且与目标系统将要启动的内核精确匹配。
这是一个两步过程。首先,使用错误的完整性哈希构建并安装模块。然后加载它以捕获正确的哈希,该操作会提前退出并显示预期的“操作已取消”错误。然后使用正确的哈希重新构建并加载模块。请注意,这些说明假设目标是本地系统。另请注意,与 Linux 内核模式兼容的最低 libwolfssl FIPS 版本是 v5.2.4。
$ cd wolfssl
$ ./configure --quiet --enable-fips=vX --enable-wolfguard --enable-cryptonly \
--enable-linuxkm --with-linux-source=/usr/src/linux \
--prefix=$(pwd)/linuxkm/build
$ make -j module
# make install
# modprobe libwolfssl
(预期上述 modprobe 会提前退出,并显示“操作已取消”消息。)
$ NEWHASH=$(dmesg | awk '{if (match($0, " new hash \"([^\"]+)\" ", hash_a)) { hash = hash_a[1]; }} END {print hash}')
$ sed --in-place=.bak "s/^\".*\";/\"${NEWHASH}\";/" wolfcrypt/src/fips_test.c
$ make -j module
# make install
# modprobe libwolfssl
如果第二次 modprobe 像第一次一样失败,并在内核日志中再次出现“Update verifyCore[] in fips_test.c with new hash ...”消息,则说明您的工具链或目标内核配置阻止了可重现构建。在这种情况下,您应使用以下替代策略,替换上面 NEWHASH= 命令之后的步骤:
$ make module-update-fips-hash FIPS_HASH="$NEWHASH"
# make install
# modprobe libwolfssl
在将 libwolfssl 内核模块投入生产之前,您应构建并加载启用了扩展自检的模块。为此,请将上面的 ./configure 配方替换为以下内容:
$ ./configure --quiet --enable-fips=vX --enable-wolfguard --enable-cryptonly \
--enable-linuxkm --with-linux-source=/usr/src/linux \
--prefix=$(pwd)/linuxkm/build --enable-crypttests \
CFLAGS=-DWOLFSSL_LINUXKM_VERBOSE_DEBUG
额外的选项不适合生产环境,但使用这些选项配置的模块应在具有代表性的运行时环境中加载,以确认所有算法功能正常。
(5) 构建并安装 WolfGuard 内核模块。同样,将 /usr/src/linux 替换为实际目标内核源代码树的路径,并将 6.16.5-gentoo 替换为目标系统上 uname -r 返回的实际值。
$ cd ../wolfguard/kernel-src
$ make -j KERNELDIR=/usr/src/linux KERNELRELEASE=6.16.5-gentoo
# make install
# modprobe wolfguard
$ ../user-src/wg-fips genkey | ../user-src/wg-fips pubkey
最后一行中的 genkey 和 pubkey 操作是基本功能测试。如果一切正常,它将成功并打印一个随机公钥。
与非 FIPS 认证过程一样,如果以上所有步骤都成功,那么您现在就可以启动 WolfGuard 隧道了。现有的 WireGuard playbook 和脚本可以直接使用,只需将 /etc/wolfguard 替换为 /etc/wireguard,并使用 WolfGuard 的 wg-fips 工具(此时 wg 将是 wg-fips 的链接)生成所有密钥。但请注意,某些 WireGuard 客户端应用程序和自动化框架期望导出的 WireGuard 公钥恰好包含 44 个 base64 字符。WolfGuard 公钥的长度大约是其两倍,除非使用 WG_USE_PUBLIC_KEY_COMPRESSION 构建,该选项目前不受 FIPS v5 支持,但受 FIPS v6 及更高版本支持。