summaryrefslogtreecommitdiff
path: root/drivers/ufs
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2024-07-08 16:53:29 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2024-07-10 22:32:30 -0400
commit4c45dba50a3750a0834353c4187e7896b158bc0c (patch)
tree4155b7b267dccc57450440736128b1ba207a2b1e /drivers/ufs
parent8ecea3da1567e0648b5d37a6faec73fc9c8571ba (diff)
downloadlwn-4c45dba50a3750a0834353c4187e7896b158bc0c.tar.gz
lwn-4c45dba50a3750a0834353c4187e7896b158bc0c.zip
scsi: ufs: core: Add UFSHCD_QUIRK_KEYS_IN_PRDT
Since the nonstandard inline encryption support on Exynos SoCs requires that raw cryptographic keys be copied into the PRDT, it is desirable to zeroize those keys after each request to keep them from being left in memory. Therefore, add a quirk bit that enables the zeroization. We could instead do the zeroization unconditionally. However, using a quirk bit avoids adding the zeroization overhead to standard devices. Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Peter Griffin <peter.griffin@linaro.org> Signed-off-by: Eric Biggers <ebiggers@google.com> Link: https://lore.kernel.org/r/20240708235330.103590-6-ebiggers@kernel.org Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/ufs')
-rw-r--r--drivers/ufs/core/ufshcd-crypto.h17
-rw-r--r--drivers/ufs/core/ufshcd.c1
2 files changed, 18 insertions, 0 deletions
diff --git a/drivers/ufs/core/ufshcd-crypto.h b/drivers/ufs/core/ufshcd-crypto.h
index 3eb8df42e194..89bb97c14c15 100644
--- a/drivers/ufs/core/ufshcd-crypto.h
+++ b/drivers/ufs/core/ufshcd-crypto.h
@@ -50,6 +50,20 @@ static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba,
return 0;
}
+static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba,
+ struct ufshcd_lrb *lrbp)
+{
+ if (!(hba->quirks & UFSHCD_QUIRK_KEYS_IN_PRDT))
+ return;
+
+ if (!(scsi_cmd_to_rq(lrbp->cmd)->crypt_ctx))
+ return;
+
+ /* Zeroize the PRDT because it can contain cryptographic keys. */
+ memzero_explicit(lrbp->ucd_prdt_ptr,
+ ufshcd_sg_entry_size(hba) * scsi_sg_count(lrbp->cmd));
+}
+
bool ufshcd_crypto_enable(struct ufs_hba *hba);
int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba);
@@ -73,6 +87,9 @@ static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba,
return 0;
}
+static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba,
+ struct ufshcd_lrb *lrbp) { }
+
static inline bool ufshcd_crypto_enable(struct ufs_hba *hba)
{
return false;
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 06619682087c..7c5ad68e49f2 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -5479,6 +5479,7 @@ void ufshcd_release_scsi_cmd(struct ufs_hba *hba,
struct scsi_cmnd *cmd = lrbp->cmd;
scsi_dma_unmap(cmd);
+ ufshcd_crypto_clear_prdt(hba, lrbp);
ufshcd_release(hba);
ufshcd_clk_scaling_update_busy(hba);
}