Skip to content

Commit af8e69e

Browse files
Merge patch series "Basic inline encryption support for ufs-exynos"
Eric Biggers <ebiggers@kernel.org> says: Add support for Flash Memory Protector (FMP), which is the inline encryption hardware on Exynos and Exynos-based SoCs. Specifically, add support for the "traditional FMP mode" that works on many Exynos-based SoCs including gs101. This is the mode that uses "software keys" and is compatible with the upstream kernel's existing inline encryption framework in the block and filesystem layers. I plan to add support for the wrapped key support on gs101 at a later time. Tested on gs101 (specifically Pixel 6) by running the 'encrypt' group of xfstests on a filesystem mounted with the 'inlinecrypt' mount option. This patchset applies to v6.10-rc6, and it has no prerequisites that aren't already upstream. Link: https://lore.kernel.org/r/20240708235330.103590-1-ebiggers@kernel.org Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2 parents e30618a + c96499f commit af8e69e

File tree

5 files changed

+320
-21
lines changed

5 files changed

+320
-21
lines changed

drivers/ufs/core/ufshcd-crypto.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,12 @@ static int ufshcd_crypto_keyslot_program(struct blk_crypto_profile *profile,
9595
return err;
9696
}
9797

98-
static int ufshcd_clear_keyslot(struct ufs_hba *hba, int slot)
98+
static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile,
99+
const struct blk_crypto_key *key,
100+
unsigned int slot)
99101
{
102+
struct ufs_hba *hba =
103+
container_of(profile, struct ufs_hba, crypto_profile);
100104
/*
101105
* Clear the crypto cfg on the device. Clearing CFGE
102106
* might not be sufficient, so just clear the entire cfg.
@@ -106,23 +110,21 @@ static int ufshcd_clear_keyslot(struct ufs_hba *hba, int slot)
106110
return ufshcd_program_key(hba, &cfg, slot);
107111
}
108112

109-
static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile,
110-
const struct blk_crypto_key *key,
111-
unsigned int slot)
112-
{
113-
struct ufs_hba *hba =
114-
container_of(profile, struct ufs_hba, crypto_profile);
115-
116-
return ufshcd_clear_keyslot(hba, slot);
117-
}
118-
113+
/*
114+
* Reprogram the keyslots if needed, and return true if CRYPTO_GENERAL_ENABLE
115+
* should be used in the host controller initialization sequence.
116+
*/
119117
bool ufshcd_crypto_enable(struct ufs_hba *hba)
120118
{
121119
if (!(hba->caps & UFSHCD_CAP_CRYPTO))
122120
return false;
123121

124122
/* Reset might clear all keys, so reprogram all the keys. */
125123
blk_crypto_reprogram_all_keys(&hba->crypto_profile);
124+
125+
if (hba->quirks & UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE)
126+
return false;
127+
126128
return true;
127129
}
128130

@@ -159,6 +161,9 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba)
159161
int err = 0;
160162
enum blk_crypto_mode_num blk_mode_num;
161163

164+
if (hba->quirks & UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE)
165+
return 0;
166+
162167
/*
163168
* Don't use crypto if either the hardware doesn't advertise the
164169
* standard crypto capability bit *or* if the vendor specific driver
@@ -228,9 +233,10 @@ void ufshcd_init_crypto(struct ufs_hba *hba)
228233
if (!(hba->caps & UFSHCD_CAP_CRYPTO))
229234
return;
230235

231-
/* Clear all keyslots - the number of keyslots is (CFGC + 1) */
232-
for (slot = 0; slot < hba->crypto_capabilities.config_count + 1; slot++)
233-
ufshcd_clear_keyslot(hba, slot);
236+
/* Clear all keyslots. */
237+
for (slot = 0; slot < hba->crypto_profile.num_slots; slot++)
238+
hba->crypto_profile.ll_ops.keyslot_evict(&hba->crypto_profile,
239+
NULL, slot);
234240
}
235241

236242
void ufshcd_crypto_register(struct ufs_hba *hba, struct request_queue *q)

drivers/ufs/core/ufshcd-crypto.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,33 @@ ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp,
3737
h->dunu = cpu_to_le32(upper_32_bits(lrbp->data_unit_num));
3838
}
3939

40+
static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba,
41+
struct ufshcd_lrb *lrbp)
42+
{
43+
struct scsi_cmnd *cmd = lrbp->cmd;
44+
const struct bio_crypt_ctx *crypt_ctx = scsi_cmd_to_rq(cmd)->crypt_ctx;
45+
46+
if (crypt_ctx && hba->vops && hba->vops->fill_crypto_prdt)
47+
return hba->vops->fill_crypto_prdt(hba, crypt_ctx,
48+
lrbp->ucd_prdt_ptr,
49+
scsi_sg_count(cmd));
50+
return 0;
51+
}
52+
53+
static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba,
54+
struct ufshcd_lrb *lrbp)
55+
{
56+
if (!(hba->quirks & UFSHCD_QUIRK_KEYS_IN_PRDT))
57+
return;
58+
59+
if (!(scsi_cmd_to_rq(lrbp->cmd)->crypt_ctx))
60+
return;
61+
62+
/* Zeroize the PRDT because it can contain cryptographic keys. */
63+
memzero_explicit(lrbp->ucd_prdt_ptr,
64+
ufshcd_sg_entry_size(hba) * scsi_sg_count(lrbp->cmd));
65+
}
66+
4067
bool ufshcd_crypto_enable(struct ufs_hba *hba);
4168

4269
int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba);
@@ -54,6 +81,15 @@ static inline void
5481
ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp,
5582
struct request_desc_header *h) { }
5683

84+
static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba,
85+
struct ufshcd_lrb *lrbp)
86+
{
87+
return 0;
88+
}
89+
90+
static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba,
91+
struct ufshcd_lrb *lrbp) { }
92+
5793
static inline bool ufshcd_crypto_enable(struct ufs_hba *hba)
5894
{
5995
return false;

drivers/ufs/core/ufshcd.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2640,7 +2640,7 @@ static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
26402640

26412641
ufshcd_sgl_to_prdt(hba, lrbp, sg_segments, scsi_sglist(cmd));
26422642

2643-
return 0;
2643+
return ufshcd_crypto_fill_prdt(hba, lrbp);
26442644
}
26452645

26462646
/**
@@ -5479,6 +5479,7 @@ void ufshcd_release_scsi_cmd(struct ufs_hba *hba,
54795479
struct scsi_cmnd *cmd = lrbp->cmd;
54805480

54815481
scsi_dma_unmap(cmd);
5482+
ufshcd_crypto_clear_prdt(hba, lrbp);
54825483
ufshcd_release(hba);
54835484
ufshcd_clk_scaling_update_busy(hba);
54845485
}

0 commit comments

Comments
 (0)