if (ccap_array[cap_idx].algorithm_id == UFS_CRYPTO_ALG_AES_XTS) { /* In XTS mode, the blk_crypto_key's size is already doubled */
memcpy(cfg.crypto_key, key->bytes, key->size/2);
memcpy(cfg.crypto_key + UFS_CRYPTO_KEY_MAX_SIZE/2,
key->bytes + key->size/2, key->size/2);
} else {
memcpy(cfg.crypto_key, key->bytes, key->size);
}
ufshcd_program_key(hba, &cfg, slot);
memzero_explicit(&cfg, sizeof(cfg)); return 0;
}
staticint ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, conststruct blk_crypto_key *key, unsignedint slot)
{ struct ufs_hba *hba = ufs_hba_from_crypto_profile(profile); /* * Clear the crypto cfg on the device. Clearing CFGE * might not be sufficient, so just clear the entire cfg.
*/ union ufs_crypto_cfg_entry cfg = {};
ufshcd_program_key(hba, &cfg, slot); return 0;
}
/* * Reprogram the keyslots if needed, and return true if CRYPTO_GENERAL_ENABLE * should be used in the host controller initialization sequence.
*/ bool ufshcd_crypto_enable(struct ufs_hba *hba)
{ if (!(hba->caps & UFSHCD_CAP_CRYPTO)) returnfalse;
/* Reset might clear all keys, so reprogram all the keys. */
blk_crypto_reprogram_all_keys(&hba->crypto_profile);
if (hba->quirks & UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE) returnfalse;
staticenum blk_crypto_mode_num
ufshcd_find_blk_crypto_mode(union ufs_crypto_cap_entry cap)
{ int i;
for (i = 0; i < ARRAY_SIZE(ufs_crypto_algs); i++) {
BUILD_BUG_ON(UFS_CRYPTO_KEY_SIZE_INVALID != 0); if (ufs_crypto_algs[i].ufs_alg == cap.algorithm_id &&
ufs_crypto_algs[i].ufs_key_size == cap.key_size) { return i;
}
} return BLK_ENCRYPTION_MODE_INVALID;
}
/** * ufshcd_hba_init_crypto_capabilities - Read crypto capabilities, init crypto * fields in hba * @hba: Per adapter instance * * Return: 0 if crypto was initialized or is not supported, else a -errno value.
*/ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba)
{ int cap_idx; int err = 0; enum blk_crypto_mode_num blk_mode_num;
if (hba->quirks & UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE) return 0;
/* * Don't use crypto if either the hardware doesn't advertise the * standard crypto capability bit *or* if the vendor specific driver * hasn't advertised that crypto is supported.
*/ if (!(hba->capabilities & MASK_CRYPTO_SUPPORT) ||
!(hba->caps & UFSHCD_CAP_CRYPTO)) goto out;
/* The actual number of configurations supported is (CFGC+1) */
err = devm_blk_crypto_profile_init(
hba->dev, &hba->crypto_profile,
hba->crypto_capabilities.config_count + 1); if (err) goto out;
hba->crypto_profile.ll_ops = ufshcd_crypto_ops; /* UFS only supports 8 bytes for any DUN */
hba->crypto_profile.max_dun_bytes_supported = 8;
hba->crypto_profile.key_types_supported = BLK_CRYPTO_KEY_TYPE_RAW;
hba->crypto_profile.dev = hba->dev;
/* * Cache all the UFS crypto capabilities and advertise the supported * crypto modes and data unit sizes to the block layer.
*/ for (cap_idx = 0; cap_idx < hba->crypto_capabilities.num_crypto_cap;
cap_idx++) {
hba->crypto_cap_array[cap_idx].reg_val =
cpu_to_le32(ufshcd_readl(hba,
REG_UFS_CRYPTOCAP +
cap_idx * sizeof(__le32)));
blk_mode_num = ufshcd_find_blk_crypto_mode(
hba->crypto_cap_array[cap_idx]); if (blk_mode_num != BLK_ENCRYPTION_MODE_INVALID)
hba->crypto_profile.modes_supported[blk_mode_num] |=
hba->crypto_cap_array[cap_idx].sdus_mask * 512;
}
return 0;
out: /* Indicate that init failed by clearing UFSHCD_CAP_CRYPTO */
hba->caps &= ~UFSHCD_CAP_CRYPTO; return err;
}
/** * ufshcd_init_crypto - Initialize crypto hardware * @hba: Per adapter instance
*/ void ufshcd_init_crypto(struct ufs_hba *hba)
{ int slot;
if (!(hba->caps & UFSHCD_CAP_CRYPTO)) return;
/* Clear all keyslots. */ for (slot = 0; slot < hba->crypto_profile.num_slots; slot++)
hba->crypto_profile.ll_ops.keyslot_evict(&hba->crypto_profile,
NULL, slot);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.