crypto-qti-virt.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Crypto virtual library for storage encryption.
  4. *
  5. * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  6. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/version.h>
  11. #include <linux/string.h>
  12. #include <linux/habmm.h>
  13. #include <linux/crypto_qti_virt.h>
  14. #include <linux/ktime.h>
  15. #include <linux/kthread.h>
  16. #include <linux/completion.h>
  17. #define RESERVE_SIZE (36*sizeof(uint16_t))
  18. #define SECRET_SIZE (32)
  19. #define HAB_TIMEOUT_MS (50000)
  20. /* FBE request command ids */
  21. #define FBE_GET_MAX_SLOTS (7)
  22. #define FBE_SET_KEY_V2 (8)
  23. #define FBE_CLEAR_KEY_V2 (9)
  24. #define FBE_DERIVE_RAW_SECRET (10)
  25. #define FBE_GET_CRYPTO_CAPABILITIES (11)
  26. #define FBE_VERIFY_CRYPTO_CAPS (12)
  27. #define MAX_CRYPTO_MODES_SUPPORTED (4)
  28. struct fbe_derive_secret {
  29. uint8_t wrapped_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE];
  30. uint32_t wrapped_key_size;
  31. };
  32. struct fbe_request_v2_t {
  33. uint8_t reserve[RESERVE_SIZE]; /*for compatibility*/
  34. uint32_t cmd;
  35. uint8_t key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE];
  36. uint32_t key_size;
  37. uint32_t virt_slot;
  38. uint32_t data_unit_size;
  39. enum blk_crypto_mode_num crypto_mode;
  40. struct fbe_derive_secret derive_raw_secret;
  41. };
  42. struct fbe_v2_resp {
  43. int32_t status;
  44. uint8_t secret_key[SECRET_SIZE];
  45. uint32_t crypto_modes_supported[MAX_CRYPTO_MODES_SUPPORTED];
  46. };
  47. struct fbe_req_args {
  48. struct fbe_request_v2_t req;
  49. struct fbe_v2_resp response;
  50. int32_t ret;
  51. };
  52. static struct completion send_fbe_req_done;
  53. static int32_t send_fbe_req_hab(void *arg)
  54. {
  55. int ret = 0;
  56. uint32_t status_size;
  57. uint32_t handle;
  58. struct fbe_req_args *req_args = (struct fbe_req_args *)arg;
  59. do {
  60. if (!req_args) {
  61. pr_err("%s Null input\n", __func__);
  62. ret = -EINVAL;
  63. break;
  64. }
  65. ret = habmm_socket_open(&handle, MM_FDE_1, 0, 0);
  66. if (ret) {
  67. pr_err("habmm_socket_open failed with ret = %d\n", ret);
  68. break;
  69. }
  70. ret = habmm_socket_send(handle, &req_args->req, sizeof(struct fbe_request_v2_t), 0);
  71. if (ret) {
  72. pr_err("habmm_socket_send failed, ret= 0x%x\n", ret);
  73. break;
  74. }
  75. do {
  76. status_size = sizeof(struct fbe_v2_resp);
  77. ret = habmm_socket_recv(handle, &req_args->response, &status_size, 0,
  78. HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE);
  79. } while (-EINTR == ret);
  80. if (ret) {
  81. pr_err("habmm_socket_recv failed, ret= 0x%x\n", ret);
  82. break;
  83. }
  84. if (status_size != sizeof(struct fbe_v2_resp)) {
  85. pr_err("habmm_socket_recv expected size: %lu, actual=%u\n",
  86. sizeof(struct fbe_v2_resp),
  87. status_size);
  88. ret = -E2BIG;
  89. break;
  90. }
  91. ret = habmm_socket_close(handle);
  92. if (ret) {
  93. pr_err("habmm_socket_close failed with ret = %d\n", ret);
  94. break;
  95. }
  96. } while (0);
  97. req_args->ret = ret;
  98. complete(&send_fbe_req_done);
  99. return 0;
  100. }
  101. static void send_fbe_req(struct fbe_req_args *arg)
  102. {
  103. struct task_struct *thread;
  104. init_completion(&send_fbe_req_done);
  105. arg->response.status = 0;
  106. thread = kthread_run(send_fbe_req_hab, arg, "send_fbe_req");
  107. if (IS_ERR(thread)) {
  108. arg->ret = -1;
  109. return;
  110. }
  111. if (wait_for_completion_interruptible_timeout(
  112. &send_fbe_req_done, msecs_to_jiffies(HAB_TIMEOUT_MS)) <= 0) {
  113. pr_err("%s: timeout hit\n", __func__);
  114. kthread_stop(thread);
  115. arg->ret = -ETIME;
  116. return;
  117. }
  118. }
  119. int crypto_qti_virt_ice_get_info(uint32_t *total_num_slots)
  120. {
  121. struct fbe_req_args arg;
  122. if (!total_num_slots) {
  123. pr_err("%s Null input\n", __func__);
  124. return -EINVAL;
  125. }
  126. arg.req.cmd = FBE_GET_MAX_SLOTS;
  127. send_fbe_req(&arg);
  128. if (arg.ret || arg.response.status < 0) {
  129. pr_err("send_fbe_req_v2 failed with ret = %d, max_slots = %d\n",
  130. arg.ret, arg.response.status);
  131. return -ECOMM;
  132. }
  133. *total_num_slots = (uint32_t) arg.response.status;
  134. return 0;
  135. }
  136. EXPORT_SYMBOL_GPL(crypto_qti_virt_ice_get_info);
  137. static int verify_crypto_capabilities(enum blk_crypto_mode_num crypto_mode,
  138. unsigned int data_unit_size)
  139. {
  140. struct fbe_req_args arg;
  141. arg.req.cmd = FBE_VERIFY_CRYPTO_CAPS;
  142. arg.req.crypto_mode = crypto_mode;
  143. arg.req.data_unit_size = data_unit_size;
  144. send_fbe_req(&arg);
  145. if (arg.ret || arg.response.status < 0) {
  146. pr_err("send_fbe_req_v2 failed with ret = %d, status = %d\n",
  147. arg.ret, arg.response.status);
  148. return -EINVAL;
  149. }
  150. return arg.response.status;
  151. }
  152. int crypto_qti_virt_program_key(const struct blk_crypto_key *key,
  153. unsigned int slot)
  154. {
  155. struct fbe_req_args arg;
  156. int ret = 0;
  157. if (!key)
  158. return -EINVAL;
  159. /* Actual determination of capabilities for UFS/EMMC for different
  160. * encryption modes are done in the back end (host operating system)
  161. * in case of virtualization driver, so will send details to backend
  162. * and BE will verify the given capabilities.
  163. */
  164. ret = verify_crypto_capabilities(key->crypto_cfg.crypto_mode,
  165. key->crypto_cfg.data_unit_size);
  166. if (ret)
  167. return -EINVAL;
  168. /* program key */
  169. arg.req.cmd = FBE_SET_KEY_V2;
  170. arg.req.virt_slot = slot;
  171. arg.req.key_size = key->size;
  172. memcpy(&(arg.req.key[0]), key->raw, key->size);
  173. send_fbe_req(&arg);
  174. if (arg.ret || arg.response.status) {
  175. pr_err("send_fbe_req_v2 failed with ret = %d, status = %d\n",
  176. arg.ret, arg.response.status);
  177. return -ECOMM;
  178. }
  179. return 0;
  180. }
  181. EXPORT_SYMBOL_GPL(crypto_qti_virt_program_key);
  182. int crypto_qti_virt_invalidate_key(unsigned int slot)
  183. {
  184. struct fbe_req_args arg;
  185. arg.req.cmd = FBE_CLEAR_KEY_V2;
  186. arg.req.virt_slot = slot;
  187. send_fbe_req(&arg);
  188. if (arg.ret || arg.response.status) {
  189. pr_err("send_fbe_req_v2 failed with ret = %d, status = %d\n",
  190. arg.ret, arg.response.status);
  191. return -ECOMM;
  192. }
  193. return 0;
  194. }
  195. EXPORT_SYMBOL_GPL(crypto_qti_virt_invalidate_key);
  196. int crypto_qti_virt_get_crypto_capabilities(unsigned int *crypto_modes_supported,
  197. uint32_t crypto_array_size)
  198. {
  199. struct fbe_req_args arg;
  200. // To compatible with BE(Back End)
  201. crypto_array_size -= sizeof(uint32_t);
  202. arg.req.cmd = FBE_GET_CRYPTO_CAPABILITIES;
  203. send_fbe_req(&arg);
  204. if (arg.ret || arg.response.status) {
  205. pr_err("send_fbe_req_v2 failed with ret = %d, status = %d\n",
  206. arg.ret, arg.response.status);
  207. return -ECOMM;
  208. }
  209. memcpy(crypto_modes_supported, &(arg.response.crypto_modes_supported[0]),
  210. crypto_array_size);
  211. return 0;
  212. }
  213. EXPORT_SYMBOL_GPL(crypto_qti_virt_get_crypto_capabilities);
  214. int crypto_qti_virt_derive_raw_secret_platform(const u8 *wrapped_key,
  215. unsigned int wrapped_key_size,
  216. u8 *secret,
  217. unsigned int secret_size)
  218. {
  219. struct fbe_req_args arg;
  220. arg.req.cmd = FBE_DERIVE_RAW_SECRET;
  221. memcpy(&(arg.req.derive_raw_secret.wrapped_key[0]), wrapped_key,
  222. wrapped_key_size);
  223. arg.req.derive_raw_secret.wrapped_key_size = wrapped_key_size;
  224. send_fbe_req(&arg);
  225. if (arg.ret || arg.response.status) {
  226. pr_err("send_fbe_req_v2 failed with ret = %d, status = %d\n",
  227. arg.ret, arg.response.status);
  228. return -EINVAL;
  229. }
  230. memcpy(secret, &(arg.response.secret_key[0]), secret_size);
  231. return 0;
  232. }
  233. EXPORT_SYMBOL_GPL(crypto_qti_virt_derive_raw_secret_platform);
  234. MODULE_LICENSE("GPL");
  235. MODULE_DESCRIPTION("Crypto Virtual library for storage encryption");