zynqmp-crypto.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Firmware layer for XilSecure APIs.
  4. *
  5. * Copyright (C) 2014-2022 Xilinx, Inc.
  6. * Copyright (C) 2022-2025 Advanced Micro Devices, Inc.
  7. */
  8. #include <linux/firmware/xlnx-zynqmp.h>
  9. #include <linux/module.h>
  10. /**
  11. * zynqmp_pm_aes_engine - Access AES hardware to encrypt/decrypt the data using
  12. * AES-GCM core.
  13. * @address: Address of the AesParams structure.
  14. * @out: Returned output value
  15. *
  16. * Return: Returns status, either success or error code.
  17. */
  18. int zynqmp_pm_aes_engine(const u64 address, u32 *out)
  19. {
  20. u32 ret_payload[PAYLOAD_ARG_CNT];
  21. int ret;
  22. if (!out)
  23. return -EINVAL;
  24. ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, ret_payload, 2, upper_32_bits(address),
  25. lower_32_bits(address));
  26. *out = ret_payload[1];
  27. return ret;
  28. }
  29. EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);
  30. /**
  31. * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
  32. * @address: Address of the data/ Address of output buffer where
  33. * hash should be stored.
  34. * @size: Size of the data.
  35. * @flags:
  36. * BIT(0) - for initializing csudma driver and SHA3(Here address
  37. * and size inputs can be NULL).
  38. * BIT(1) - to call Sha3_Update API which can be called multiple
  39. * times when data is not contiguous.
  40. * BIT(2) - to get final hash of the whole updated data.
  41. * Hash will be overwritten at provided address with
  42. * 48 bytes.
  43. *
  44. * Return: Returns status, either success or error code.
  45. */
  46. int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags)
  47. {
  48. u32 lower_addr = lower_32_bits(address);
  49. u32 upper_addr = upper_32_bits(address);
  50. return zynqmp_pm_invoke_fn(PM_SECURE_SHA, NULL, 4, upper_addr, lower_addr, size, flags);
  51. }
  52. EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash);
  53. /**
  54. * xlnx_get_crypto_dev_data() - Get crypto dev data of platform
  55. * @feature_map: List of available feature map of all platform
  56. *
  57. * Return: Returns crypto dev data, either address crypto dev or ERR PTR
  58. */
  59. void *xlnx_get_crypto_dev_data(struct xlnx_feature *feature_map)
  60. {
  61. struct xlnx_feature *feature;
  62. u32 pm_family_code;
  63. int ret;
  64. /* Get the Family code and sub family code of platform */
  65. ret = zynqmp_pm_get_family_info(&pm_family_code);
  66. if (ret < 0)
  67. return ERR_PTR(ret);
  68. feature = feature_map;
  69. for (; feature->family; feature++) {
  70. if (feature->family == pm_family_code) {
  71. ret = zynqmp_pm_feature(feature->feature_id);
  72. if (ret < 0)
  73. return ERR_PTR(ret);
  74. return feature->data;
  75. }
  76. }
  77. return ERR_PTR(-ENODEV);
  78. }
  79. EXPORT_SYMBOL_GPL(xlnx_get_crypto_dev_data);
  80. /**
  81. * versal_pm_aes_key_write - Write AES key registers
  82. * @keylen: Size of the input key to be written
  83. * @keysrc: Key Source to be selected to which provided
  84. * key should be updated
  85. * @keyaddr: Address of a buffer which should contain the key
  86. * to be written
  87. *
  88. * This function provides support to write AES volatile user keys.
  89. *
  90. * Return: Returns status, either success or error+reason
  91. */
  92. int versal_pm_aes_key_write(const u32 keylen,
  93. const u32 keysrc, const u64 keyaddr)
  94. {
  95. return zynqmp_pm_invoke_fn(XSECURE_API_AES_WRITE_KEY, NULL, 4,
  96. keylen, keysrc,
  97. lower_32_bits(keyaddr),
  98. upper_32_bits(keyaddr));
  99. }
  100. EXPORT_SYMBOL_GPL(versal_pm_aes_key_write);
  101. /**
  102. * versal_pm_aes_key_zero - Zeroise AES User key registers
  103. * @keysrc: Key Source to be selected to which provided
  104. * key should be updated
  105. *
  106. * This function provides support to zeroise AES volatile user keys.
  107. *
  108. * Return: Returns status, either success or error+reason
  109. */
  110. int versal_pm_aes_key_zero(const u32 keysrc)
  111. {
  112. return zynqmp_pm_invoke_fn(XSECURE_API_AES_KEY_ZERO, NULL, 1, keysrc);
  113. }
  114. EXPORT_SYMBOL_GPL(versal_pm_aes_key_zero);
  115. /**
  116. * versal_pm_aes_op_init - Init AES operation
  117. * @hw_req: AES op init structure address
  118. *
  119. * This function provides support to init AES operation.
  120. *
  121. * Return: Returns status, either success or error+reason
  122. */
  123. int versal_pm_aes_op_init(const u64 hw_req)
  124. {
  125. return zynqmp_pm_invoke_fn(XSECURE_API_AES_OP_INIT, NULL, 2,
  126. lower_32_bits(hw_req),
  127. upper_32_bits(hw_req));
  128. }
  129. EXPORT_SYMBOL_GPL(versal_pm_aes_op_init);
  130. /**
  131. * versal_pm_aes_update_aad - AES update aad
  132. * @aad_addr: AES aad address
  133. * @aad_len: AES aad data length
  134. *
  135. * This function provides support to update AAD data.
  136. *
  137. * Return: Returns status, either success or error+reason
  138. */
  139. int versal_pm_aes_update_aad(const u64 aad_addr, const u32 aad_len)
  140. {
  141. return zynqmp_pm_invoke_fn(XSECURE_API_AES_UPDATE_AAD, NULL, 3,
  142. lower_32_bits(aad_addr),
  143. upper_32_bits(aad_addr),
  144. aad_len);
  145. }
  146. EXPORT_SYMBOL_GPL(versal_pm_aes_update_aad);
  147. /**
  148. * versal_pm_aes_enc_update - Access AES hardware to encrypt the data using
  149. * AES-GCM core.
  150. * @in_params: Address of the AesParams structure
  151. * @in_addr: Address of input buffer
  152. *
  153. * Return: Returns status, either success or error code.
  154. */
  155. int versal_pm_aes_enc_update(const u64 in_params, const u64 in_addr)
  156. {
  157. return zynqmp_pm_invoke_fn(XSECURE_API_AES_ENCRYPT_UPDATE, NULL, 4,
  158. lower_32_bits(in_params),
  159. upper_32_bits(in_params),
  160. lower_32_bits(in_addr),
  161. upper_32_bits(in_addr));
  162. }
  163. EXPORT_SYMBOL_GPL(versal_pm_aes_enc_update);
  164. /**
  165. * versal_pm_aes_enc_final - Access AES hardware to store the GCM tag
  166. * @gcm_addr: Address of the gcm tag
  167. *
  168. * Return: Returns status, either success or error code.
  169. */
  170. int versal_pm_aes_enc_final(const u64 gcm_addr)
  171. {
  172. return zynqmp_pm_invoke_fn(XSECURE_API_AES_ENCRYPT_FINAL, NULL, 2,
  173. lower_32_bits(gcm_addr),
  174. upper_32_bits(gcm_addr));
  175. }
  176. EXPORT_SYMBOL_GPL(versal_pm_aes_enc_final);
  177. /**
  178. * versal_pm_aes_dec_update - Access AES hardware to decrypt the data using
  179. * AES-GCM core.
  180. * @in_params: Address of the AesParams structure
  181. * @in_addr: Address of input buffer
  182. *
  183. * Return: Returns status, either success or error code.
  184. */
  185. int versal_pm_aes_dec_update(const u64 in_params, const u64 in_addr)
  186. {
  187. return zynqmp_pm_invoke_fn(XSECURE_API_AES_DECRYPT_UPDATE, NULL, 4,
  188. lower_32_bits(in_params),
  189. upper_32_bits(in_params),
  190. lower_32_bits(in_addr),
  191. upper_32_bits(in_addr));
  192. }
  193. EXPORT_SYMBOL_GPL(versal_pm_aes_dec_update);
  194. /**
  195. * versal_pm_aes_dec_final - Access AES hardware to get the GCM tag
  196. * @gcm_addr: Address of the gcm tag
  197. *
  198. * Return: Returns status, either success or error code.
  199. */
  200. int versal_pm_aes_dec_final(const u64 gcm_addr)
  201. {
  202. return zynqmp_pm_invoke_fn(XSECURE_API_AES_DECRYPT_FINAL, NULL, 2,
  203. lower_32_bits(gcm_addr),
  204. upper_32_bits(gcm_addr));
  205. }
  206. EXPORT_SYMBOL_GPL(versal_pm_aes_dec_final);
  207. /**
  208. * versal_pm_aes_init - Init AES block
  209. *
  210. * This function initialise AES block.
  211. *
  212. * Return: Returns status, either success or error+reason
  213. */
  214. int versal_pm_aes_init(void)
  215. {
  216. return zynqmp_pm_invoke_fn(XSECURE_API_AES_INIT, NULL, 0);
  217. }
  218. EXPORT_SYMBOL_GPL(versal_pm_aes_init);