xref: /linux/net/rxrpc/tests/rxrpc_kunit.c (revision 432042e25e33d0db9c12bbe4ee3fa234d3b061af)
1f10e73dfSEric Biggers // SPDX-License-Identifier: GPL-2.0-only
2f10e73dfSEric Biggers /*
3f10e73dfSEric Biggers  * Unit tests for RxRPC crypto functions
4f10e73dfSEric Biggers  *
5f10e73dfSEric Biggers  * Copyright 2026 Google LLC
6f10e73dfSEric Biggers  */
7f10e73dfSEric Biggers #include "../ar-internal.h"
8*432042e2SEric Biggers #include <crypto/des.h>
9f10e73dfSEric Biggers #include <kunit/test.h>
10f10e73dfSEric Biggers 
11f10e73dfSEric Biggers struct fcrypt_pcbc_testvec {
12f10e73dfSEric Biggers 	u8 key[FCRYPT_BSIZE];
13f10e73dfSEric Biggers 	u8 iv[FCRYPT_BSIZE];
14f10e73dfSEric Biggers 	const u8 *ptext; /* plaintext */
15f10e73dfSEric Biggers 	const u8 *ctext; /* ciphertext */
16f10e73dfSEric Biggers 	size_t nblocks; /* length of ptext and ctext in blocks */
17f10e73dfSEric Biggers };
18f10e73dfSEric Biggers 
19f10e73dfSEric Biggers /* FCrypt-PCBC test vectors */
20f10e73dfSEric Biggers static const struct fcrypt_pcbc_testvec fcrypt_pcbc_testvecs[] = {
21f10e73dfSEric Biggers 	{
22f10e73dfSEric Biggers 		/* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */
23f10e73dfSEric Biggers 		.key = "\x00\x00\x00\x00\x00\x00\x00\x00",
24f10e73dfSEric Biggers 		.iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
25f10e73dfSEric Biggers 		.ptext = "\x00\x00\x00\x00\x00\x00\x00\x00",
26f10e73dfSEric Biggers 		.ctext = "\x0E\x09\x00\xC7\x3E\xF7\xED\x41",
27f10e73dfSEric Biggers 		.nblocks = 1,
28f10e73dfSEric Biggers 	},
29f10e73dfSEric Biggers 	{
30f10e73dfSEric Biggers 		.key = "\x11\x44\x77\xAA\xDD\x00\x33\x66",
31f10e73dfSEric Biggers 		.iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
32f10e73dfSEric Biggers 		.ptext = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
33f10e73dfSEric Biggers 		.ctext = "\xD8\xED\x78\x74\x77\xEC\x06\x80",
34f10e73dfSEric Biggers 		.nblocks = 1,
35f10e73dfSEric Biggers 	},
36f10e73dfSEric Biggers 	{
37f10e73dfSEric Biggers 		/* From Arla */
38f10e73dfSEric Biggers 		.key = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
39f10e73dfSEric Biggers 		.iv = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
40f10e73dfSEric Biggers 		.ptext = "The quick brown fox jumps over the lazy dogs.\0\0",
41f10e73dfSEric Biggers 		.ctext = "\x00\xf0\x0e\x11\x75\xe6\x23\x82"
42f10e73dfSEric Biggers 			 "\xee\xac\x98\x62\x44\x51\xe4\x84"
43f10e73dfSEric Biggers 			 "\xc3\x59\xd8\xaa\x64\x60\xae\xf7"
44f10e73dfSEric Biggers 			 "\xd2\xd9\x13\x79\x72\xa3\x45\x03"
45f10e73dfSEric Biggers 			 "\x23\xb5\x62\xd7\x0c\xf5\x27\xd1"
46f10e73dfSEric Biggers 			 "\xf8\x91\x3c\xac\x44\x22\x92\xef",
47f10e73dfSEric Biggers 		.nblocks = 6,
48f10e73dfSEric Biggers 	},
49f10e73dfSEric Biggers 	{
50f10e73dfSEric Biggers 		.key = "\xfe\xdc\xba\x98\x76\x54\x32\x10",
51f10e73dfSEric Biggers 		.iv = "\xf0\xe1\xd2\xc3\xb4\xa5\x96\x87",
52f10e73dfSEric Biggers 		.ptext = "The quick brown fox jumps over the lazy dogs.\0\0",
53f10e73dfSEric Biggers 		.ctext = "\xca\x90\xf5\x9d\xcb\xd4\xd2\x3c"
54f10e73dfSEric Biggers 			 "\x01\x88\x7f\x3e\x31\x6e\x62\x9d"
55f10e73dfSEric Biggers 			 "\xd8\xe0\x57\xa3\x06\x3a\x42\x58"
56f10e73dfSEric Biggers 			 "\x2a\x28\xfe\x72\x52\x2f\xdd\xe0"
57f10e73dfSEric Biggers 			 "\x19\x89\x09\x1c\x2a\x8e\x8c\x94"
58f10e73dfSEric Biggers 			 "\xfc\xc7\x68\xe4\x88\xaa\xde\x0f",
59f10e73dfSEric Biggers 		.nblocks = 6,
60f10e73dfSEric Biggers 	}
61f10e73dfSEric Biggers };
62f10e73dfSEric Biggers 
63f10e73dfSEric Biggers static void test_fcrypt_pcbc(struct kunit *test)
64f10e73dfSEric Biggers {
65f10e73dfSEric Biggers 	u8 data[48];
66f10e73dfSEric Biggers 
67f10e73dfSEric Biggers 	for (size_t i = 0; i < ARRAY_SIZE(fcrypt_pcbc_testvecs); i++) {
68f10e73dfSEric Biggers 		const struct fcrypt_pcbc_testvec *tv = &fcrypt_pcbc_testvecs[i];
69f10e73dfSEric Biggers 		const size_t nblocks = tv->nblocks;
70f10e73dfSEric Biggers 		const size_t len = nblocks * FCRYPT_BSIZE;
71f10e73dfSEric Biggers 		struct fcrypt_key key;
72f10e73dfSEric Biggers 
73f10e73dfSEric Biggers 		KUNIT_ASSERT_GE(test, sizeof(data), len);
74f10e73dfSEric Biggers 
75f10e73dfSEric Biggers 		fcrypt_preparekey(&key, tv->key);
76f10e73dfSEric Biggers 
77f10e73dfSEric Biggers 		/* out-of-place encryption */
78f10e73dfSEric Biggers 		fcrypt_pcbc_encrypt(&key, tv->iv, tv->ptext, data, nblocks);
79f10e73dfSEric Biggers 		KUNIT_ASSERT_MEMEQ(test, tv->ctext, data, len);
80f10e73dfSEric Biggers 
81f10e73dfSEric Biggers 		/* in-place encryption */
82f10e73dfSEric Biggers 		memcpy(data, tv->ptext, len);
83f10e73dfSEric Biggers 		fcrypt_pcbc_encrypt(&key, tv->iv, data, data, nblocks);
84f10e73dfSEric Biggers 		KUNIT_ASSERT_MEMEQ(test, tv->ctext, data, len);
85f10e73dfSEric Biggers 
86f10e73dfSEric Biggers 		/* out-of-place decryption */
87f10e73dfSEric Biggers 		fcrypt_pcbc_decrypt(&key, tv->iv, tv->ctext, data, nblocks);
88f10e73dfSEric Biggers 		KUNIT_ASSERT_MEMEQ(test, tv->ptext, data, len);
89f10e73dfSEric Biggers 
90f10e73dfSEric Biggers 		/* in-place decryption */
91f10e73dfSEric Biggers 		memcpy(data, tv->ctext, len);
92f10e73dfSEric Biggers 		fcrypt_pcbc_decrypt(&key, tv->iv, data, data, nblocks);
93f10e73dfSEric Biggers 		KUNIT_ASSERT_MEMEQ(test, tv->ptext, data, len);
94f10e73dfSEric Biggers 	}
95f10e73dfSEric Biggers }
96f10e73dfSEric Biggers 
97*432042e2SEric Biggers static void test_des_pcbc(struct kunit *test)
98*432042e2SEric Biggers {
99*432042e2SEric Biggers 	/* This was generated from the original pcbc(des) crypto API code. */
100*432042e2SEric Biggers 	static const u8 expected_ptext[24] =
101*432042e2SEric Biggers 		"\xc8\xe2\x3c\xdf\x80\x61\x8a\xad\xa5\x52\xb4\x20"
102*432042e2SEric Biggers 		"\x74\x32\x1f\xe4\x2c\x15\x7d\x21\x57\xda\x3f\x31";
103*432042e2SEric Biggers 	u8 key[8];
104*432042e2SEric Biggers 	union {
105*432042e2SEric Biggers 		__le64 w;
106*432042e2SEric Biggers 		u8 b[8];
107*432042e2SEric Biggers 	} iv;
108*432042e2SEric Biggers 	u8 data[24];
109*432042e2SEric Biggers 	struct des_ctx ctx;
110*432042e2SEric Biggers 	int err;
111*432042e2SEric Biggers 
112*432042e2SEric Biggers 	for (int i = 0; i < 8; i++) {
113*432042e2SEric Biggers 		key[i] = i;
114*432042e2SEric Biggers 		iv.b[i] = 255 - i;
115*432042e2SEric Biggers 	}
116*432042e2SEric Biggers 	for (int i = 0; i < sizeof(data); i++)
117*432042e2SEric Biggers 		data[i] = i;
118*432042e2SEric Biggers 
119*432042e2SEric Biggers 	err = des_expand_key(&ctx, key, sizeof(key));
120*432042e2SEric Biggers 	KUNIT_ASSERT_EQ(test, 0, err);
121*432042e2SEric Biggers 
122*432042e2SEric Biggers 	des_pcbc_decrypt_inplace(&ctx, iv.w, data, sizeof(data));
123*432042e2SEric Biggers 	KUNIT_ASSERT_MEMEQ(test, expected_ptext, data, sizeof(data));
124*432042e2SEric Biggers }
125*432042e2SEric Biggers 
126f10e73dfSEric Biggers static struct kunit_case rxrpc_test_cases[] = {
127f10e73dfSEric Biggers 	KUNIT_CASE(test_fcrypt_pcbc),
128*432042e2SEric Biggers 	KUNIT_CASE(test_des_pcbc),
129f10e73dfSEric Biggers 	{},
130f10e73dfSEric Biggers };
131f10e73dfSEric Biggers 
132f10e73dfSEric Biggers static struct kunit_suite rxrpc_test_suite = {
133f10e73dfSEric Biggers 	.name = "rxrpc",
134f10e73dfSEric Biggers 	.test_cases = rxrpc_test_cases,
135f10e73dfSEric Biggers };
136f10e73dfSEric Biggers kunit_test_suite(rxrpc_test_suite);
137f10e73dfSEric Biggers 
138f10e73dfSEric Biggers MODULE_DESCRIPTION("Unit tests for RxRPC crypto functions");
139f10e73dfSEric Biggers MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
140f10e73dfSEric Biggers MODULE_LICENSE("GPL");
141