1*f990ad67SEric Biggers // SPDX-License-Identifier: GPL-2.0-only 2*f990ad67SEric Biggers /* 3*f990ad67SEric Biggers * Unit tests for NVMe authentication functions 4*f990ad67SEric Biggers * 5*f990ad67SEric Biggers * Copyright 2026 Google LLC 6*f990ad67SEric Biggers */ 7*f990ad67SEric Biggers 8*f990ad67SEric Biggers #include <crypto/sha2.h> 9*f990ad67SEric Biggers #include <kunit/test.h> 10*f990ad67SEric Biggers #include <linux/nvme.h> 11*f990ad67SEric Biggers #include <linux/nvme-auth.h> 12*f990ad67SEric Biggers #include <linux/slab.h> 13*f990ad67SEric Biggers 14*f990ad67SEric Biggers struct nvme_auth_test_values { 15*f990ad67SEric Biggers u8 hmac_id; 16*f990ad67SEric Biggers size_t hash_len; 17*f990ad67SEric Biggers u8 expected_psk[NVME_AUTH_MAX_DIGEST_SIZE]; 18*f990ad67SEric Biggers char *expected_psk_digest; 19*f990ad67SEric Biggers u8 expected_tls_psk[NVME_AUTH_MAX_DIGEST_SIZE]; 20*f990ad67SEric Biggers }; 21*f990ad67SEric Biggers 22*f990ad67SEric Biggers static void kfree_action(void *ptr) 23*f990ad67SEric Biggers { 24*f990ad67SEric Biggers kfree(ptr); 25*f990ad67SEric Biggers } 26*f990ad67SEric Biggers 27*f990ad67SEric Biggers static void kunit_add_kfree_action(struct kunit *test, void *ptr) 28*f990ad67SEric Biggers { 29*f990ad67SEric Biggers KUNIT_ASSERT_EQ(test, 0, 30*f990ad67SEric Biggers kunit_add_action_or_reset(test, kfree_action, ptr)); 31*f990ad67SEric Biggers } 32*f990ad67SEric Biggers 33*f990ad67SEric Biggers /* 34*f990ad67SEric Biggers * Test the derivation of a TLS PSK from the initial skey. The vals parameter 35*f990ad67SEric Biggers * gives the expected value of tls_psk as well as the intermediate values psk 36*f990ad67SEric Biggers * and psk_digest. The inputs are implicitly the fixed values set below. 37*f990ad67SEric Biggers */ 38*f990ad67SEric Biggers static void 39*f990ad67SEric Biggers test_nvme_auth_derive_tls_psk(struct kunit *test, 40*f990ad67SEric Biggers const struct nvme_auth_test_values *vals) 41*f990ad67SEric Biggers { 42*f990ad67SEric Biggers const u8 hmac_id = vals->hmac_id; 43*f990ad67SEric Biggers const size_t hash_len = vals->hash_len; 44*f990ad67SEric Biggers const size_t skey_len = hash_len; 45*f990ad67SEric Biggers u8 skey[NVME_AUTH_MAX_DIGEST_SIZE]; 46*f990ad67SEric Biggers u8 c1[NVME_AUTH_MAX_DIGEST_SIZE]; 47*f990ad67SEric Biggers u8 c2[NVME_AUTH_MAX_DIGEST_SIZE]; 48*f990ad67SEric Biggers const char *subsysnqn = "subsysnqn"; 49*f990ad67SEric Biggers const char *hostnqn = "hostnqn"; 50*f990ad67SEric Biggers u8 *psk = NULL, *tls_psk = NULL; 51*f990ad67SEric Biggers char *psk_digest = NULL; 52*f990ad67SEric Biggers size_t psk_len; 53*f990ad67SEric Biggers int ret; 54*f990ad67SEric Biggers 55*f990ad67SEric Biggers for (int i = 0; i < NVME_AUTH_MAX_DIGEST_SIZE; i++) { 56*f990ad67SEric Biggers skey[i] = 'A' + i; 57*f990ad67SEric Biggers c1[i] = i; 58*f990ad67SEric Biggers c2[i] = 0xff - i; 59*f990ad67SEric Biggers } 60*f990ad67SEric Biggers 61*f990ad67SEric Biggers ret = nvme_auth_generate_psk(hmac_id, skey, skey_len, c1, c2, hash_len, 62*f990ad67SEric Biggers &psk, &psk_len); 63*f990ad67SEric Biggers kunit_add_kfree_action(test, psk); 64*f990ad67SEric Biggers KUNIT_ASSERT_EQ(test, 0, ret); 65*f990ad67SEric Biggers KUNIT_ASSERT_EQ(test, hash_len, psk_len); 66*f990ad67SEric Biggers KUNIT_ASSERT_MEMEQ(test, vals->expected_psk, psk, psk_len); 67*f990ad67SEric Biggers 68*f990ad67SEric Biggers ret = nvme_auth_generate_digest(hmac_id, psk, psk_len, subsysnqn, 69*f990ad67SEric Biggers hostnqn, &psk_digest); 70*f990ad67SEric Biggers kunit_add_kfree_action(test, psk_digest); 71*f990ad67SEric Biggers if (vals->expected_psk_digest == NULL) { 72*f990ad67SEric Biggers /* 73*f990ad67SEric Biggers * Algorithm has an ID assigned but is not supported by 74*f990ad67SEric Biggers * nvme_auth_generate_digest(). 75*f990ad67SEric Biggers */ 76*f990ad67SEric Biggers KUNIT_ASSERT_EQ(test, -EINVAL, ret); 77*f990ad67SEric Biggers return; 78*f990ad67SEric Biggers } 79*f990ad67SEric Biggers KUNIT_ASSERT_EQ(test, 0, ret); 80*f990ad67SEric Biggers KUNIT_ASSERT_STREQ(test, vals->expected_psk_digest, psk_digest); 81*f990ad67SEric Biggers 82*f990ad67SEric Biggers ret = nvme_auth_derive_tls_psk(hmac_id, psk, psk_len, psk_digest, 83*f990ad67SEric Biggers &tls_psk); 84*f990ad67SEric Biggers kunit_add_kfree_action(test, tls_psk); 85*f990ad67SEric Biggers KUNIT_ASSERT_EQ(test, 0, ret); 86*f990ad67SEric Biggers KUNIT_ASSERT_MEMEQ(test, vals->expected_tls_psk, tls_psk, psk_len); 87*f990ad67SEric Biggers } 88*f990ad67SEric Biggers 89*f990ad67SEric Biggers static void test_nvme_auth_derive_tls_psk_hmac_sha256(struct kunit *test) 90*f990ad67SEric Biggers { 91*f990ad67SEric Biggers static const struct nvme_auth_test_values vals = { 92*f990ad67SEric Biggers .hmac_id = NVME_AUTH_HASH_SHA256, 93*f990ad67SEric Biggers .hash_len = SHA256_DIGEST_SIZE, 94*f990ad67SEric Biggers .expected_psk = { 95*f990ad67SEric Biggers 0x17, 0x33, 0xc5, 0x9f, 0xa7, 0xf4, 0x8f, 0xcf, 96*f990ad67SEric Biggers 0x37, 0xf5, 0xf2, 0x6f, 0xc4, 0xff, 0x02, 0x68, 97*f990ad67SEric Biggers 0xad, 0x4f, 0x78, 0xe0, 0x30, 0xf4, 0xf3, 0xb0, 98*f990ad67SEric Biggers 0xbf, 0xd1, 0xd4, 0x7e, 0x7b, 0xb1, 0x44, 0x7a, 99*f990ad67SEric Biggers }, 100*f990ad67SEric Biggers .expected_psk_digest = "OldoKuTfKddMuyCznAZojkWD7P4D9/AtzDzLimtOxqI=", 101*f990ad67SEric Biggers .expected_tls_psk = { 102*f990ad67SEric Biggers 0x3c, 0x17, 0xda, 0x62, 0x84, 0x74, 0xa0, 0x4d, 103*f990ad67SEric Biggers 0x22, 0x47, 0xc4, 0xca, 0xb4, 0x79, 0x68, 0xc9, 104*f990ad67SEric Biggers 0x15, 0x38, 0x81, 0x93, 0xf7, 0xc0, 0x71, 0xbd, 105*f990ad67SEric Biggers 0x94, 0x89, 0xcc, 0x36, 0x66, 0xcd, 0x7c, 0xc8, 106*f990ad67SEric Biggers }, 107*f990ad67SEric Biggers }; 108*f990ad67SEric Biggers 109*f990ad67SEric Biggers test_nvme_auth_derive_tls_psk(test, &vals); 110*f990ad67SEric Biggers } 111*f990ad67SEric Biggers 112*f990ad67SEric Biggers static void test_nvme_auth_derive_tls_psk_hmac_sha384(struct kunit *test) 113*f990ad67SEric Biggers { 114*f990ad67SEric Biggers static const struct nvme_auth_test_values vals = { 115*f990ad67SEric Biggers .hmac_id = NVME_AUTH_HASH_SHA384, 116*f990ad67SEric Biggers .hash_len = SHA384_DIGEST_SIZE, 117*f990ad67SEric Biggers .expected_psk = { 118*f990ad67SEric Biggers 0xf1, 0x4b, 0x2d, 0xd3, 0x23, 0x4c, 0x45, 0x96, 119*f990ad67SEric Biggers 0x94, 0xd3, 0xbc, 0x63, 0xf8, 0x96, 0x8b, 0xd6, 120*f990ad67SEric Biggers 0xb3, 0x7c, 0x2c, 0x6d, 0xe8, 0x49, 0xe2, 0x2e, 121*f990ad67SEric Biggers 0x11, 0x87, 0x49, 0x00, 0x1c, 0xe4, 0xbb, 0xe8, 122*f990ad67SEric Biggers 0x64, 0x0b, 0x9e, 0x3a, 0x74, 0x8c, 0xb1, 0x1c, 123*f990ad67SEric Biggers 0xe4, 0xb1, 0xd7, 0x1d, 0x35, 0x9c, 0xce, 0x39, 124*f990ad67SEric Biggers }, 125*f990ad67SEric Biggers .expected_psk_digest = "cffMWk8TSS7HOQebjgYEIkrPrjWPV4JE5cdPB8WhEvY4JBW5YynKyv66XscN4A9n", 126*f990ad67SEric Biggers .expected_tls_psk = { 127*f990ad67SEric Biggers 0x27, 0x74, 0x75, 0x32, 0x33, 0x53, 0x7b, 0x3f, 128*f990ad67SEric Biggers 0xa5, 0x0e, 0xb7, 0xd1, 0x6a, 0x8e, 0x43, 0x45, 129*f990ad67SEric Biggers 0x7d, 0x85, 0xf4, 0x90, 0x6c, 0x00, 0x5b, 0x22, 130*f990ad67SEric Biggers 0x36, 0x61, 0x6c, 0x5d, 0x80, 0x93, 0x9d, 0x08, 131*f990ad67SEric Biggers 0x98, 0xff, 0xf1, 0x5b, 0xb8, 0xb7, 0x71, 0x19, 132*f990ad67SEric Biggers 0xd2, 0xbe, 0x0a, 0xac, 0x42, 0x3e, 0x75, 0x90, 133*f990ad67SEric Biggers }, 134*f990ad67SEric Biggers }; 135*f990ad67SEric Biggers 136*f990ad67SEric Biggers test_nvme_auth_derive_tls_psk(test, &vals); 137*f990ad67SEric Biggers } 138*f990ad67SEric Biggers 139*f990ad67SEric Biggers static void test_nvme_auth_derive_tls_psk_hmac_sha512(struct kunit *test) 140*f990ad67SEric Biggers { 141*f990ad67SEric Biggers static const struct nvme_auth_test_values vals = { 142*f990ad67SEric Biggers .hmac_id = NVME_AUTH_HASH_SHA512, 143*f990ad67SEric Biggers .hash_len = SHA512_DIGEST_SIZE, 144*f990ad67SEric Biggers .expected_psk = { 145*f990ad67SEric Biggers 0x9c, 0x9f, 0x08, 0x9a, 0x61, 0x8b, 0x47, 0xd2, 146*f990ad67SEric Biggers 0xd7, 0x5f, 0x4b, 0x6c, 0x28, 0x07, 0x04, 0x24, 147*f990ad67SEric Biggers 0x48, 0x7b, 0x44, 0x5d, 0xd9, 0x6e, 0x70, 0xc4, 148*f990ad67SEric Biggers 0xc0, 0x9b, 0x55, 0xe8, 0xb6, 0x00, 0x01, 0x52, 149*f990ad67SEric Biggers 0xa3, 0x36, 0x3c, 0x34, 0x54, 0x04, 0x3f, 0x38, 150*f990ad67SEric Biggers 0xf0, 0xb8, 0x50, 0x36, 0xde, 0xd4, 0x06, 0x55, 151*f990ad67SEric Biggers 0x35, 0x0a, 0xa8, 0x7b, 0x8b, 0x6a, 0x28, 0x2b, 152*f990ad67SEric Biggers 0x5c, 0x1a, 0xca, 0xe1, 0x62, 0x33, 0xdd, 0x5b, 153*f990ad67SEric Biggers }, 154*f990ad67SEric Biggers /* nvme_auth_generate_digest() doesn't support SHA-512 yet. */ 155*f990ad67SEric Biggers .expected_psk_digest = NULL, 156*f990ad67SEric Biggers }; 157*f990ad67SEric Biggers 158*f990ad67SEric Biggers test_nvme_auth_derive_tls_psk(test, &vals); 159*f990ad67SEric Biggers } 160*f990ad67SEric Biggers 161*f990ad67SEric Biggers static struct kunit_case nvme_auth_test_cases[] = { 162*f990ad67SEric Biggers KUNIT_CASE(test_nvme_auth_derive_tls_psk_hmac_sha256), 163*f990ad67SEric Biggers KUNIT_CASE(test_nvme_auth_derive_tls_psk_hmac_sha384), 164*f990ad67SEric Biggers KUNIT_CASE(test_nvme_auth_derive_tls_psk_hmac_sha512), 165*f990ad67SEric Biggers {}, 166*f990ad67SEric Biggers }; 167*f990ad67SEric Biggers 168*f990ad67SEric Biggers static struct kunit_suite nvme_auth_test_suite = { 169*f990ad67SEric Biggers .name = "nvme-auth", 170*f990ad67SEric Biggers .test_cases = nvme_auth_test_cases, 171*f990ad67SEric Biggers }; 172*f990ad67SEric Biggers kunit_test_suite(nvme_auth_test_suite); 173*f990ad67SEric Biggers 174*f990ad67SEric Biggers MODULE_DESCRIPTION("Unit tests for NVMe authentication functions"); 175*f990ad67SEric Biggers MODULE_LICENSE("GPL"); 176