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