Skip to content

Commit

Permalink
mptcp: move crypto test to KUNIT
Browse files Browse the repository at this point in the history
currently MPTCP uses a custom hook to executed unit tests at
boot time. Let's use the KUNIT framework instead.
Additionally move the relevant code to a separate file and
export the function needed by the test when self-tests
are build as a module.

Co-developed-by: Matthieu Baerts <[email protected]>
Signed-off-by: Matthieu Baerts <[email protected]>
Signed-off-by: Paolo Abeni <[email protected]>
Reviewed-by: Mat Martineau <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Paolo Abeni authored and davem330 committed Jun 26, 2020
1 parent 2c5ebd0 commit a00a582
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 67 deletions.
20 changes: 14 additions & 6 deletions net/mptcp/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,20 @@ config MPTCP_IPV6
select IPV6
default y

config MPTCP_HMAC_TEST
bool "Tests for MPTCP HMAC implementation"
endif

config MPTCP_KUNIT_TESTS
tristate "This builds the MPTCP KUnit tests" if !KUNIT_ALL_TESTS
select MPTCP
depends on KUNIT
default KUNIT_ALL_TESTS
help
This option enable boot time self-test for the HMAC implementation
used by the MPTCP code
Currently covers the MPTCP crypto helpers.
Only useful for kernel devs running KUnit test harness and are not
for inclusion into a production build.

Say N if you are unsure.
For more information on KUnit and unit tests in general please refer
to the KUnit documentation in Documentation/dev-tools/kunit/.

If unsure, say N.

endif
3 changes: 3 additions & 0 deletions net/mptcp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ obj-$(CONFIG_MPTCP) += mptcp.o

mptcp-y := protocol.o subflow.o options.o token.o crypto.o ctrl.o pm.o diag.o \
mib.o pm_netlink.o

mptcp_crypto_test-objs := crypto_test.o
obj-$(CONFIG_MPTCP_KUNIT_TESTS) += mptcp_crypto_test.o
63 changes: 2 additions & 61 deletions net/mptcp/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,65 +87,6 @@ void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac)
sha256_final(&state, (u8 *)hmac);
}

#ifdef CONFIG_MPTCP_HMAC_TEST
struct test_cast {
char *key;
char *msg;
char *result;
};

/* we can't reuse RFC 4231 test vectors, as we have constraint on the
* input and key size.
*/
static struct test_cast tests[] = {
{
.key = "0b0b0b0b0b0b0b0b",
.msg = "48692054",
.result = "8385e24fb4235ac37556b6b886db106284a1da671699f46db1f235ec622dcafa",
},
{
.key = "aaaaaaaaaaaaaaaa",
.msg = "dddddddd",
.result = "2c5e219164ff1dca1c4a92318d847bb6b9d44492984e1eb71aff9022f71046e9",
},
{
.key = "0102030405060708",
.msg = "cdcdcdcd",
.result = "e73b9ba9969969cefb04aa0d6df18ec2fcc075b6f23b4d8c4da736a5dbbc6e7d",
},
};

static int __init test_mptcp_crypto(void)
{
char hmac[32], hmac_hex[65];
u32 nonce1, nonce2;
u64 key1, key2;
u8 msg[8];
int i, j;

for (i = 0; i < ARRAY_SIZE(tests); ++i) {
/* mptcp hmap will convert to be before computing the hmac */
key1 = be64_to_cpu(*((__be64 *)&tests[i].key[0]));
key2 = be64_to_cpu(*((__be64 *)&tests[i].key[8]));
nonce1 = be32_to_cpu(*((__be32 *)&tests[i].msg[0]));
nonce2 = be32_to_cpu(*((__be32 *)&tests[i].msg[4]));

put_unaligned_be32(nonce1, &msg[0]);
put_unaligned_be32(nonce2, &msg[4]);

mptcp_crypto_hmac_sha(key1, key2, msg, 8, hmac);
for (j = 0; j < 32; ++j)
sprintf(&hmac_hex[j << 1], "%02x", hmac[j] & 0xff);
hmac_hex[64] = 0;

if (memcmp(hmac_hex, tests[i].result, 64))
pr_err("test %d failed, got %s expected %s", i,
hmac_hex, tests[i].result);
else
pr_info("test %d [ ok ]", i);
}
return 0;
}

late_initcall(test_mptcp_crypto);
#if IS_MODULE(CONFIG_MPTCP_KUNIT_TESTS)
EXPORT_SYMBOL_GPL(mptcp_crypto_hmac_sha);
#endif
72 changes: 72 additions & 0 deletions net/mptcp/crypto_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: GPL-2.0
#include <kunit/test.h>

#include "protocol.h"

struct test_case {
char *key;
char *msg;
char *result;
};

/* we can't reuse RFC 4231 test vectors, as we have constraint on the
* input and key size.
*/
static struct test_case tests[] = {
{
.key = "0b0b0b0b0b0b0b0b",
.msg = "48692054",
.result = "8385e24fb4235ac37556b6b886db106284a1da671699f46db1f235ec622dcafa",
},
{
.key = "aaaaaaaaaaaaaaaa",
.msg = "dddddddd",
.result = "2c5e219164ff1dca1c4a92318d847bb6b9d44492984e1eb71aff9022f71046e9",
},
{
.key = "0102030405060708",
.msg = "cdcdcdcd",
.result = "e73b9ba9969969cefb04aa0d6df18ec2fcc075b6f23b4d8c4da736a5dbbc6e7d",
},
};

static void mptcp_crypto_test_basic(struct kunit *test)
{
char hmac[32], hmac_hex[65];
u32 nonce1, nonce2;
u64 key1, key2;
u8 msg[8];
int i, j;

for (i = 0; i < ARRAY_SIZE(tests); ++i) {
/* mptcp hmap will convert to be before computing the hmac */
key1 = be64_to_cpu(*((__be64 *)&tests[i].key[0]));
key2 = be64_to_cpu(*((__be64 *)&tests[i].key[8]));
nonce1 = be32_to_cpu(*((__be32 *)&tests[i].msg[0]));
nonce2 = be32_to_cpu(*((__be32 *)&tests[i].msg[4]));

put_unaligned_be32(nonce1, &msg[0]);
put_unaligned_be32(nonce2, &msg[4]);

mptcp_crypto_hmac_sha(key1, key2, msg, 8, hmac);
for (j = 0; j < 32; ++j)
sprintf(&hmac_hex[j << 1], "%02x", hmac[j] & 0xff);
hmac_hex[64] = 0;

KUNIT_EXPECT_STREQ(test, &hmac_hex[0], tests[i].result);
}
}

static struct kunit_case mptcp_crypto_test_cases[] = {
KUNIT_CASE(mptcp_crypto_test_basic),
{}
};

static struct kunit_suite mptcp_crypto_suite = {
.name = "mptcp-crypto",
.test_cases = mptcp_crypto_test_cases,
};

kunit_test_suite(mptcp_crypto_suite);

MODULE_LICENSE("GPL");

0 comments on commit a00a582

Please sign in to comment.