[PATCH 08/10] scsi: ufs: add support for generate, import and prepare keys

Gaurav Kashyap
2021-12-06T22:59:20Z

This patch contains two changes in UFS for wrapped keys.
1. Implements the blk_crypto_profile ops for generate, import
and prepare key apis.
2. Adds UFS vops for generate, import and prepare keys so
that vendors can hooks to them.

Signed-off-by: Gaurav Kashyap <quic_gaurkash@quicinc.com>
---
drivers/scsi/ufs/ufshcd-crypto.c | 50 ++++++++++++++++++++++++++++++--
drivers/scsi/ufs/ufshcd.h | 11 +++++++
2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/scsi/ufs/ufshcd-crypto.c
index 9d68621a0eb4..2bea9b924f77 100644
--- a/drivers/scsi/ufs/ufshcd-crypto.c
+++ b/drivers/scsi/ufs/ufshcd-crypto.c
@@ -136,9 +136,9 @@ bool ufshcd_crypto_enable(struct ufs_hba *hba)
}

static int ufshcd_crypto_derive_sw_secret(struct blk_crypto_profile *profile,
- const u8 *wrapped_key,
- unsigned int wrapped_key_size,
- u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE])
+ const u8 *wrapped_key,
+ unsigned int wrapped_key_size,
+ u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE])
{
struct ufs_hba *hba =
container_of(profile, struct ufs_hba, crypto_profile);
@@ -146,6 +146,47 @@ static int ufshcd_crypto_derive_sw_secret(struct blk_crypto_profile *profile,
if (hba->vops && hba->vops->derive_secret)
return hba->vops->derive_secret(hba, wrapped_key,
wrapped_key_size, sw_secret);
+ return 0;
+}
+
+static int ufshcd_crypto_generate_key(struct blk_crypto_profile *profile,
+ u8 longterm_wrapped_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+ struct ufs_hba *hba =
+ container_of(profile, struct ufs_hba, crypto_profile);
+
+ if (hba->vops && hba->vops->generate_key)
+ return hba->vops->generate_key(longterm_wrapped_key);
+
+ return -EOPNOTSUPP;
+}
+
+static int ufshcd_crypto_prepare_key(struct blk_crypto_profile *profile,
+ const u8 *longterm_wrapped_key,
+ size_t longterm_wrapped_key_size,
+ u8 ephemerally_wrapped_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+ struct ufs_hba *hba =
+ container_of(profile, struct ufs_hba, crypto_profile);
+
+ if (hba->vops && hba->vops->prepare_key)
+ return hba->vops->prepare_key(longterm_wrapped_key,
+ longterm_wrapped_key_size, ephemerally_wrapped_key);
+
+ return -EOPNOTSUPP;
+}
+
+static int ufshcd_crypto_import_key(struct blk_crypto_profile *profile,
+ const u8 *imported_key,
+ size_t imported_key_size,
+ u8 longterm_wrapped_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+ struct ufs_hba *hba =
+ container_of(profile, struct ufs_hba, crypto_profile);
+
+ if (hba->vops && hba->vops->import_key)
+ return hba->vops->import_key(imported_key,
+ imported_key_size, longterm_wrapped_key);

return -EOPNOTSUPP;
}
@@ -154,6 +195,9 @@ static const struct blk_crypto_ll_ops ufshcd_crypto_ops = {
.keyslot_program = ufshcd_crypto_keyslot_program,
.keyslot_evict = ufshcd_crypto_keyslot_evict,
.derive_sw_secret = ufshcd_crypto_derive_sw_secret,
+ .generate_key = ufshcd_crypto_generate_key,
+ .prepare_key = ufshcd_crypto_prepare_key,
+ .import_key = ufshcd_crypto_import_key,
};

static enum blk_crypto_mode_num
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 095c2d660aa7..88cd21dec0d9 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -321,6 +321,10 @@ struct ufs_pwr_mode_info {
* @program_key: program or evict an inline encryption key
* @event_notify: called to notify important events
* @derive_secret: derive sw secret from wrapped inline encryption key
+ * @generate_key: generate a longterm wrapped key for inline encryption
+ * @prepare_key: prepare the longterm wrapped key for inline encryption
+ * by rewrapping with a ephemeral wrapping key.
+ * @import_key: import a raw key and return a longterm wrapped key.
*/
struct ufs_hba_variant_ops {
const char *name;
@@ -362,6 +366,13 @@ struct ufs_hba_variant_ops {
int (*derive_secret)(struct ufs_hba *hba, const u8 *wrapped_key,
unsigned int wrapped_key_size,
u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]);
+ int (*generate_key)(u8 longterm_wrapped_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]);
+ int (*prepare_key)(const u8 *longterm_wrapped_key,
+ unsigned int longterm_wrapped_key_size,
+ u8 ephemerally_wrapped_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]);
+ int (*import_key)(const u8 *imported_key,
+ unsigned int imported_key_size,
+ u8 longterm_wrapped_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]);
};

/* clock gating state */
--
2.17.1