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