Skip to content

Commit 741521f

Browse files
ebiggersstorulf
authored andcommitted
mmc: sdhci-msm: convert to use custom crypto profile
As is being done in ufs-qcom, make the sdhci-msm driver override the full crypto profile rather than "just" key programming and eviction. This makes it much more straightforward to add support for hardware-wrapped inline encryption keys. It also makes it easy to pass the original blk_crypto_key down to qcom_ice_program_key() once it is updated to require the key in that form. Signed-off-by: Eric Biggers <ebiggers@google.com> Message-ID: <20241213041958.202565-8-ebiggers@kernel.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 08a7ead commit 741521f

File tree

3 files changed

+94
-41
lines changed

3 files changed

+94
-41
lines changed

drivers/mmc/host/cqhci-crypto.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,13 @@ cqhci_host_from_crypto_profile(struct blk_crypto_profile *profile)
2828
return mmc_from_crypto_profile(profile)->cqe_private;
2929
}
3030

31-
static int cqhci_crypto_program_key(struct cqhci_host *cq_host,
32-
const union cqhci_crypto_cfg_entry *cfg,
33-
int slot)
31+
static void cqhci_crypto_program_key(struct cqhci_host *cq_host,
32+
const union cqhci_crypto_cfg_entry *cfg,
33+
int slot)
3434
{
3535
u32 slot_offset = cq_host->crypto_cfg_register + slot * sizeof(*cfg);
3636
int i;
3737

38-
if (cq_host->ops->program_key)
39-
return cq_host->ops->program_key(cq_host, cfg, slot);
40-
4138
/* Clear CFGE */
4239
cqhci_writel(cq_host, 0, slot_offset + 16 * sizeof(cfg->reg_val[0]));
4340

@@ -52,7 +49,6 @@ static int cqhci_crypto_program_key(struct cqhci_host *cq_host,
5249
/* Write dword 16, which includes the new value of CFGE */
5350
cqhci_writel(cq_host, le32_to_cpu(cfg->reg_val[16]),
5451
slot_offset + 16 * sizeof(cfg->reg_val[0]));
55-
return 0;
5652
}
5753

5854
static int cqhci_crypto_keyslot_program(struct blk_crypto_profile *profile,
@@ -69,7 +65,6 @@ static int cqhci_crypto_keyslot_program(struct blk_crypto_profile *profile,
6965
int i;
7066
int cap_idx = -1;
7167
union cqhci_crypto_cfg_entry cfg = {};
72-
int err;
7368

7469
BUILD_BUG_ON(CQHCI_CRYPTO_KEY_SIZE_INVALID != 0);
7570
for (i = 0; i < cq_host->crypto_capabilities.num_crypto_cap; i++) {
@@ -96,10 +91,10 @@ static int cqhci_crypto_keyslot_program(struct blk_crypto_profile *profile,
9691
memcpy(cfg.crypto_key, key->raw, key->size);
9792
}
9893

99-
err = cqhci_crypto_program_key(cq_host, &cfg, slot);
94+
cqhci_crypto_program_key(cq_host, &cfg, slot);
10095

10196
memzero_explicit(&cfg, sizeof(cfg));
102-
return err;
97+
return 0;
10398
}
10499

105100
static int cqhci_crypto_clear_keyslot(struct cqhci_host *cq_host, int slot)
@@ -110,7 +105,8 @@ static int cqhci_crypto_clear_keyslot(struct cqhci_host *cq_host, int slot)
110105
*/
111106
union cqhci_crypto_cfg_entry cfg = {};
112107

113-
return cqhci_crypto_program_key(cq_host, &cfg, slot);
108+
cqhci_crypto_program_key(cq_host, &cfg, slot);
109+
return 0;
114110
}
115111

116112
static int cqhci_crypto_keyslot_evict(struct blk_crypto_profile *profile,
@@ -167,7 +163,6 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
167163
struct mmc_host *mmc = cq_host->mmc;
168164
struct device *dev = mmc_dev(mmc);
169165
struct blk_crypto_profile *profile = &mmc->crypto_profile;
170-
unsigned int num_keyslots;
171166
unsigned int cap_idx;
172167
enum blk_crypto_mode_num blk_mode_num;
173168
unsigned int slot;
@@ -177,6 +172,9 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
177172
!(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
178173
goto out;
179174

175+
if (cq_host->ops->uses_custom_crypto_profile)
176+
goto profile_initialized;
177+
180178
cq_host->crypto_capabilities.reg_val =
181179
cpu_to_le32(cqhci_readl(cq_host, CQHCI_CCAP));
182180

@@ -195,9 +193,8 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
195193
* CCAP.CFGC is off by one, so the actual number of crypto
196194
* configurations (a.k.a. keyslots) is CCAP.CFGC + 1.
197195
*/
198-
num_keyslots = cq_host->crypto_capabilities.config_count + 1;
199-
200-
err = devm_blk_crypto_profile_init(dev, profile, num_keyslots);
196+
err = devm_blk_crypto_profile_init(
197+
dev, profile, cq_host->crypto_capabilities.config_count + 1);
201198
if (err)
202199
goto out;
203200

@@ -225,9 +222,11 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
225222
cq_host->crypto_cap_array[cap_idx].sdus_mask * 512;
226223
}
227224

225+
profile_initialized:
226+
228227
/* Clear all the keyslots so that we start in a known state. */
229-
for (slot = 0; slot < num_keyslots; slot++)
230-
cqhci_crypto_clear_keyslot(cq_host, slot);
228+
for (slot = 0; slot < profile->num_slots; slot++)
229+
profile->ll_ops.keyslot_evict(profile, NULL, slot);
231230

232231
/* CQHCI crypto requires the use of 128-bit task descriptors. */
233232
cq_host->caps |= CQHCI_TASK_DESC_SZ_128;

drivers/mmc/host/cqhci.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -289,13 +289,11 @@ struct cqhci_host_ops {
289289
u64 *data);
290290
void (*pre_enable)(struct mmc_host *mmc);
291291
void (*post_disable)(struct mmc_host *mmc);
292-
#ifdef CONFIG_MMC_CRYPTO
293-
int (*program_key)(struct cqhci_host *cq_host,
294-
const union cqhci_crypto_cfg_entry *cfg, int slot);
295-
#endif
296292
void (*set_tran_desc)(struct cqhci_host *cq_host, u8 **desc,
297293
dma_addr_t addr, int len, bool end, bool dma64);
298-
294+
#ifdef CONFIG_MMC_CRYPTO
295+
bool uses_custom_crypto_profile;
296+
#endif
299297
};
300298

301299
static inline void cqhci_writel(struct cqhci_host *host, u32 val, int reg)

drivers/mmc/host/sdhci-msm.c

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,12 +1807,19 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
18071807

18081808
#ifdef CONFIG_MMC_CRYPTO
18091809

1810+
static const struct blk_crypto_ll_ops sdhci_msm_crypto_ops; /* forward decl */
1811+
18101812
static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
18111813
struct cqhci_host *cq_host)
18121814
{
18131815
struct mmc_host *mmc = msm_host->mmc;
1816+
struct blk_crypto_profile *profile = &mmc->crypto_profile;
18141817
struct device *dev = mmc_dev(mmc);
18151818
struct qcom_ice *ice;
1819+
union cqhci_crypto_capabilities caps;
1820+
union cqhci_crypto_cap_entry cap;
1821+
int err;
1822+
int i;
18161823

18171824
if (!(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
18181825
return 0;
@@ -1827,8 +1834,37 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
18271834
return PTR_ERR_OR_ZERO(ice);
18281835

18291836
msm_host->ice = ice;
1830-
mmc->caps2 |= MMC_CAP2_CRYPTO;
18311837

1838+
/* Initialize the blk_crypto_profile */
1839+
1840+
caps.reg_val = cpu_to_le32(cqhci_readl(cq_host, CQHCI_CCAP));
1841+
1842+
/* The number of keyslots supported is (CFGC+1) */
1843+
err = devm_blk_crypto_profile_init(dev, profile, caps.config_count + 1);
1844+
if (err)
1845+
return err;
1846+
1847+
profile->ll_ops = sdhci_msm_crypto_ops;
1848+
profile->max_dun_bytes_supported = 4;
1849+
profile->dev = dev;
1850+
1851+
/*
1852+
* Currently this driver only supports AES-256-XTS. All known versions
1853+
* of ICE support it, but to be safe make sure it is really declared in
1854+
* the crypto capability registers. The crypto capability registers
1855+
* also give the supported data unit size(s).
1856+
*/
1857+
for (i = 0; i < caps.num_crypto_cap; i++) {
1858+
cap.reg_val = cpu_to_le32(cqhci_readl(cq_host,
1859+
CQHCI_CRYPTOCAP +
1860+
i * sizeof(__le32)));
1861+
if (cap.algorithm_id == CQHCI_CRYPTO_ALG_AES_XTS &&
1862+
cap.key_size == CQHCI_CRYPTO_KEY_SIZE_256)
1863+
profile->modes_supported[BLK_ENCRYPTION_MODE_AES_256_XTS] |=
1864+
cap.sdus_mask * 512;
1865+
}
1866+
1867+
mmc->caps2 |= MMC_CAP2_CRYPTO;
18321868
return 0;
18331869
}
18341870

@@ -1854,35 +1890,55 @@ static __maybe_unused int sdhci_msm_ice_suspend(struct sdhci_msm_host *msm_host)
18541890
return 0;
18551891
}
18561892

1857-
/*
1858-
* Program a key into a QC ICE keyslot, or evict a keyslot. QC ICE requires
1859-
* vendor-specific SCM calls for this; it doesn't support the standard way.
1860-
*/
1861-
static int sdhci_msm_program_key(struct cqhci_host *cq_host,
1862-
const union cqhci_crypto_cfg_entry *cfg,
1863-
int slot)
1893+
static inline struct sdhci_msm_host *
1894+
sdhci_msm_host_from_crypto_profile(struct blk_crypto_profile *profile)
18641895
{
1865-
struct sdhci_host *host = mmc_priv(cq_host->mmc);
1896+
struct mmc_host *mmc = mmc_from_crypto_profile(profile);
1897+
struct sdhci_host *host = mmc_priv(mmc);
18661898
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
18671899
struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
1868-
union cqhci_crypto_cap_entry cap;
18691900

1870-
if (!(cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE))
1871-
return qcom_ice_evict_key(msm_host->ice, slot);
1901+
return msm_host;
1902+
}
1903+
1904+
/*
1905+
* Program a key into a QC ICE keyslot. QC ICE requires a QC-specific SCM call
1906+
* for this; it doesn't support the standard way.
1907+
*/
1908+
static int sdhci_msm_ice_keyslot_program(struct blk_crypto_profile *profile,
1909+
const struct blk_crypto_key *key,
1910+
unsigned int slot)
1911+
{
1912+
struct sdhci_msm_host *msm_host =
1913+
sdhci_msm_host_from_crypto_profile(profile);
18721914

18731915
/* Only AES-256-XTS has been tested so far. */
1874-
cap = cq_host->crypto_cap_array[cfg->crypto_cap_idx];
1875-
if (cap.algorithm_id != CQHCI_CRYPTO_ALG_AES_XTS ||
1876-
cap.key_size != CQHCI_CRYPTO_KEY_SIZE_256)
1877-
return -EINVAL;
1916+
if (key->crypto_cfg.crypto_mode != BLK_ENCRYPTION_MODE_AES_256_XTS)
1917+
return -EOPNOTSUPP;
18781918

18791919
return qcom_ice_program_key(msm_host->ice,
18801920
QCOM_ICE_CRYPTO_ALG_AES_XTS,
18811921
QCOM_ICE_CRYPTO_KEY_SIZE_256,
1882-
cfg->crypto_key,
1883-
cfg->data_unit_size, slot);
1922+
key->raw,
1923+
key->crypto_cfg.data_unit_size / 512,
1924+
slot);
18841925
}
18851926

1927+
static int sdhci_msm_ice_keyslot_evict(struct blk_crypto_profile *profile,
1928+
const struct blk_crypto_key *key,
1929+
unsigned int slot)
1930+
{
1931+
struct sdhci_msm_host *msm_host =
1932+
sdhci_msm_host_from_crypto_profile(profile);
1933+
1934+
return qcom_ice_evict_key(msm_host->ice, slot);
1935+
}
1936+
1937+
static const struct blk_crypto_ll_ops sdhci_msm_crypto_ops = {
1938+
.keyslot_program = sdhci_msm_ice_keyslot_program,
1939+
.keyslot_evict = sdhci_msm_ice_keyslot_evict,
1940+
};
1941+
18861942
#else /* CONFIG_MMC_CRYPTO */
18871943

18881944
static inline int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
@@ -1988,7 +2044,7 @@ static const struct cqhci_host_ops sdhci_msm_cqhci_ops = {
19882044
.enable = sdhci_msm_cqe_enable,
19892045
.disable = sdhci_msm_cqe_disable,
19902046
#ifdef CONFIG_MMC_CRYPTO
1991-
.program_key = sdhci_msm_program_key,
2047+
.uses_custom_crypto_profile = true,
19922048
#endif
19932049
};
19942050

0 commit comments

Comments
 (0)