mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 04:42:04 -04:00
Merge "soc: qcom: crypto-qti-hwkm: add wrapped raw secret"
This commit is contained in:
commit
11ffa851db
6 changed files with 201 additions and 12 deletions
|
|
@ -147,8 +147,24 @@ static int ufshcd_crypto_qti_derive_raw_secret(struct keyslot_manager *ksm,
|
|||
u8 *secret,
|
||||
unsigned int secret_size)
|
||||
{
|
||||
return crypto_qti_derive_raw_secret(wrapped_key, wrapped_key_size,
|
||||
secret, secret_size);
|
||||
int err = 0;
|
||||
struct ufs_hba *hba = keyslot_manager_private(ksm);
|
||||
|
||||
pm_runtime_get_sync(hba->dev);
|
||||
err = ufshcd_hold(hba, false);
|
||||
if (err) {
|
||||
pr_err("%s: failed to enable clocks, err %d\n", __func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = crypto_qti_derive_raw_secret(hba->crypto_vops->priv,
|
||||
wrapped_key, wrapped_key_size,
|
||||
secret, secret_size);
|
||||
|
||||
ufshcd_release(hba);
|
||||
pm_runtime_put_sync(hba->dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct keyslot_mgmt_ll_ops ufshcd_crypto_qti_ksm_ops = {
|
||||
|
|
|
|||
|
|
@ -443,11 +443,19 @@ int crypto_qti_keyslot_evict(void *priv_data, unsigned int slot)
|
|||
}
|
||||
EXPORT_SYMBOL(crypto_qti_keyslot_evict);
|
||||
|
||||
int crypto_qti_derive_raw_secret(const u8 *wrapped_key,
|
||||
int crypto_qti_derive_raw_secret(void *priv_data,
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size, u8 *secret,
|
||||
unsigned int secret_size)
|
||||
{
|
||||
int err = 0;
|
||||
struct crypto_vops_qti_entry *ice_entry;
|
||||
|
||||
ice_entry = (struct crypto_vops_qti_entry *) priv_data;
|
||||
if (!ice_entry) {
|
||||
pr_err("%s: vops ice data is invalid\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wrapped_key_size <= RAW_SECRET_SIZE) {
|
||||
pr_err("%s: Invalid wrapped_key_size: %u\n",
|
||||
|
|
@ -461,9 +469,9 @@ int crypto_qti_derive_raw_secret(const u8 *wrapped_key,
|
|||
return err;
|
||||
}
|
||||
|
||||
memcpy(secret, wrapped_key, secret_size);
|
||||
|
||||
return err;
|
||||
return crypto_qti_derive_raw_secret_platform(ice_entry,
|
||||
wrapped_key, wrapped_key_size,
|
||||
secret, secret_size);
|
||||
}
|
||||
EXPORT_SYMBOL(crypto_qti_derive_raw_secret);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,14 @@
|
|||
#define TPKEY_SLOT_ICEMEM_SLAVE 0x92
|
||||
#define KEYMANAGER_ICE_MAP_SLOT(slot) ((slot * 2) + 10)
|
||||
#define GP_KEYSLOT 140
|
||||
#define RAW_SECRET_KEYSLOT 141
|
||||
|
||||
#define QTI_HWKM_INIT_DONE 0x1
|
||||
#define SLOT_EMPTY_ERROR 0x1000
|
||||
#define INLINECRYPT_CTX "inline encryption key"
|
||||
#define RAW_SECRET_CTX "raw secret"
|
||||
#define BYTE_ORDER_VAL 8
|
||||
#define KEY_WRAPPED_SIZE 68
|
||||
|
||||
union crypto_cfg {
|
||||
__le32 regval[2];
|
||||
|
|
@ -98,7 +101,7 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry,
|
|||
}
|
||||
|
||||
//Failsafe, clear GP_KEYSLOT incase it is not empty for any reason
|
||||
err_clear = crypto_qti_hwkm_evict_slot(GP_KEYSLOT, true);
|
||||
err_clear = crypto_qti_hwkm_evict_slot(GP_KEYSLOT, false);
|
||||
if (err_clear && (err_clear != SLOT_EMPTY_ERROR)) {
|
||||
pr_err("%s: Error clearing ICE slot %d, err %d\n",
|
||||
__func__, GP_KEYSLOT, err_clear);
|
||||
|
|
@ -110,9 +113,16 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry,
|
|||
cmd_unwrap.op = KEY_UNWRAP_IMPORT;
|
||||
cmd_unwrap.unwrap.dks = GP_KEYSLOT;
|
||||
cmd_unwrap.unwrap.kwk = TPKEY_SLOT_ICEMEM_SLAVE;
|
||||
cmd_unwrap.unwrap.sz = (key->size) - RAW_SECRET_SIZE;
|
||||
memcpy(cmd_unwrap.unwrap.wkb, (key->raw) + RAW_SECRET_SIZE,
|
||||
cmd_unwrap.unwrap.sz);
|
||||
if ((key->size) == KEY_WRAPPED_SIZE) {
|
||||
cmd_unwrap.unwrap.sz = key->size;
|
||||
memcpy(cmd_unwrap.unwrap.wkb, key->raw,
|
||||
cmd_unwrap.unwrap.sz);
|
||||
} else {
|
||||
cmd_unwrap.unwrap.sz = (key->size) - RAW_SECRET_SIZE;
|
||||
memcpy(cmd_unwrap.unwrap.wkb, (key->raw) + RAW_SECRET_SIZE,
|
||||
cmd_unwrap.unwrap.sz);
|
||||
}
|
||||
|
||||
err_program = qti_hwkm_handle_cmd(&cmd_unwrap, &rsp_unwrap);
|
||||
if (err_program) {
|
||||
pr_err("%s: Error with key unwrap %d\n", __func__,
|
||||
|
|
@ -214,5 +224,132 @@ void crypto_qti_disable_platform(struct crypto_vops_qti_entry *ice_entry)
|
|||
}
|
||||
EXPORT_SYMBOL(crypto_qti_disable_platform);
|
||||
|
||||
int crypto_qti_derive_raw_secret_platform(
|
||||
struct crypto_vops_qti_entry *ice_entry,
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size, u8 *secret,
|
||||
unsigned int secret_size)
|
||||
{
|
||||
int err_program = 0;
|
||||
int err_clear = 0;
|
||||
struct hwkm_cmd cmd_unwrap;
|
||||
struct hwkm_cmd cmd_kdf;
|
||||
struct hwkm_cmd cmd_read;
|
||||
struct hwkm_rsp rsp_unwrap;
|
||||
struct hwkm_rsp rsp_kdf;
|
||||
struct hwkm_rsp rsp_read;
|
||||
|
||||
struct hwkm_key_policy policy_kdf = {
|
||||
.security_lvl = SW_KEY,
|
||||
.hw_destination = ICEMEM_SLAVE,
|
||||
.key_type = GENERIC_KEY,
|
||||
.enc_allowed = true,
|
||||
.dec_allowed = true,
|
||||
.alg_allowed = AES256_CBC,
|
||||
.km_by_nsec_allowed = true,
|
||||
};
|
||||
struct hwkm_bsve bsve_kdf = {
|
||||
.enabled = true,
|
||||
.km_swc_en = true,
|
||||
.km_child_key_policy_en = true,
|
||||
};
|
||||
|
||||
if (wrapped_key_size != KEY_WRAPPED_SIZE) {
|
||||
memcpy(secret, wrapped_key, secret_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err_program = qti_hwkm_clocks(true);
|
||||
if (err_program) {
|
||||
pr_err("%s: Error enabling clocks %d\n", __func__,
|
||||
err_program);
|
||||
return err_program;
|
||||
}
|
||||
|
||||
if ((ice_entry->flags & QTI_HWKM_INIT_DONE) != QTI_HWKM_INIT_DONE) {
|
||||
err_program = qti_hwkm_init();
|
||||
if (err_program) {
|
||||
pr_err("%s: Error with HWKM init %d\n", __func__,
|
||||
err_program);
|
||||
qti_hwkm_clocks(false);
|
||||
return -EINVAL;
|
||||
}
|
||||
ice_entry->flags |= QTI_HWKM_INIT_DONE;
|
||||
}
|
||||
|
||||
//Failsafe, clear GP_KEYSLOT incase it is not empty for any reason
|
||||
err_clear = crypto_qti_hwkm_evict_slot(GP_KEYSLOT, false);
|
||||
if (err_clear && (err_clear != SLOT_EMPTY_ERROR)) {
|
||||
pr_err("%s: Error clearing GP slot %d, err %d\n",
|
||||
__func__, GP_KEYSLOT, err_clear);
|
||||
qti_hwkm_clocks(false);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Unwrap keyblob into a non ICE slot using TP key */
|
||||
cmd_unwrap.op = KEY_UNWRAP_IMPORT;
|
||||
cmd_unwrap.unwrap.dks = GP_KEYSLOT;
|
||||
cmd_unwrap.unwrap.kwk = TPKEY_SLOT_ICEMEM_SLAVE;
|
||||
cmd_unwrap.unwrap.sz = wrapped_key_size;
|
||||
memcpy(cmd_unwrap.unwrap.wkb, wrapped_key,
|
||||
cmd_unwrap.unwrap.sz);
|
||||
|
||||
err_program = qti_hwkm_handle_cmd(&cmd_unwrap, &rsp_unwrap);
|
||||
if (err_program) {
|
||||
pr_err("%s: Error with key unwrap %d\n", __func__,
|
||||
err_program);
|
||||
qti_hwkm_clocks(false);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
//Failsafe, clear RAW_SECRET_KEYSLOT incase it is not empty
|
||||
err_clear = crypto_qti_hwkm_evict_slot(RAW_SECRET_KEYSLOT, false);
|
||||
if (err_clear && (err_clear != SLOT_EMPTY_ERROR)) {
|
||||
pr_err("%s: Error clearing raw secret slot %d, err %d\n",
|
||||
__func__, RAW_SECRET_KEYSLOT, err_clear);
|
||||
qti_hwkm_clocks(false);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Derive a 512-bit key which will be the key to encrypt/decrypt data */
|
||||
cmd_kdf.op = SYSTEM_KDF;
|
||||
cmd_kdf.kdf.dks = RAW_SECRET_KEYSLOT;
|
||||
cmd_kdf.kdf.kdk = GP_KEYSLOT;
|
||||
cmd_kdf.kdf.policy = policy_kdf;
|
||||
cmd_kdf.kdf.bsve = bsve_kdf;
|
||||
cmd_kdf.kdf.sz = round_up(strlen(RAW_SECRET_CTX), BYTE_ORDER_VAL);
|
||||
memset(cmd_kdf.kdf.ctx, 0, HWKM_MAX_CTX_SIZE);
|
||||
memcpy(cmd_kdf.kdf.ctx, RAW_SECRET_CTX, strlen(RAW_SECRET_CTX));
|
||||
|
||||
err_program = qti_hwkm_handle_cmd(&cmd_kdf, &rsp_kdf);
|
||||
if (err_program) {
|
||||
pr_err("%s: Error deriving secret %d, slot %d\n", __func__,
|
||||
err_program, RAW_SECRET_KEYSLOT);
|
||||
err_program = -EINVAL;
|
||||
}
|
||||
|
||||
//Read the KDF key for raw secret
|
||||
cmd_read.op = KEY_SLOT_RDWR;
|
||||
cmd_read.rdwr.slot = RAW_SECRET_KEYSLOT;
|
||||
cmd_read.rdwr.is_write = false;
|
||||
err_program = qti_hwkm_handle_cmd(&cmd_read, &rsp_read);
|
||||
if (err_program) {
|
||||
pr_err("%s: Error with key read %d\n", __func__, err_program);
|
||||
err_program = -EINVAL;
|
||||
}
|
||||
memcpy(secret, rsp_read.rdwr.key, rsp_read.rdwr.sz);
|
||||
|
||||
err_clear = crypto_qti_hwkm_evict_slot(GP_KEYSLOT, false);
|
||||
if (err_clear)
|
||||
pr_err("%s: GP slot clear %d\n", __func__, err_clear);
|
||||
err_clear = crypto_qti_hwkm_evict_slot(RAW_SECRET_KEYSLOT, false);
|
||||
if (err_clear)
|
||||
pr_err("%s: raw secret slot clear %d\n", __func__, err_clear);
|
||||
|
||||
qti_hwkm_clocks(false);
|
||||
return err_program;
|
||||
}
|
||||
EXPORT_SYMBOL(crypto_qti_derive_raw_secret_platform);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Crypto HWKM library for storage encryption");
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry,
|
|||
unsigned int data_unit_mask, int capid);
|
||||
int crypto_qti_invalidate_key(struct crypto_vops_qti_entry *ice_entry,
|
||||
unsigned int slot);
|
||||
int crypto_qti_derive_raw_secret_platform(
|
||||
struct crypto_vops_qti_entry *ice_entry,
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size, u8 *secret,
|
||||
unsigned int secret_size);
|
||||
|
||||
#if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER)
|
||||
void crypto_qti_disable_platform(struct crypto_vops_qti_entry *ice_entry);
|
||||
#else
|
||||
|
|
@ -39,6 +45,15 @@ static inline int crypto_qti_invalidate_key(
|
|||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
static inline int crypto_qti_derive_raw_secret_platform(
|
||||
struct crypto_vops_qti_entry *ice_entry,
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size, u8 *secret,
|
||||
unsigned int secret_size)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void crypto_qti_disable_platform(
|
||||
struct crypto_vops_qti_entry *ice_entry)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -58,5 +58,16 @@ int crypto_qti_invalidate_key(struct crypto_vops_qti_entry *ice_entry,
|
|||
}
|
||||
EXPORT_SYMBOL(crypto_qti_invalidate_key);
|
||||
|
||||
int crypto_qti_derive_raw_secret_platform(
|
||||
struct crypto_vops_qti_entry *ice_entry,
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size, u8 *secret,
|
||||
unsigned int secret_size)
|
||||
{
|
||||
memcpy(secret, wrapped_key, secret_size);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(crypto_qti_derive_raw_secret_platform);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Crypto TZ library for storage encryption");
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ int crypto_qti_keyslot_program(void *priv_data,
|
|||
unsigned int slot, u8 data_unit_mask,
|
||||
int capid);
|
||||
int crypto_qti_keyslot_evict(void *priv_data, unsigned int slot);
|
||||
int crypto_qti_derive_raw_secret(const u8 *wrapped_key,
|
||||
int crypto_qti_derive_raw_secret(void *priv_data,
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size, u8 *secret,
|
||||
unsigned int secret_size);
|
||||
|
||||
|
|
@ -74,7 +75,8 @@ static inline int crypto_qti_keyslot_evict(void *priv_data, unsigned int slot)
|
|||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
static inline int crypto_qti_derive_raw_secret(const u8 *wrapped_key,
|
||||
static inline int crypto_qti_derive_raw_secret(void *priv_data,
|
||||
const u8 *wrapped_key,
|
||||
unsigned int wrapped_key_size,
|
||||
u8 *secret,
|
||||
unsigned int secret_size)
|
||||
|
|
|
|||
Loading…
Reference in a new issue