keyring.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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.h>
  8. #include <linux/key-type.h>
  9. #include <keys/user-type.h>
  10. #include <linux/nvme.h>
  11. #include <linux/nvme-tcp.h>
  12. #include <linux/nvme-keyring.h>
  13. static struct key *nvme_keyring;
  14. key_serial_t nvme_keyring_id(void)
  15. {
  16. return nvme_keyring->serial;
  17. }
  18. EXPORT_SYMBOL_GPL(nvme_keyring_id);
  19. static bool nvme_tls_psk_revoked(struct key *psk)
  20. {
  21. return test_bit(KEY_FLAG_REVOKED, &psk->flags) ||
  22. test_bit(KEY_FLAG_INVALIDATED, &psk->flags);
  23. }
  24. struct key *nvme_tls_key_lookup(key_serial_t key_id)
  25. {
  26. struct key *key = key_lookup(key_id);
  27. if (IS_ERR(key)) {
  28. pr_err("key id %08x not found\n", key_id);
  29. return key;
  30. }
  31. if (nvme_tls_psk_revoked(key)) {
  32. pr_err("key id %08x revoked\n", key_id);
  33. return ERR_PTR(-EKEYREVOKED);
  34. }
  35. return key;
  36. }
  37. EXPORT_SYMBOL_GPL(nvme_tls_key_lookup);
  38. static void nvme_tls_psk_describe(const struct key *key, struct seq_file *m)
  39. {
  40. seq_puts(m, key->description);
  41. seq_printf(m, ": %u", key->datalen);
  42. }
  43. static bool nvme_tls_psk_match(const struct key *key,
  44. const struct key_match_data *match_data)
  45. {
  46. const char *match_id;
  47. size_t match_len;
  48. if (!key->description) {
  49. pr_debug("%s: no key description\n", __func__);
  50. return false;
  51. }
  52. if (!match_data->raw_data) {
  53. pr_debug("%s: no match data\n", __func__);
  54. return false;
  55. }
  56. match_id = match_data->raw_data;
  57. match_len = strlen(match_id);
  58. pr_debug("%s: match '%s' '%s' len %zd\n",
  59. __func__, match_id, key->description, match_len);
  60. return !memcmp(key->description, match_id, match_len);
  61. }
  62. static int nvme_tls_psk_match_preparse(struct key_match_data *match_data)
  63. {
  64. match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE;
  65. match_data->cmp = nvme_tls_psk_match;
  66. return 0;
  67. }
  68. static struct key_type nvme_tls_psk_key_type = {
  69. .name = "psk",
  70. .flags = KEY_TYPE_NET_DOMAIN,
  71. .preparse = user_preparse,
  72. .free_preparse = user_free_preparse,
  73. .match_preparse = nvme_tls_psk_match_preparse,
  74. .instantiate = generic_key_instantiate,
  75. .revoke = user_revoke,
  76. .destroy = user_destroy,
  77. .describe = nvme_tls_psk_describe,
  78. .read = user_read,
  79. };
  80. static struct key *nvme_tls_psk_lookup(struct key *keyring,
  81. const char *hostnqn, const char *subnqn,
  82. u8 hmac, u8 psk_ver, bool generated)
  83. {
  84. char *identity;
  85. size_t identity_len = (NVMF_NQN_SIZE) * 2 + 11;
  86. key_ref_t keyref;
  87. key_serial_t keyring_id;
  88. identity = kzalloc(identity_len, GFP_KERNEL);
  89. if (!identity)
  90. return ERR_PTR(-ENOMEM);
  91. snprintf(identity, identity_len, "NVMe%u%c%02u %s %s",
  92. psk_ver, generated ? 'G' : 'R', hmac, hostnqn, subnqn);
  93. if (!keyring)
  94. keyring = nvme_keyring;
  95. keyring_id = key_serial(keyring);
  96. pr_debug("keyring %x lookup tls psk '%s'\n",
  97. keyring_id, identity);
  98. keyref = keyring_search(make_key_ref(keyring, true),
  99. &nvme_tls_psk_key_type,
  100. identity, false);
  101. if (IS_ERR(keyref)) {
  102. pr_debug("lookup tls psk '%s' failed, error %ld\n",
  103. identity, PTR_ERR(keyref));
  104. kfree(identity);
  105. return ERR_PTR(-ENOKEY);
  106. }
  107. kfree(identity);
  108. return key_ref_to_ptr(keyref);
  109. }
  110. /*
  111. * NVMe PSK priority list
  112. *
  113. * 'Retained' PSKs (ie 'generated == false') should be preferred to 'generated'
  114. * PSKs, PSKs with hash (psk_ver 1) should be preferred to PSKs without hash
  115. * (psk_ver 0), and SHA-384 should be preferred to SHA-256.
  116. */
  117. static struct nvme_tls_psk_priority_list {
  118. bool generated;
  119. u8 psk_ver;
  120. enum nvme_tcp_tls_cipher cipher;
  121. } nvme_tls_psk_prio[] = {
  122. { .generated = false,
  123. .psk_ver = 1,
  124. .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
  125. { .generated = false,
  126. .psk_ver = 1,
  127. .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
  128. { .generated = false,
  129. .psk_ver = 0,
  130. .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
  131. { .generated = false,
  132. .psk_ver = 0,
  133. .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
  134. { .generated = true,
  135. .psk_ver = 1,
  136. .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
  137. { .generated = true,
  138. .psk_ver = 1,
  139. .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
  140. { .generated = true,
  141. .psk_ver = 0,
  142. .cipher = NVME_TCP_TLS_CIPHER_SHA384, },
  143. { .generated = true,
  144. .psk_ver = 0,
  145. .cipher = NVME_TCP_TLS_CIPHER_SHA256, },
  146. };
  147. /*
  148. * nvme_tls_psk_default - Return the preferred PSK to use for TLS ClientHello
  149. */
  150. key_serial_t nvme_tls_psk_default(struct key *keyring,
  151. const char *hostnqn, const char *subnqn)
  152. {
  153. struct key *tls_key;
  154. key_serial_t tls_key_id;
  155. int prio;
  156. for (prio = 0; prio < ARRAY_SIZE(nvme_tls_psk_prio); prio++) {
  157. bool generated = nvme_tls_psk_prio[prio].generated;
  158. u8 ver = nvme_tls_psk_prio[prio].psk_ver;
  159. enum nvme_tcp_tls_cipher cipher = nvme_tls_psk_prio[prio].cipher;
  160. tls_key = nvme_tls_psk_lookup(keyring, hostnqn, subnqn,
  161. cipher, ver, generated);
  162. if (!IS_ERR(tls_key)) {
  163. tls_key_id = tls_key->serial;
  164. key_put(tls_key);
  165. return tls_key_id;
  166. }
  167. }
  168. return 0;
  169. }
  170. EXPORT_SYMBOL_GPL(nvme_tls_psk_default);
  171. static int __init nvme_keyring_init(void)
  172. {
  173. int err;
  174. nvme_keyring = keyring_alloc(".nvme",
  175. GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
  176. current_cred(),
  177. (KEY_POS_ALL & ~KEY_POS_SETATTR) |
  178. (KEY_USR_ALL & ~KEY_USR_SETATTR),
  179. KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
  180. if (IS_ERR(nvme_keyring))
  181. return PTR_ERR(nvme_keyring);
  182. err = register_key_type(&nvme_tls_psk_key_type);
  183. if (err) {
  184. key_put(nvme_keyring);
  185. return err;
  186. }
  187. return 0;
  188. }
  189. static void __exit nvme_keyring_exit(void)
  190. {
  191. unregister_key_type(&nvme_tls_psk_key_type);
  192. key_revoke(nvme_keyring);
  193. key_put(nvme_keyring);
  194. }
  195. MODULE_LICENSE("GPL v2");
  196. MODULE_AUTHOR("Hannes Reinecke <hare@suse.de>");
  197. MODULE_DESCRIPTION("NVMe Keyring implementation");
  198. module_init(nvme_keyring_init);
  199. module_exit(nvme_keyring_exit);