cqhci-crypto-qti.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <crypto/algapi.h>
  7. #include "sdhci.h"
  8. #include "sdhci-pltfm.h"
  9. #include "cqhci-crypto-qti.h"
  10. #include <linux/blk-crypto-profile.h>
  11. #include <linux/crypto-qti-common.h>
  12. #define RAW_SECRET_SIZE 32
  13. #define MINIMUM_DUN_SIZE 512
  14. #define MAXIMUM_DUN_SIZE 65536
  15. static const struct cqhci_crypto_alg_entry {
  16. enum cqhci_crypto_alg alg;
  17. enum cqhci_crypto_key_size key_size;
  18. } cqhci_crypto_algs[BLK_ENCRYPTION_MODE_MAX] = {
  19. [BLK_ENCRYPTION_MODE_AES_256_XTS] = {
  20. .alg = CQHCI_CRYPTO_ALG_AES_XTS,
  21. .key_size = CQHCI_CRYPTO_KEY_SIZE_256,
  22. },
  23. };
  24. static inline struct cqhci_host *
  25. cqhci_host_from_crypto(struct blk_crypto_profile *profile)
  26. {
  27. struct mmc_host *mmc = container_of(profile, struct mmc_host, crypto_profile);
  28. return mmc->cqe_private;
  29. }
  30. static void get_mmio_data(struct ice_mmio_data *data, struct cqhci_host *host)
  31. {
  32. data->ice_base_mmio = host->ice_mmio;
  33. #if (IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER) || IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER_V1))
  34. data->ice_hwkm_mmio = host->ice_hwkm_mmio;
  35. #endif
  36. }
  37. static int cqhci_crypto_qti_keyslot_program(struct blk_crypto_profile *profile,
  38. const struct blk_crypto_key *key,
  39. unsigned int slot)
  40. {
  41. struct cqhci_host *cq_host = cqhci_host_from_crypto(profile);
  42. int err = 0;
  43. u8 data_unit_mask = -1;
  44. struct ice_mmio_data mmio_data;
  45. const struct cqhci_crypto_alg_entry *alg;
  46. int i;
  47. int cap_idx = -1;
  48. const union cqhci_crypto_cap_entry *ccap_array =
  49. cq_host->crypto_cap_array;
  50. if (!key) {
  51. pr_err("Invalid/no key present\n");
  52. return -EINVAL;
  53. }
  54. alg = &cqhci_crypto_algs[key->crypto_cfg.crypto_mode];
  55. data_unit_mask = key->crypto_cfg.data_unit_size / MINIMUM_DUN_SIZE;
  56. BUILD_BUG_ON(CQHCI_CRYPTO_KEY_SIZE_INVALID != 0);
  57. for (i = 0; i < cq_host->crypto_capabilities.num_crypto_cap; i++) {
  58. if (ccap_array[i].algorithm_id == alg->alg &&
  59. ccap_array[i].key_size == alg->key_size &&
  60. (ccap_array[i].sdus_mask & data_unit_mask)) {
  61. cap_idx = i;
  62. break;
  63. }
  64. }
  65. if (WARN_ON(cap_idx < 0))
  66. return -EOPNOTSUPP;
  67. get_mmio_data(&mmio_data, cq_host);
  68. err = crypto_qti_keyslot_program(&mmio_data, key,
  69. slot, data_unit_mask, cap_idx, SDCC_CE);
  70. if (err)
  71. pr_err("%s: failed with error %d\n", __func__, err);
  72. return err;
  73. }
  74. static int cqhci_crypto_qti_keyslot_evict(struct blk_crypto_profile *profile,
  75. const struct blk_crypto_key *key,
  76. unsigned int slot)
  77. {
  78. int err = 0;
  79. struct cqhci_host *host = cqhci_host_from_crypto(profile);
  80. struct ice_mmio_data mmio_data;
  81. get_mmio_data(&mmio_data, host);
  82. err = crypto_qti_keyslot_evict(&mmio_data, slot, SDCC_CE);
  83. if (err)
  84. pr_err("%s: failed with error %d\n", __func__, err);
  85. return err;
  86. }
  87. static int cqhci_crypto_qti_derive_raw_secret(struct blk_crypto_profile *profile,
  88. const u8 *wrapped_key, size_t wrapped_key_size,
  89. u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE])
  90. {
  91. int err = 0;
  92. struct cqhci_host *host = cqhci_host_from_crypto(profile);
  93. struct ice_mmio_data mmio_data;
  94. get_mmio_data(&mmio_data, host);
  95. err = crypto_qti_derive_raw_secret(&mmio_data, wrapped_key, wrapped_key_size,
  96. sw_secret, BLK_CRYPTO_SW_SECRET_SIZE);
  97. if (err)
  98. pr_err("%s: failed with error %d\n", __func__, err);
  99. return err;
  100. }
  101. static const struct blk_crypto_ll_ops cqhci_crypto_qti_ops = {
  102. .keyslot_program = cqhci_crypto_qti_keyslot_program,
  103. .keyslot_evict = cqhci_crypto_qti_keyslot_evict,
  104. .derive_sw_secret = cqhci_crypto_qti_derive_raw_secret
  105. };
  106. static enum blk_crypto_mode_num
  107. cqhci_find_blk_crypto_mode(union cqhci_crypto_cap_entry cap)
  108. {
  109. int i;
  110. for (i = 0; i < ARRAY_SIZE(cqhci_crypto_algs); i++) {
  111. BUILD_BUG_ON(CQHCI_CRYPTO_KEY_SIZE_INVALID != 0);
  112. if (cqhci_crypto_algs[i].alg == cap.algorithm_id &&
  113. cqhci_crypto_algs[i].key_size == cap.key_size)
  114. return i;
  115. }
  116. return BLK_ENCRYPTION_MODE_INVALID;
  117. }
  118. /**
  119. * cqhci_crypto_init - initialize CQHCI crypto support
  120. * @cq_host: a cqhci host
  121. *
  122. * If the driver previously set MMC_CAP2_CRYPTO and the CQE declares
  123. * CQHCI_CAP_CS, initialize the crypto support. This involves reading the
  124. * crypto capability registers, initializing the keyslot manager, clearing all
  125. * keyslots, and enabling 128-bit task descriptors.
  126. *
  127. * Return: 0 if crypto was initialized or isn't supported; whether
  128. * MMC_CAP2_CRYPTO remains set indicates which one of those cases it is.
  129. * Also can return a negative errno value on unexpected error.
  130. */
  131. int cqhci_qti_crypto_init(struct cqhci_host *cq_host)
  132. {
  133. struct mmc_host *mmc = cq_host->mmc;
  134. struct device *dev = mmc_dev(mmc);
  135. struct blk_crypto_profile *profile = &mmc->crypto_profile;
  136. unsigned int num_keyslots;
  137. unsigned int cap_idx;
  138. enum blk_crypto_mode_num blk_mode_num;
  139. unsigned int slot;
  140. int err = 0;
  141. if (!(mmc->caps2 & MMC_CAP2_CRYPTO) ||
  142. !(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
  143. goto out;
  144. cq_host->crypto_capabilities.reg_val =
  145. cpu_to_le32(cqhci_readl(cq_host, CQHCI_CCAP));
  146. cq_host->crypto_cfg_register =
  147. (u32)cq_host->crypto_capabilities.config_array_ptr * 0x100;
  148. cq_host->crypto_cap_array =
  149. devm_kcalloc(dev, cq_host->crypto_capabilities.num_crypto_cap,
  150. sizeof(cq_host->crypto_cap_array[0]), GFP_KERNEL);
  151. if (!cq_host->crypto_cap_array) {
  152. err = -ENOMEM;
  153. goto out;
  154. }
  155. /*
  156. * CCAP.CFGC is off by one, so the actual number of crypto
  157. * configurations (a.k.a. keyslots) is CCAP.CFGC + 1.
  158. */
  159. num_keyslots = cq_host->crypto_capabilities.config_count + 1;
  160. err = devm_blk_crypto_profile_init(dev, profile, num_keyslots);
  161. if (err)
  162. goto out;
  163. profile->ll_ops = cqhci_crypto_qti_ops;
  164. profile->dev = dev;
  165. /* Unfortunately, CQHCI crypto only supports 32 DUN bits. */
  166. profile->max_dun_bytes_supported = 4;
  167. profile->key_types_supported = BLK_CRYPTO_KEY_TYPE_HW_WRAPPED;
  168. /*
  169. * Cache all the crypto capabilities and advertise the supported crypto
  170. * modes and data unit sizes to the block layer.
  171. */
  172. for (cap_idx = 0; cap_idx < cq_host->crypto_capabilities.num_crypto_cap;
  173. cap_idx++) {
  174. cq_host->crypto_cap_array[cap_idx].reg_val =
  175. cpu_to_le32(cqhci_readl(cq_host,
  176. CQHCI_CRYPTOCAP +
  177. cap_idx * sizeof(__le32)));
  178. blk_mode_num = cqhci_find_blk_crypto_mode(
  179. cq_host->crypto_cap_array[cap_idx]);
  180. if (blk_mode_num == BLK_ENCRYPTION_MODE_INVALID)
  181. continue;
  182. profile->modes_supported[blk_mode_num] |=
  183. cq_host->crypto_cap_array[cap_idx].sdus_mask * 512;
  184. }
  185. /* Clear all the keyslots so that we start in a known state. */
  186. for (slot = 0; slot < num_keyslots; slot++)
  187. profile->ll_ops.keyslot_evict(profile, NULL, slot);
  188. /* CQHCI crypto requires the use of 128-bit task descriptors. */
  189. cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
  190. return 0;
  191. out:
  192. mmc->caps2 &= ~MMC_CAP2_CRYPTO;
  193. return err;
  194. }
  195. MODULE_DESCRIPTION("Vendor specific CQHCI Crypto Engine Support");
  196. MODULE_LICENSE("GPL");