ANDROID: scsi: ufs: add UFSHCD_QUIRK_KEYS_IN_PRDT

Add UFSHCD_QUIRK_KEYS_IN_PRDT which tells ufshcd-core to zeroize the
PRDT after each encrypted request.

This is needed because when using FMP, encryption keys get stored in the
PRDT.  Keys should always be zeroized when no longer needed.

Bug: 166139333
Bug: 162257402
Change-Id: I4855e276f16742aeaf962a2d344a11db6ff2a544
Signed-off-by: Eric Biggers <ebiggers@google.com>
This commit is contained in:
Eric Biggers 2020-08-22 10:47:34 -07:00 committed by Alistair Delva
parent 73372c9835
commit 4ad2fd5329
3 changed files with 24 additions and 0 deletions

View File

@ -34,6 +34,19 @@ ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, u32 *dword_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 (!lrbp->cmd->request->crypt_ctx)
return;
memzero_explicit(lrbp->ucd_prdt_ptr,
hba->sg_entry_size * scsi_sg_count(lrbp->cmd));
}
bool ufshcd_crypto_enable(struct ufs_hba *hba);
int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba);
@ -54,6 +67,9 @@ static inline void
ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, u32 *dword_0,
u32 *dword_1, u32 *dword_3) { }
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;

View File

@ -4927,6 +4927,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
result = ufshcd_transfer_rsp_status(hba, lrbp);
scsi_dma_unmap(cmd);
cmd->result = result;
ufshcd_crypto_clear_prdt(hba, lrbp);
/* Mark completed command as NULL in LRB */
lrbp->cmd = NULL;
/* Do not touch lrbp after scsi done */

View File

@ -539,6 +539,13 @@ enum ufshcd_quirks {
* a passthrough keyslot manager.
*/
UFSHCD_QUIRK_NO_KEYSLOTS = 1 << 12,
/*
* This quirk needs to be enabled if the host controller requires that
* the PRDT be cleared after each encrypted request because encryption
* keys were stored in it.
*/
UFSHCD_QUIRK_KEYS_IN_PRDT = 1 << 13,
};
enum ufshcd_caps {