keyring.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2023 Hannes Reinecke, SUSE Labs
  4. */
  5. #include <linux/module.h>
  6. #include <linux/seq_file.h>
  7. #include <linux/key-type.h>
  8. #include <keys/user-type.h>
  9. #include <linux/nvme.h>
  10. #include <linux/nvme-tcp.h>
  11. #include <linux/nvme-keyring.h>
  12. static struct key *nvme_keyring;
  13. key_serial_t nvme_keyring_id(void)
  14. {
  15. return nvme_keyring->serial;
  16. }
  17. EXPORT_SYMBOL_GPL(nvme_keyring_id);
  18. static bool nvme_tls_psk_revoked(struct key *psk)
  19. {
  20. return test_bit(KEY_FLAG_REVOKED, &psk->flags) ||
  21. test_bit(KEY_FLAG_INVALIDATED, &psk->flags);
  22. }
  23. struct key *nvme_tls_key_lookup(key_serial_t key_id)
  24. {
  25. struct key *key = key_lookup(key_id);
  26. if (IS_ERR(key)) {
  27. pr_err("key id %08x not found\n", key_id);
  28. return key;
  29. }
  30. if (nvme_tls_psk_revoked(key)) {
  31. pr_err("key id %08x revoked\n", key_id);
  32. return ERR_PTR(-EKEYREVOKED);
  33. }
  34. return key;
  35. }
  36. EXPORT_SYMBOL_GPL(nvme_tls_key_lookup);
  37. static void nvme_tls_psk_describe(const struct key *key, struct seq_file *m)
  38. {
  39. seq_puts(m, key->description);
  40. seq_printf(m, ": %u", key->datalen);
  41. }
  42. static bool nvme_tls_psk_match(const struct key *key,
  43. const struct key_match_data *match_data)
  44. {
  45. const char *match_id;
  46. size_t match_len;
  47. if (!key->description) {
  48. pr_debug("%s: no key description\n", __func__);
  49. return false;
  50. }
  51. if (!match_data->raw_data) {
  52. pr_debug("%s: no match data\n", __func__);
  53. return false;
  54. }
  55. match_id = match_data->raw_data;
  56. match_len = strlen(match_id);
  57. pr_debug("%s: match '%s' '%s' len %zd\n",
  58. __func__, match_id, key->description, match_len);
  59. return !memcmp(key->description, match_id, match_len);
  60. }
  61. static int nvme_tls_psk_match_preparse(struct key_match_data *match_data)
  62. {
  63. match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE;
  64. match_data->cmp = nvme_tls_psk_match;
  65. return 0;
  66. }
  67. static struct key_type nvme_tls_psk_key_type = {
  68. .name = "psk",
  69. .flags = KEY_TYPE_NET_DOMAIN,
  70. .preparse = user_preparse,
  71. .free_preparse = user_free_preparse,
  72. .match_preparse = nvme_tls_psk_match_preparse,
  73. .instantiate = generic_key_instantiate,
  74. .revoke = user_revoke,
  75. .destroy = user_destroy,
  76. .describe = nvme_tls_psk_describe,
  77. .read = user_read,
  78. };
  79. static struct key *nvme_tls_psk_lookup(struct key *keyring,
  80. const char *hostnqn, const char *subnqn,
  81. u8 hmac, u8 psk_ver, bool generated)
  82. {
  83. char *identity;
  84. size_t identity_len = (NVMF_NQN_SIZE) * 2 + 11;
  85. key_ref_t keyref;
  86. key_serial_t keyring_id;
  87. identity = kzalloc(identity_len, GFP_KERNEL);
  88. if (!identity)
  89. return ERR_PTR(-ENOMEM);
  90. snprintf(identity, identity_len, "NVMe%u%c%02u %s %s",
  91. psk_ver, generated ? 'G' : 'R', hmac, hostnqn, subnqn);
  92. if (!keyring)
  93. keyring = nvme_keyring;
  94. keyring_id = key_serial(keyring);
  95. pr_debug("keyring %x lookup tls psk '%s'\n",
  96. keyring_id, identity);
  97. keyref = keyring_search(make_key_ref(keyring, true),
  98. &nvme_tls_psk_key_type,
  99. identity, false);
  100. if (IS_ERR(keyref)) {
  101. pr_debug("lookup tls psk '%s' failed, error %ld\n",
  102. identity, PTR_ERR(keyref));
  103. kfree(identity);
  104. return ERR_PTR(-ENOKEY);
  105. }
  106. kfree(identity);
  107. return key_ref_to_ptr(keyref);
  108. }
  109. /**
  110. * nvme_tls_psk_refresh - Refresh TLS PSK
  111. * @keyring: Keyring holding the TLS PSK
  112. * @hostnqn: Host NQN to use
  113. * @subnqn: Subsystem NQN to use
  114. * @hmac_id: Hash function identifier
  115. * @data: TLS PSK key material
  116. * @data_len: Length of @data
  117. * @digest: TLS PSK digest
  118. *
  119. * Refresh a generated version 1 TLS PSK with the identity generated
  120. * from @hmac_id, @hostnqn, @subnqn, and @digest in the keyring given
  121. * by @keyring.
  122. *
  123. * Returns the updated key success or an error pointer otherwise.
  124. */
  125. struct key *nvme_tls_psk_refresh(struct key *keyring,
  126. const char *hostnqn, const char *subnqn, u8 hmac_id,
  127. u8 *data, size_t data_len, const char *digest)
  128. {
  129. key_perm_t keyperm =
  130. KEY_POS_SEARCH | KEY_POS_VIEW | KEY_POS_READ |
  131. KEY_POS_WRITE | KEY_POS_LINK | KEY_POS_SETATTR |
  132. KEY_USR_SEARCH | KEY_USR_VIEW | KEY_USR_READ;
  133. char *identity;
  134. key_ref_t keyref;
  135. key_serial_t keyring_id;
  136. struct key *key;
  137. if (!hostnqn || !subnqn || !data || !data_len)
  138. return ERR_PTR(-EINVAL);
  139. identity = kasprintf(GFP_KERNEL, "NVMe1G%02d %s %s %s",
  140. hmac_id, hostnqn, subnqn, digest);
  141. if (!identity)
  142. return ERR_PTR(-ENOMEM);
  143. if (!keyring)
  144. keyring = nvme_keyring;
  145. keyring_id = key_serial(keyring);
  146. pr_debug("keyring %x refresh tls psk '%s'\n",
  147. keyring_id, identity);
  148. keyref = key_create_or_update(make_key_ref(keyring, true),
  149. "psk", identity, data, data_len,
  150. keyperm, KEY_ALLOC_NOT_IN_QUOTA |
  151. KEY_ALLOC_BUILT_IN |
  152. KEY_ALLOC_BYPASS_RESTRICTION);
  153. if (IS_ERR(keyref)) {
  154. pr_debug("refresh tls psk '%s' failed, error %ld\n",
  155. identity, PTR_ERR(keyref));
  156. kfree(identity);
  157. return ERR_PTR(-ENOKEY);
  158. }
  159. kfree(identity);
  160. /*
  161. * Set the default timeout to 1 hour
  162. * as suggested in TP8018.
  163. */
  164. key = key_ref_to_ptr(keyref);
  165. key_set_timeout(key, 3600);
  166. return key;
  167. }
  168. EXPORT_SYMBOL_GPL(nvme_tls_psk_refresh);
  169. /*
  170. * NVMe PSK priority list
  171. *
  172. * 'Retained' PSKs (ie 'generated == false') should be preferred to 'generated'
  173. * PSKs, PSKs with hash (psk_ver 1) should be preferred to PSKs without hash
  174. * (psk_ver 0), and SHA-384 should be preferred to SHA-256.
  175. */
  176. static struct nvme_tls_psk_priority_list {
  177. bool generated;
  178. u8 psk_ver;
  179. enum nvme_tcp_tls_cipher cipher;
  180. } nvme_tls_psk_prio[] = {
  181. { .generated = false,
  182. .psk_ver = 1,
  183. .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
  184. { .generated = false,
  185. .psk_ver = 1,
  186. .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
  187. { .generated = false,
  188. .psk_ver = 0,
  189. .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
  190. { .generated = false,
  191. .psk_ver = 0,
  192. .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
  193. { .generated = true,
  194. .psk_ver = 1,
  195. .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
  196. { .generated = true,
  197. .psk_ver = 1,
  198. .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
  199. { .generated = true,
  200. .psk_ver = 0,
  201. .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
  202. { .generated = true,
  203. .psk_ver = 0,
  204. .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
  205. };
  206. /*
  207. * nvme_tls_psk_default - Return the preferred PSK to use for TLS ClientHello
  208. */
  209. key_serial_t nvme_tls_psk_default(struct key *keyring,
  210. const char *hostnqn, const char *subnqn)
  211. {
  212. struct key *tls_key;
  213. key_serial_t tls_key_id;
  214. int prio;
  215. for (prio = 0; prio < ARRAY_SIZE(nvme_tls_psk_prio); prio++) {
  216. bool generated = nvme_tls_psk_prio[prio].generated;
  217. u8 ver = nvme_tls_psk_prio[prio].psk_ver;
  218. enum nvme_tcp_tls_cipher cipher = nvme_tls_psk_prio[prio].cipher;
  219. tls_key = nvme_tls_psk_lookup(keyring, hostnqn, subnqn,
  220. cipher, ver, generated);
  221. if (!IS_ERR(tls_key)) {
  222. tls_key_id = tls_key->serial;
  223. key_put(tls_key);
  224. return tls_key_id;
  225. }
  226. }
  227. return 0;
  228. }
  229. EXPORT_SYMBOL_GPL(nvme_tls_psk_default);
  230. static int __init nvme_keyring_init(void)
  231. {
  232. int err;
  233. nvme_keyring = keyring_alloc(".nvme",
  234. GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
  235. current_cred(),
  236. (KEY_POS_ALL & ~KEY_POS_SETATTR) |
  237. (KEY_USR_ALL & ~KEY_USR_SETATTR),
  238. KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
  239. if (IS_ERR(nvme_keyring))
  240. return PTR_ERR(nvme_keyring);
  241. err = register_key_type(&nvme_tls_psk_key_type);
  242. if (err) {
  243. key_put(nvme_keyring);
  244. return err;
  245. }
  246. return 0;
  247. }
  248. static void __exit nvme_keyring_exit(void)
  249. {
  250. unregister_key_type(&nvme_tls_psk_key_type);
  251. key_revoke(nvme_keyring);
  252. key_put(nvme_keyring);
  253. }
  254. MODULE_LICENSE("GPL v2");
  255. MODULE_AUTHOR("Hannes Reinecke <hare@suse.de>");
  256. MODULE_DESCRIPTION("NVMe Keyring implementation");
  257. module_init(nvme_keyring_init);
  258. module_exit(nvme_keyring_exit);