From: Marco Baffo <marco@mandelbit.com>
To: linux-crypto@vger.kernel.org
Cc: herbert@gondor.apana.org.au, davem@davemloft.net,
ebiggers@kernel.org, Jason@zx2c4.com, ardb@kernel.org,
tytso@mit.edu, jaegeuk@kernel.org, linux-fscrypt@vger.kernel.org,
kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me,
hare@suse.de, linux-nvme@lists.infradead.org,
andrew+netdev@lunn.ch, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, antonio@openvpn.net, sd@queasysnail.net,
linux-kernel@vger.kernel.org, Marco Baffo <marco@mandelbit.com>
Subject: [PATCH 2/5] lib/crypto: tests: add HKDF KUnit tests
Date: Tue, 21 Jul 2026 16:06:41 +0200 [thread overview]
Message-ID: <20260721140644.780006-3-marco@mandelbit.com> (raw)
In-Reply-To: <20260721140644.780006-1-marco@mandelbit.com>
Add KUnit tests for the HKDF-SHA{256,384,512} helpers using the
RFC 5869 SHA-256 vectors and SHA-384 and SHA-512 vectors generated
with "openssl kdf" from the same inputs. Also test empty salt and
info, multi-block output, and segmented info.
Signed-off-by: Marco Baffo <marco@mandelbit.com>
---
lib/crypto/.kunitconfig | 1 +
lib/crypto/tests/Kconfig | 8 +
lib/crypto/tests/Makefile | 1 +
lib/crypto/tests/hkdf_kunit.c | 276 ++++++++++++++++++++++++++++++++++
4 files changed, 286 insertions(+)
create mode 100644 lib/crypto/tests/hkdf_kunit.c
diff --git a/lib/crypto/.kunitconfig b/lib/crypto/.kunitconfig
index 3efc854a2c08..82739358aa44 100644
--- a/lib/crypto/.kunitconfig
+++ b/lib/crypto/.kunitconfig
@@ -8,6 +8,7 @@ CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_CHACHA20POLY1305_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_GHASH_KUNIT_TEST=y
+CONFIG_CRYPTO_LIB_HKDF_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_MD5_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_MLDSA_KUNIT_TEST=y
CONFIG_CRYPTO_LIB_NH_KUNIT_TEST=y
diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig
index bc084dde424f..900e5d3afd00 100644
--- a/lib/crypto/tests/Kconfig
+++ b/lib/crypto/tests/Kconfig
@@ -52,6 +52,14 @@ config CRYPTO_LIB_GHASH_KUNIT_TEST
help
KUnit tests for the GHASH library functions.
+config CRYPTO_LIB_HKDF_KUNIT_TEST
+ tristate "KUnit tests for HKDF" if !KUNIT_ALL_TESTS
+ depends on KUNIT && CRYPTO_LIB_SHA256 && CRYPTO_LIB_SHA512
+ default KUNIT_ALL_TESTS
+ help
+ KUnit tests for the HKDF-SHA256, HKDF-SHA384, and HKDF-SHA512 key
+ derivation functions.
+
config CRYPTO_LIB_MD5_KUNIT_TEST
tristate "KUnit tests for MD5" if !KUNIT_ALL_TESTS
depends on KUNIT && CRYPTO_LIB_MD5
diff --git a/lib/crypto/tests/Makefile b/lib/crypto/tests/Makefile
index a739413500b6..15a2f9b54458 100644
--- a/lib/crypto/tests/Makefile
+++ b/lib/crypto/tests/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST) += blake2s_kunit.o
obj-$(CONFIG_CRYPTO_LIB_CHACHA20POLY1305_KUNIT_TEST) += chacha20poly1305_kunit.o
obj-$(CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST) += curve25519_kunit.o
obj-$(CONFIG_CRYPTO_LIB_GHASH_KUNIT_TEST) += ghash_kunit.o
+obj-$(CONFIG_CRYPTO_LIB_HKDF_KUNIT_TEST) += hkdf_kunit.o
obj-$(CONFIG_CRYPTO_LIB_MD5_KUNIT_TEST) += md5_kunit.o
obj-$(CONFIG_CRYPTO_LIB_MLDSA_KUNIT_TEST) += mldsa_kunit.o
obj-$(CONFIG_CRYPTO_LIB_NH_KUNIT_TEST) += nh_kunit.o
diff --git a/lib/crypto/tests/hkdf_kunit.c b/lib/crypto/tests/hkdf_kunit.c
new file mode 100644
index 000000000000..e8f65d761cc0
--- /dev/null
+++ b/lib/crypto/tests/hkdf_kunit.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * KUnit tests for HKDF-SHA256, HKDF-SHA384, and HKDF-SHA512
+ *
+ * The HKDF-SHA256 test vectors are from RFC 5869 Appendix A. RFC 5869 does not
+ * provide SHA-384 or SHA-512 vectors, so those were generated with OpenSSL's
+ * "openssl kdf" command (available since OpenSSL 3.0) using the same inputs as
+ * the SHA-256 vectors. See: https://docs.openssl.org/3.0/man1/openssl-kdf/
+ *
+ * For example, the SHA-384 vector was generated with:
+ *
+ * $ openssl kdf -keylen 42 -kdfopt mode:EXTRACT_AND_EXPAND \
+ * -kdfopt digest:SHA384 \
+ * -kdfopt hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b \
+ * -kdfopt hexsalt:000102030405060708090a0b0c \
+ * -kdfopt hexinfo:f0f1f2f3f4f5f6f7f8f9 HKDF
+ */
+
+#include <crypto/hkdf.h>
+#include <kunit/test.h>
+
+#define RFC5869_A1_IKM_BYTE 0x0b
+#define RFC5869_A1_IKM_LEN 22
+#define RFC5869_A1_SALT_START 0x00
+#define RFC5869_A1_SALT_LEN 13
+#define RFC5869_A1_INFO_START 0xf0
+#define RFC5869_A1_INFO_LEN 10
+
+#define RFC5869_A2_IKM_START 0x00
+#define RFC5869_A2_IKM_LEN 80
+#define RFC5869_A2_SALT_START 0x60
+#define RFC5869_A2_SALT_LEN 80
+#define RFC5869_A2_INFO_START 0xb0
+#define RFC5869_A2_INFO_LEN 80
+
+#define SEGMENT_TEST_INFO_LEN 40
+#define SEGMENT_TEST_OKM_LEN 100
+
+/* RFC 5869 A.1: ikm = 22 x 0x0b, salt = 0x00..0x0c, info = 0xf0..0xf9 */
+static const u8 rfc5869_a1_okm[] = {
+ 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
+ 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
+ 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
+ 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
+ 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
+ 0x58, 0x65
+};
+
+/* RFC 5869 A.2: ikm = 0x00..0x4f, salt = 0x60..0xaf, info = 0xb0..0xff */
+static const u8 rfc5869_a2_okm[] = {
+ 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
+ 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
+ 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
+ 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
+ 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
+ 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
+ 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
+ 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
+ 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
+ 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
+ 0x1d, 0x87
+};
+
+/* RFC 5869 A.3: ikm = 22 x 0x0b, zero-length salt and info */
+static const u8 rfc5869_a3_okm[] = {
+ 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
+ 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
+ 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
+ 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
+ 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
+ 0x96, 0xc8
+};
+
+/* HKDF-SHA384 with the RFC 5869 A.1 inputs */
+static const u8 hkdf_sha384_a1_okm[] = {
+ 0x9b, 0x50, 0x97, 0xa8, 0x60, 0x38, 0xb8, 0x05,
+ 0x30, 0x90, 0x76, 0xa4, 0x4b, 0x3a, 0x9f, 0x38,
+ 0x06, 0x3e, 0x25, 0xb5, 0x16, 0xdc, 0xbf, 0x36,
+ 0x9f, 0x39, 0x4c, 0xfa, 0xb4, 0x36, 0x85, 0xf7,
+ 0x48, 0xb6, 0x45, 0x77, 0x63, 0xe4, 0xf0, 0x20,
+ 0x4f, 0xc5
+};
+
+/* HKDF-SHA512 with the RFC 5869 A.1 inputs */
+static const u8 hkdf_sha512_a1_okm[] = {
+ 0x83, 0x23, 0x90, 0x08, 0x6c, 0xda, 0x71, 0xfb,
+ 0x47, 0x62, 0x5b, 0xb5, 0xce, 0xb1, 0x68, 0xe4,
+ 0xc8, 0xe2, 0x6a, 0x1a, 0x16, 0xed, 0x34, 0xd9,
+ 0xfc, 0x7f, 0xe9, 0x2c, 0x14, 0x81, 0x57, 0x93,
+ 0x38, 0xda, 0x36, 0x2c, 0xb8, 0xd9, 0xf9, 0x25,
+ 0xd7, 0xcb
+};
+
+/*
+ * HKDF-SHA512 with the RFC 5869 A.3 inputs and okm_len = 150, so that the
+ * output spans multiple blocks and ends with a partial block
+ */
+static const u8 hkdf_sha512_a3_okm[] = {
+ 0xf5, 0xfa, 0x02, 0xb1, 0x82, 0x98, 0xa7, 0x2a,
+ 0x8c, 0x23, 0x89, 0x8a, 0x87, 0x03, 0x47, 0x2c,
+ 0x6e, 0xb1, 0x79, 0xdc, 0x20, 0x4c, 0x03, 0x42,
+ 0x5c, 0x97, 0x0e, 0x3b, 0x16, 0x4b, 0xf9, 0x0f,
+ 0xff, 0x22, 0xd0, 0x48, 0x36, 0xd0, 0xe2, 0x34,
+ 0x3b, 0xac, 0xc4, 0xe7, 0xcb, 0x60, 0x45, 0xfa,
+ 0xaa, 0x69, 0x8e, 0x0e, 0x3b, 0x3e, 0xb9, 0x13,
+ 0x31, 0x30, 0x6d, 0xef, 0x1d, 0xb8, 0x31, 0x9e,
+ 0x8a, 0x69, 0x9b, 0x5e, 0xe4, 0x5a, 0xb9, 0x93,
+ 0x84, 0x7d, 0xc4, 0xdf, 0x75, 0xbd, 0xe0, 0x23,
+ 0x69, 0x2c, 0x8c, 0x07, 0x10, 0xa6, 0x7a, 0x55,
+ 0x12, 0x3f, 0x10, 0xa8, 0xb2, 0xd8, 0x32, 0x7f,
+ 0x9e, 0xb1, 0x38, 0xda, 0x69, 0xd5, 0xbe, 0xa1,
+ 0xe0, 0x9a, 0x39, 0xea, 0x99, 0xa3, 0x41, 0xc0,
+ 0x0b, 0x2c, 0x9e, 0xe0, 0xd4, 0xba, 0x63, 0x21,
+ 0x15, 0xae, 0xc5, 0x16, 0xbb, 0x71, 0xe9, 0x22,
+ 0x7c, 0xb0, 0x0c, 0xa9, 0x8b, 0x7d, 0xfa, 0x8f,
+ 0x1c, 0x7e, 0xca, 0x60, 0xc9, 0x31, 0x28, 0x1f,
+ 0xa8, 0x5b, 0x87, 0x2f, 0x70, 0xb4
+};
+
+/*
+ * Utility function to initialize ikm/salt/info buffers.
+ * Fill 'buf' with 'len' consecutive byte values beginning with 'start'.
+ */
+static void fill_range(u8 *buf, size_t len, u8 start)
+{
+ for (size_t i = 0; i < len; i++)
+ buf[i] = start + i;
+}
+
+static void test_hkdf_sha256_rfc5869(struct kunit *test)
+{
+ struct hmac_sha256_key prk;
+ u8 ikm[RFC5869_A2_IKM_LEN];
+ u8 salt[RFC5869_A2_SALT_LEN];
+ u8 info[RFC5869_A2_INFO_LEN];
+ u8 okm[sizeof(rfc5869_a2_okm)];
+ struct hkdf_seg seg;
+
+ /* A.1: basic test case */
+ memset(ikm, RFC5869_A1_IKM_BYTE, RFC5869_A1_IKM_LEN);
+ fill_range(salt, RFC5869_A1_SALT_LEN, RFC5869_A1_SALT_START);
+ fill_range(info, RFC5869_A1_INFO_LEN, RFC5869_A1_INFO_START);
+ hkdf_sha256_extract(&prk, salt, RFC5869_A1_SALT_LEN,
+ ikm, RFC5869_A1_IKM_LEN);
+ seg = (struct hkdf_seg){ .data = info, .len = RFC5869_A1_INFO_LEN };
+ hkdf_sha256_expand(&prk, &seg, 1, okm, sizeof(rfc5869_a1_okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, rfc5869_a1_okm,
+ sizeof(rfc5869_a1_okm), "RFC 5869 A.1");
+
+ /* A.2: longer inputs, multi-block output ending in a partial block */
+ fill_range(ikm, RFC5869_A2_IKM_LEN, RFC5869_A2_IKM_START);
+ fill_range(salt, RFC5869_A2_SALT_LEN, RFC5869_A2_SALT_START);
+ fill_range(info, RFC5869_A2_INFO_LEN, RFC5869_A2_INFO_START);
+ hkdf_sha256_extract(&prk, salt, RFC5869_A2_SALT_LEN,
+ ikm, RFC5869_A2_IKM_LEN);
+ seg = (struct hkdf_seg){ .data = info, .len = RFC5869_A2_INFO_LEN };
+ hkdf_sha256_expand(&prk, &seg, 1, okm, sizeof(rfc5869_a2_okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, rfc5869_a2_okm,
+ sizeof(rfc5869_a2_okm), "RFC 5869 A.2");
+
+ /* A.3: zero-length salt and info */
+ memset(ikm, RFC5869_A1_IKM_BYTE, RFC5869_A1_IKM_LEN);
+ hkdf_sha256_extract(&prk, NULL, 0, ikm, RFC5869_A1_IKM_LEN);
+ hkdf_sha256_expand(&prk, NULL, 0, okm, sizeof(rfc5869_a3_okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, rfc5869_a3_okm,
+ sizeof(rfc5869_a3_okm),
+ "RFC 5869 A.3 with NULL salt and info");
+
+ /* A.3 again, with a non-NULL empty salt and an empty info segment */
+ hkdf_sha256_extract(&prk, salt, 0, ikm, RFC5869_A1_IKM_LEN);
+ seg = (struct hkdf_seg){ .data = info, .len = 0 };
+ hkdf_sha256_expand(&prk, &seg, 1, okm, sizeof(rfc5869_a3_okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, rfc5869_a3_okm,
+ sizeof(rfc5869_a3_okm),
+ "RFC 5869 A.3 with non-NULL empty salt and info");
+}
+
+static void test_hkdf_sha384_rfc5869_a1(struct kunit *test)
+{
+ struct hmac_sha384_key prk;
+ u8 ikm[RFC5869_A1_IKM_LEN];
+ u8 salt[RFC5869_A1_SALT_LEN];
+ u8 info[RFC5869_A1_INFO_LEN];
+ u8 okm[sizeof(hkdf_sha384_a1_okm)];
+ struct hkdf_seg seg;
+
+ memset(ikm, RFC5869_A1_IKM_BYTE, sizeof(ikm));
+ fill_range(salt, sizeof(salt), RFC5869_A1_SALT_START);
+ fill_range(info, sizeof(info), RFC5869_A1_INFO_START);
+ seg = (struct hkdf_seg){ .data = info, .len = sizeof(info) };
+ hkdf_sha384_extract(&prk, salt, sizeof(salt), ikm, sizeof(ikm));
+ hkdf_sha384_expand(&prk, &seg, 1, okm, sizeof(okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, hkdf_sha384_a1_okm, sizeof(okm),
+ "SHA-384 with RFC 5869 A.1 inputs");
+}
+
+static void test_hkdf_sha512_rfc5869_a1_a3(struct kunit *test)
+{
+ struct hmac_sha512_key prk;
+ u8 ikm[RFC5869_A1_IKM_LEN];
+ u8 salt[RFC5869_A1_SALT_LEN];
+ u8 info[RFC5869_A1_INFO_LEN];
+ u8 okm[sizeof(hkdf_sha512_a3_okm)];
+ struct hkdf_seg seg;
+
+ memset(ikm, RFC5869_A1_IKM_BYTE, sizeof(ikm));
+ fill_range(salt, sizeof(salt), RFC5869_A1_SALT_START);
+ fill_range(info, sizeof(info), RFC5869_A1_INFO_START);
+ seg = (struct hkdf_seg){ .data = info, .len = sizeof(info) };
+ hkdf_sha512_extract(&prk, salt, sizeof(salt), ikm, sizeof(ikm));
+ hkdf_sha512_expand(&prk, &seg, 1, okm, sizeof(hkdf_sha512_a1_okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, hkdf_sha512_a1_okm,
+ sizeof(hkdf_sha512_a1_okm),
+ "SHA-512 with RFC 5869 A.1 inputs");
+
+ hkdf_sha512_extract(&prk, NULL, 0, ikm, sizeof(ikm));
+ hkdf_sha512_expand(&prk, NULL, 0, okm, sizeof(hkdf_sha512_a3_okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, hkdf_sha512_a3_okm,
+ sizeof(hkdf_sha512_a3_okm),
+ "SHA-512 with RFC 5869 A.3 inputs and 150-byte OKM");
+}
+
+/* Test that splitting info into segments does not influence the output. */
+static void test_hkdf_expand_info_segments(struct kunit *test)
+{
+ struct hmac_sha512_key prk;
+ u8 ikm[RFC5869_A1_IKM_LEN];
+ u8 info[SEGMENT_TEST_INFO_LEN];
+ u8 okm_ref[SEGMENT_TEST_OKM_LEN];
+ u8 okm[SEGMENT_TEST_OKM_LEN];
+ struct hkdf_seg segs[sizeof(info)];
+
+ memset(ikm, RFC5869_A1_IKM_BYTE, sizeof(ikm));
+ fill_range(info, sizeof(info), 0x00);
+ hkdf_sha512_extract(&prk, NULL, 0, ikm, sizeof(ikm));
+
+ segs[0] = (struct hkdf_seg){ .data = info, .len = sizeof(info) };
+ hkdf_sha512_expand(&prk, segs, 1, okm_ref, sizeof(okm_ref));
+
+ /* every possible two-way split */
+ for (size_t split = 0; split <= sizeof(info); split++) {
+ segs[0] = (struct hkdf_seg){ .data = info, .len = split };
+ segs[1] = (struct hkdf_seg){ .data = &info[split],
+ .len = sizeof(info) - split };
+ memset(okm, 0, sizeof(okm));
+ hkdf_sha512_expand(&prk, segs, 2, okm, sizeof(okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, okm_ref, sizeof(okm),
+ "failed for split=%zu", split);
+ }
+
+ /* one segment per byte */
+ for (size_t i = 0; i < sizeof(info); i++)
+ segs[i] = (struct hkdf_seg){ .data = &info[i], .len = 1 };
+ memset(okm, 0, sizeof(okm));
+ hkdf_sha512_expand(&prk, segs, sizeof(info), okm, sizeof(okm));
+ KUNIT_EXPECT_MEMEQ_MSG(test, okm, okm_ref, sizeof(okm),
+ "one info segment per byte");
+}
+
+static struct kunit_case hkdf_test_cases[] = {
+ KUNIT_CASE(test_hkdf_sha256_rfc5869),
+ KUNIT_CASE(test_hkdf_sha384_rfc5869_a1),
+ KUNIT_CASE(test_hkdf_sha512_rfc5869_a1_a3),
+ KUNIT_CASE(test_hkdf_expand_info_segments),
+ {},
+};
+
+static struct kunit_suite hkdf_test_suite = {
+ .name = "hkdf",
+ .test_cases = hkdf_test_cases,
+};
+
+kunit_test_suite(hkdf_test_suite);
+
+MODULE_DESCRIPTION("KUnit tests for HKDF-SHA256, HKDF-SHA384, and HKDF-SHA512");
+MODULE_LICENSE("GPL");
--
2.43.0
next prev parent reply other threads:[~2026-07-21 14:07 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-21 14:06 [PATCH 0/5] lib/crypto: add HKDF and convert fscrypt and NVMe Marco Baffo
2026-07-21 14:06 ` [PATCH 1/5] lib/crypto: add HKDF-SHA{256,384,512} Marco Baffo
2026-07-21 14:06 ` Marco Baffo [this message]
2026-07-21 14:06 ` [PATCH 3/5] fscrypt: use HKDF library functions Marco Baffo
2026-07-21 14:06 ` [PATCH 4/5] nvme-auth: use HKDF library functions for TLS PSK derivation Marco Baffo
2026-07-21 14:06 ` [RFC PATCH 5/5] ovpn: use HKDF library functions for epoch key derivation Marco Baffo
2026-07-21 15:06 ` [PATCH 0/5] lib/crypto: add HKDF and convert fscrypt and NVMe Eric Biggers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260721140644.780006-3-marco@mandelbit.com \
--to=marco@mandelbit.com \
--cc=Jason@zx2c4.com \
--cc=andrew+netdev@lunn.ch \
--cc=antonio@openvpn.net \
--cc=ardb@kernel.org \
--cc=axboe@kernel.dk \
--cc=davem@davemloft.net \
--cc=ebiggers@kernel.org \
--cc=edumazet@google.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=herbert@gondor.apana.org.au \
--cc=jaegeuk@kernel.org \
--cc=kbusch@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=pabeni@redhat.com \
--cc=sagi@grimberg.me \
--cc=sd@queasysnail.net \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox