pkey_uv.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * pkey uv specific code
  4. *
  5. * Copyright IBM Corp. 2024
  6. */
  7. #define pr_fmt(fmt) "pkey: " fmt
  8. #include <linux/cpufeature.h>
  9. #include <linux/init.h>
  10. #include <linux/module.h>
  11. #include <asm/uv.h>
  12. #include "zcrypt_ccamisc.h"
  13. #include "pkey_base.h"
  14. MODULE_LICENSE("GPL");
  15. MODULE_AUTHOR("IBM Corporation");
  16. MODULE_DESCRIPTION("s390 protected key UV handler");
  17. /*
  18. * One pre-allocated uv_secret_list for use with uv_find_secret()
  19. */
  20. static struct uv_secret_list *uv_list;
  21. static DEFINE_MUTEX(uv_list_mutex);
  22. /*
  23. * UV secret token struct and defines.
  24. */
  25. #define TOKVER_UV_SECRET 0x09
  26. struct uvsecrettoken {
  27. u8 type; /* 0x00 = TOKTYPE_NON_CCA */
  28. u8 res0[3];
  29. u8 version; /* 0x09 = TOKVER_UV_SECRET */
  30. u8 res1[3];
  31. u16 secret_type; /* one of enum uv_secret_types from uv.h */
  32. u16 secret_len; /* length in bytes of the secret */
  33. u8 secret_id[UV_SECRET_ID_LEN]; /* the secret id for this secret */
  34. } __packed;
  35. /*
  36. * Check key blob for known and supported UV key.
  37. */
  38. static bool is_uv_key(const u8 *key, u32 keylen)
  39. {
  40. struct uvsecrettoken *t = (struct uvsecrettoken *)key;
  41. if (keylen < sizeof(*t))
  42. return false;
  43. switch (t->type) {
  44. case TOKTYPE_NON_CCA:
  45. switch (t->version) {
  46. case TOKVER_UV_SECRET:
  47. switch (t->secret_type) {
  48. case UV_SECRET_AES_128:
  49. case UV_SECRET_AES_192:
  50. case UV_SECRET_AES_256:
  51. case UV_SECRET_AES_XTS_128:
  52. case UV_SECRET_AES_XTS_256:
  53. case UV_SECRET_HMAC_SHA_256:
  54. case UV_SECRET_HMAC_SHA_512:
  55. case UV_SECRET_ECDSA_P256:
  56. case UV_SECRET_ECDSA_P384:
  57. case UV_SECRET_ECDSA_P521:
  58. case UV_SECRET_ECDSA_ED25519:
  59. case UV_SECRET_ECDSA_ED448:
  60. return true;
  61. default:
  62. return false;
  63. }
  64. default:
  65. return false;
  66. }
  67. default:
  68. return false;
  69. }
  70. }
  71. static bool is_uv_keytype(enum pkey_key_type keytype)
  72. {
  73. switch (keytype) {
  74. case PKEY_TYPE_UVSECRET:
  75. return true;
  76. default:
  77. return false;
  78. }
  79. }
  80. static int get_secret_metadata(const u8 secret_id[UV_SECRET_ID_LEN],
  81. struct uv_secret_list_item_hdr *secret)
  82. {
  83. int rc;
  84. mutex_lock(&uv_list_mutex);
  85. memset(uv_list, 0, sizeof(*uv_list));
  86. rc = uv_find_secret(secret_id, uv_list, secret);
  87. mutex_unlock(&uv_list_mutex);
  88. return rc;
  89. }
  90. static int retrieve_secret(const u8 secret_id[UV_SECRET_ID_LEN],
  91. u16 *secret_type, u8 *buf, u32 *buflen)
  92. {
  93. struct uv_secret_list_item_hdr secret_meta_data;
  94. int rc;
  95. rc = get_secret_metadata(secret_id, &secret_meta_data);
  96. if (rc)
  97. return rc;
  98. if (*buflen < secret_meta_data.length)
  99. return -EINVAL;
  100. rc = uv_retrieve_secret(secret_meta_data.index,
  101. buf, secret_meta_data.length);
  102. if (rc)
  103. return rc;
  104. *secret_type = secret_meta_data.type;
  105. *buflen = secret_meta_data.length;
  106. return 0;
  107. }
  108. static int uv_get_size_and_type(u16 secret_type, u32 *pkeysize, u32 *pkeytype)
  109. {
  110. int rc = 0;
  111. switch (secret_type) {
  112. case UV_SECRET_AES_128:
  113. *pkeysize = 16 + AES_WK_VP_SIZE;
  114. *pkeytype = PKEY_KEYTYPE_AES_128;
  115. break;
  116. case UV_SECRET_AES_192:
  117. *pkeysize = 24 + AES_WK_VP_SIZE;
  118. *pkeytype = PKEY_KEYTYPE_AES_192;
  119. break;
  120. case UV_SECRET_AES_256:
  121. *pkeysize = 32 + AES_WK_VP_SIZE;
  122. *pkeytype = PKEY_KEYTYPE_AES_256;
  123. break;
  124. case UV_SECRET_AES_XTS_128:
  125. *pkeysize = 16 + 16 + AES_WK_VP_SIZE;
  126. *pkeytype = PKEY_KEYTYPE_AES_XTS_128;
  127. break;
  128. case UV_SECRET_AES_XTS_256:
  129. *pkeysize = 32 + 32 + AES_WK_VP_SIZE;
  130. *pkeytype = PKEY_KEYTYPE_AES_XTS_256;
  131. break;
  132. case UV_SECRET_HMAC_SHA_256:
  133. *pkeysize = 64 + AES_WK_VP_SIZE;
  134. *pkeytype = PKEY_KEYTYPE_HMAC_512;
  135. break;
  136. case UV_SECRET_HMAC_SHA_512:
  137. *pkeysize = 128 + AES_WK_VP_SIZE;
  138. *pkeytype = PKEY_KEYTYPE_HMAC_1024;
  139. break;
  140. case UV_SECRET_ECDSA_P256:
  141. *pkeysize = 32 + AES_WK_VP_SIZE;
  142. *pkeytype = PKEY_KEYTYPE_ECC_P256;
  143. break;
  144. case UV_SECRET_ECDSA_P384:
  145. *pkeysize = 48 + AES_WK_VP_SIZE;
  146. *pkeytype = PKEY_KEYTYPE_ECC_P384;
  147. break;
  148. case UV_SECRET_ECDSA_P521:
  149. *pkeysize = 80 + AES_WK_VP_SIZE;
  150. *pkeytype = PKEY_KEYTYPE_ECC_P521;
  151. break;
  152. case UV_SECRET_ECDSA_ED25519:
  153. *pkeysize = 32 + AES_WK_VP_SIZE;
  154. *pkeytype = PKEY_KEYTYPE_ECC_ED25519;
  155. break;
  156. case UV_SECRET_ECDSA_ED448:
  157. *pkeysize = 64 + AES_WK_VP_SIZE;
  158. *pkeytype = PKEY_KEYTYPE_ECC_ED448;
  159. break;
  160. default:
  161. rc = -EINVAL;
  162. }
  163. return rc;
  164. }
  165. static int uv_key2protkey(const struct pkey_apqn *_apqns __always_unused,
  166. size_t _nr_apqns __always_unused,
  167. const u8 *key, u32 keylen,
  168. u8 *protkey, u32 *protkeylen, u32 *keyinfo,
  169. u32 _xflags __always_unused)
  170. {
  171. struct uvsecrettoken *t = (struct uvsecrettoken *)key;
  172. u32 pkeysize, pkeytype;
  173. u16 secret_type;
  174. int rc;
  175. rc = uv_get_size_and_type(t->secret_type, &pkeysize, &pkeytype);
  176. if (rc)
  177. goto out;
  178. if (*protkeylen < pkeysize) {
  179. PKEY_DBF_ERR("%s prot key buffer size too small: %u < %u\n",
  180. __func__, *protkeylen, pkeysize);
  181. rc = -EINVAL;
  182. goto out;
  183. }
  184. rc = retrieve_secret(t->secret_id, &secret_type, protkey, protkeylen);
  185. if (rc) {
  186. PKEY_DBF_ERR("%s retrieve_secret() failed with %d\n",
  187. __func__, rc);
  188. goto out;
  189. }
  190. if (secret_type != t->secret_type) {
  191. PKEY_DBF_ERR("%s retrieved secret type %u != expected type %u\n",
  192. __func__, secret_type, t->secret_type);
  193. rc = -EINVAL;
  194. goto out;
  195. }
  196. if (keyinfo)
  197. *keyinfo = pkeytype;
  198. out:
  199. pr_debug("rc=%d\n", rc);
  200. return rc;
  201. }
  202. static int uv_verifykey(const u8 *key, u32 keylen,
  203. u16 *_card __always_unused,
  204. u16 *_dom __always_unused,
  205. u32 *keytype, u32 *keybitsize, u32 *flags,
  206. u32 xflags __always_unused)
  207. {
  208. struct uvsecrettoken *t = (struct uvsecrettoken *)key;
  209. struct uv_secret_list_item_hdr secret_meta_data;
  210. u32 pkeysize, pkeytype, bitsize;
  211. int rc;
  212. rc = uv_get_size_and_type(t->secret_type, &pkeysize, &pkeytype);
  213. if (rc)
  214. goto out;
  215. rc = get_secret_metadata(t->secret_id, &secret_meta_data);
  216. if (rc)
  217. goto out;
  218. if (secret_meta_data.type != t->secret_type) {
  219. rc = -EINVAL;
  220. goto out;
  221. }
  222. /* set keytype; keybitsize and flags are not supported */
  223. if (keytype)
  224. *keytype = PKEY_TYPE_UVSECRET;
  225. if (keybitsize) {
  226. bitsize = 8 * pkey_keytype_to_size(pkeytype);
  227. *keybitsize = bitsize ?: PKEY_SIZE_UNKNOWN;
  228. }
  229. if (flags)
  230. *flags = pkeytype;
  231. out:
  232. pr_debug("rc=%d\n", rc);
  233. return rc;
  234. }
  235. static struct pkey_handler uv_handler = {
  236. .module = THIS_MODULE,
  237. .name = "PKEY UV handler",
  238. .is_supported_key = is_uv_key,
  239. .is_supported_keytype = is_uv_keytype,
  240. .key_to_protkey = uv_key2protkey,
  241. .verify_key = uv_verifykey,
  242. };
  243. /*
  244. * Module init
  245. */
  246. static int __init pkey_uv_init(void)
  247. {
  248. int rc;
  249. if (!is_prot_virt_guest())
  250. return -ENODEV;
  251. if (!test_bit_inv(BIT_UVC_CMD_RETR_SECRET, uv_info.inst_calls_list))
  252. return -ENODEV;
  253. uv_list = kmalloc_obj(*uv_list);
  254. if (!uv_list)
  255. return -ENOMEM;
  256. rc = pkey_handler_register(&uv_handler);
  257. if (rc)
  258. kfree(uv_list);
  259. return rc;
  260. }
  261. /*
  262. * Module exit
  263. */
  264. static void __exit pkey_uv_exit(void)
  265. {
  266. pkey_handler_unregister(&uv_handler);
  267. mutex_lock(&uv_list_mutex);
  268. kvfree(uv_list);
  269. mutex_unlock(&uv_list_mutex);
  270. }
  271. module_cpu_feature_match(S390_CPU_FEATURE_UV, pkey_uv_init);
  272. module_exit(pkey_uv_exit);