aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeeraj Soni <neersoni@codeaurora.org>2018-08-17 20:39:35 +0530
committerAnurudh Kumar Tiwari <aktiwari@codeaurora.org>2018-09-04 11:46:33 +0530
commitcd6e78581acf722f022495bc50498a732fa64b24 (patch)
tree5630ad2a5b58cd46c4eae97f8e3e9b5965f54cba
parent5d14c24f62e91e034e28571cc9ea4df3099156d3 (diff)
security: pfe: Set DUN size accroding to file system and storage typeLA.UM.7.8.r1-02800-SDM710.0
EXT4 FS and F2FS has different way of setting Data Unit Number (DUN) size value for UFS and eMMC storage devices. EXT4 FS uses sector number while F2FS uses inode|pgidx. Check Storage and file system type before setting the DUN value in Inline Crypto Engine (ICE). Change-Id: If822863893fc0725a5ff0410e7418c352ad70fc1 Signed-off-by: Neeraj Soni <neersoni@codeaurora.org>
-rw-r--r--include/crypto/ice.h12
-rw-r--r--security/pfe/pfk.c20
-rw-r--r--security/pfe/pfk_ext4.c17
-rw-r--r--security/pfe/pfk_ext4.h4
-rw-r--r--security/pfe/pfk_f2fs.c16
-rw-r--r--security/pfe/pfk_f2fs.h4
-rw-r--r--security/pfe/pfk_ice.c63
-rw-r--r--security/pfe/pfk_ice.h2
-rw-r--r--security/pfe/pfk_kc.c21
-rw-r--r--security/pfe/pfk_kc.h3
10 files changed, 112 insertions, 50 deletions
diff --git a/include/crypto/ice.h b/include/crypto/ice.h
index 133041ea9ec8..0b8f048f39cb 100644
--- a/include/crypto/ice.h
+++ b/include/crypto/ice.h
@@ -49,6 +49,18 @@ struct ice_data_setting {
bool encr_bypass;
};
+/* MSM ICE Crypto Data Unit of target DUN of Transfer Request */
+enum ice_crypto_data_unit {
+ ICE_CRYPTO_DATA_UNIT_512_B = 0,
+ ICE_CRYPTO_DATA_UNIT_1_KB = 1,
+ ICE_CRYPTO_DATA_UNIT_2_KB = 2,
+ ICE_CRYPTO_DATA_UNIT_4_KB = 3,
+ ICE_CRYPTO_DATA_UNIT_8_KB = 4,
+ ICE_CRYPTO_DATA_UNIT_16_KB = 5,
+ ICE_CRYPTO_DATA_UNIT_32_KB = 6,
+ ICE_CRYPTO_DATA_UNIT_64_KB = 7,
+};
+
typedef void (*ice_error_cb)(void *, u32 error);
struct qcom_ice_variant_ops *qcom_ice_get_variant_ops(struct device_node *node);
diff --git a/security/pfe/pfk.c b/security/pfe/pfk.c
index 8ad25cc0f3e2..0e153f2c8dd1 100644
--- a/security/pfe/pfk.c
+++ b/security/pfe/pfk.c
@@ -75,7 +75,9 @@ typedef int (*pfk_parse_inode_type)(const struct bio *bio,
const struct inode *inode,
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
- bool *is_pfe);
+ bool *is_pfe,
+ unsigned int *data_unit,
+ const char *storage_type);
typedef bool (*pfk_allow_merge_bio_type)(const struct bio *bio1,
const struct bio *bio2, const struct inode *inode1,
@@ -281,21 +283,24 @@ bool pfe_is_inode_filesystem_type(const struct inode *inode,
static int pfk_get_key_for_bio(const struct bio *bio,
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo_mode,
- bool *is_pfe)
+ bool *is_pfe, unsigned int *data_unit)
{
const struct inode *inode;
enum pfe_type which_pfe;
const struct blk_encryption_key *key;
+ char *s_type = NULL;
inode = pfk_bio_get_inode(bio);
which_pfe = pfk_get_pfe_type(inode);
+ s_type = (char *)pfk_kc_get_storage_type();
if (which_pfe != INVALID_PFE) {
/* Encrypted file; override ->bi_crypt_key */
pr_debug("parsing inode %lu with PFE type %d\n",
inode->i_ino, which_pfe);
return (*(pfk_parse_inode_ftable[which_pfe]))
- (bio, inode, key_info, algo_mode, is_pfe);
+ (bio, inode, key_info, algo_mode, is_pfe,
+ data_unit, (const char *)s_type);
}
/*
@@ -348,6 +353,7 @@ int pfk_load_key_start(const struct bio *bio,
struct pfk_key_info key_info = {NULL, NULL, 0, 0};
enum ice_cryto_algo_mode algo_mode = ICE_CRYPTO_ALGO_MODE_AES_XTS;
enum ice_crpto_key_size key_size_type = 0;
+ unsigned int data_unit = 1 << ICE_CRYPTO_DATA_UNIT_512_B;
u32 key_index = 0;
if (!is_pfe) {
@@ -370,7 +376,8 @@ int pfk_load_key_start(const struct bio *bio,
return -EINVAL;
}
- ret = pfk_get_key_for_bio(bio, &key_info, &algo_mode, is_pfe);
+ ret = pfk_get_key_for_bio(bio, &key_info, &algo_mode, is_pfe,
+ &data_unit);
if (ret != 0)
return ret;
@@ -380,7 +387,8 @@ int pfk_load_key_start(const struct bio *bio,
return ret;
ret = pfk_kc_load_key_start(key_info.key, key_info.key_size,
- key_info.salt, key_info.salt_size, &key_index, async);
+ key_info.salt, key_info.salt_size, &key_index, async,
+ data_unit);
if (ret) {
if (ret != -EBUSY && ret != -EAGAIN)
pr_err("start: could not load key into pfk key cache, error %d\n",
@@ -431,7 +439,7 @@ int pfk_load_key_end(const struct bio *bio, bool *is_pfe)
if (!pfk_is_ready())
return -ENODEV;
- ret = pfk_get_key_for_bio(bio, &key_info, NULL, is_pfe);
+ ret = pfk_get_key_for_bio(bio, &key_info, NULL, is_pfe, NULL);
if (ret != 0)
return ret;
diff --git a/security/pfe/pfk_ext4.c b/security/pfe/pfk_ext4.c
index 0eb122565ecc..7000b666657b 100644
--- a/security/pfe/pfk_ext4.c
+++ b/security/pfe/pfk_ext4.c
@@ -141,7 +141,9 @@ int pfk_ext4_parse_inode(const struct bio *bio,
const struct inode *inode,
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
- bool *is_pfe)
+ bool *is_pfe,
+ unsigned int *data_unit,
+ const char *storage_type)
{
int ret = 0;
@@ -155,6 +157,19 @@ int pfk_ext4_parse_inode(const struct bio *bio,
*/
*is_pfe = true;
+ /* Update dun based upon storage type.
+ * For ext4 FS UFS has 4k dun whereas eMMC
+ * uses 512Byte dun.
+ */
+ if (storage_type && data_unit) {
+ if (!memcmp(storage_type, "ufs", strlen("ufs")))
+ *data_unit = 1 << ICE_CRYPTO_DATA_UNIT_4_KB;
+ else if (!memcmp(storage_type, "sdcc", strlen("sdcc")))
+ *data_unit = 1 << ICE_CRYPTO_DATA_UNIT_512_B;
+ else
+ return -EINVAL;
+ }
+
if (!pfk_ext4_is_ready())
return -ENODEV;
diff --git a/security/pfe/pfk_ext4.h b/security/pfe/pfk_ext4.h
index c33232f35a14..e39d04d82df5 100644
--- a/security/pfe/pfk_ext4.h
+++ b/security/pfe/pfk_ext4.h
@@ -24,7 +24,9 @@ int pfk_ext4_parse_inode(const struct bio *bio,
const struct inode *inode,
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
- bool *is_pfe);
+ bool *is_pfe,
+ unsigned int *data_unit,
+ const char *storage_type);
bool pfk_ext4_allow_merge_bio(const struct bio *bio1,
const struct bio *bio2, const struct inode *inode1,
diff --git a/security/pfe/pfk_f2fs.c b/security/pfe/pfk_f2fs.c
index 8b9d515043e8..2076267f0592 100644
--- a/security/pfe/pfk_f2fs.c
+++ b/security/pfe/pfk_f2fs.c
@@ -116,7 +116,9 @@ int pfk_f2fs_parse_inode(const struct bio *bio,
const struct inode *inode,
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
- bool *is_pfe)
+ bool *is_pfe,
+ unsigned int *data_unit,
+ const char *storage_type)
{
int ret = 0;
@@ -130,6 +132,18 @@ int pfk_f2fs_parse_inode(const struct bio *bio,
*/
*is_pfe = true;
+ /* Update the dun based upon storage type.
+ * Right now both UFS and eMMC storage uses 4KB dun
+ * for F2FS
+ */
+ if (storage_type && data_unit) {
+ if (!memcmp(storage_type, "ufs", strlen("ufs")) ||
+ !memcmp(storage_type, "sdcc", strlen("sdcc")))
+ *data_unit = 1 << ICE_CRYPTO_DATA_UNIT_4_KB;
+ else
+ return -EINVAL;
+ }
+
if (!pfk_f2fs_is_ready())
return -ENODEV;
diff --git a/security/pfe/pfk_f2fs.h b/security/pfe/pfk_f2fs.h
index 551d529bced6..2e0c21d16ea6 100644
--- a/security/pfe/pfk_f2fs.h
+++ b/security/pfe/pfk_f2fs.h
@@ -24,7 +24,9 @@ int pfk_f2fs_parse_inode(const struct bio *bio,
const struct inode *inode,
struct pfk_key_info *key_info,
enum ice_cryto_algo_mode *algo,
- bool *is_pfe);
+ bool *is_pfe,
+ unsigned int *data_unit,
+ const char *storage_type);
bool pfk_f2fs_allow_merge_bio(const struct bio *bio1,
const struct bio *bio2, const struct inode *inode1,
diff --git a/security/pfe/pfk_ice.c b/security/pfe/pfk_ice.c
index a86042c98e1f..59c4adeaee47 100644
--- a/security/pfe/pfk_ice.c
+++ b/security/pfe/pfk_ice.c
@@ -26,11 +26,7 @@
#include "pfk_ice.h"
-/**********************************/
-/** global definitions **/
-/**********************************/
-
-#define TZ_ES_SET_ICE_KEY 0x2
+#define TZ_ES_CONFIG_SET_ICE_KEY 0x4
#define TZ_ES_INVALIDATE_ICE_KEY 0x3
/* index 0 and 1 is reserved for FDE */
@@ -38,44 +34,45 @@
#define MAX_ICE_KEY_INDEX 31
-
-#define TZ_ES_SET_ICE_KEY_ID \
- TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, TZ_ES_SET_ICE_KEY)
-
+#define TZ_ES_CONFIG_SET_ICE_KEY_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, \
+ TZ_ES_CONFIG_SET_ICE_KEY)
#define TZ_ES_INVALIDATE_ICE_KEY_ID \
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, \
TZ_SVC_ES, TZ_ES_INVALIDATE_ICE_KEY)
-
-#define TZ_ES_SET_ICE_KEY_PARAM_ID \
+#define TZ_ES_CONFIG_SET_ICE_KEY_PARAM_ID \
TZ_SYSCALL_CREATE_PARAM_ID_5( \
TZ_SYSCALL_PARAM_TYPE_VAL, \
TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL, \
- TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL)
#define TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID \
TZ_SYSCALL_CREATE_PARAM_ID_1( \
TZ_SYSCALL_PARAM_TYPE_VAL)
-#define ICE_KEY_SIZE 32
-#define ICE_SALT_SIZE 32
+#define ICE_BUFFER_SIZE 64
+
+enum {
+ TZ_CIPHER_MODE_XTS_128 = 0,
+ TZ_CIPHER_MODE_CBC_128 = 1,
+ TZ_CIPHER_MODE_XTS_256 = 3,
+ TZ_CIPHER_MODE_CBC_256 = 4
+};
-static uint8_t ice_key[ICE_KEY_SIZE];
-static uint8_t ice_salt[ICE_KEY_SIZE];
+static uint8_t ice_buffer[ICE_BUFFER_SIZE];
int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
- char *storage_type)
+ char *storage_type, unsigned int data_unit)
{
struct scm_desc desc = {0};
int ret, ret1;
- char *tzbuf_key = (char *)ice_key;
- char *tzbuf_salt = (char *)ice_salt;
+ char *tzbuf = (char *)ice_buffer;
char *s_type = storage_type;
uint32_t smc_id = 0;
- u32 tzbuflen_key = sizeof(ice_key);
- u32 tzbuflen_salt = sizeof(ice_salt);
+ u32 size = ICE_BUFFER_SIZE / 2;
if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX) {
pr_err("%s Invalid index %d\n", __func__, index);
@@ -86,7 +83,7 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
return -EINVAL;
}
- if (!tzbuf_key || !tzbuf_salt) {
+ if (!tzbuf) {
pr_err("%s No Memory\n", __func__);
return -ENOMEM;
}
@@ -96,23 +93,21 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
return -EINVAL;
}
- memset(tzbuf_key, 0, tzbuflen_key);
- memset(tzbuf_salt, 0, tzbuflen_salt);
+ memset(tzbuf, 0, ICE_BUFFER_SIZE);
- memcpy(ice_key, key, tzbuflen_key);
- memcpy(ice_salt, salt, tzbuflen_salt);
+ memcpy(ice_buffer, key, size);
+ memcpy(ice_buffer + size, salt, size);
- dmac_flush_range(tzbuf_key, tzbuf_key + tzbuflen_key);
- dmac_flush_range(tzbuf_salt, tzbuf_salt + tzbuflen_salt);
+ dmac_flush_range(tzbuf, tzbuf + ICE_BUFFER_SIZE);
- smc_id = TZ_ES_SET_ICE_KEY_ID;
+ smc_id = TZ_ES_CONFIG_SET_ICE_KEY_ID;
- desc.arginfo = TZ_ES_SET_ICE_KEY_PARAM_ID;
+ desc.arginfo = TZ_ES_CONFIG_SET_ICE_KEY_PARAM_ID;
desc.args[0] = index;
- desc.args[1] = virt_to_phys(tzbuf_key);
- desc.args[2] = tzbuflen_key;
- desc.args[3] = virt_to_phys(tzbuf_salt);
- desc.args[4] = tzbuflen_salt;
+ desc.args[1] = virt_to_phys(tzbuf);
+ desc.args[2] = ICE_BUFFER_SIZE;
+ desc.args[3] = TZ_CIPHER_MODE_XTS_256;
+ desc.args[4] = data_unit;
ret = qcom_ice_setup_ice_hw((const char *)s_type, true);
diff --git a/security/pfe/pfk_ice.h b/security/pfe/pfk_ice.h
index 31772e798636..8fd0d83b3ae0 100644
--- a/security/pfe/pfk_ice.h
+++ b/security/pfe/pfk_ice.h
@@ -26,7 +26,7 @@ int pfk_ice_init(void);
int pfk_ice_deinit(void);
int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
- char *storage_type);
+ char *storage_type, unsigned int data_unit);
int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type);
diff --git a/security/pfe/pfk_kc.c b/security/pfe/pfk_kc.c
index eecc0260087d..a8e990926af3 100644
--- a/security/pfe/pfk_kc.c
+++ b/security/pfe/pfk_kc.c
@@ -132,6 +132,16 @@ static inline void kc_spin_unlock(void)
}
/**
+ * pfk_kc_get_storage_type() - return the hardware storage type.
+ *
+ * Return: storage type queried during bootup.
+ */
+const char *pfk_kc_get_storage_type(void)
+{
+ return s_type;
+}
+
+/**
* kc_entry_is_available() - checks whether the entry is available
*
* Return true if it is , false otherwise or if invalid
@@ -389,13 +399,15 @@ static void kc_clear_entry(struct kc_entry *entry)
* @key_size: key_size
* @salt: salt
* @salt_size: salt_size
+ * @data_unit: dun size
*
* The previous key is securely released and wiped, the new one is loaded
* to ICE.
* Should be invoked under spinlock
*/
static int kc_update_entry(struct kc_entry *entry, const unsigned char *key,
- size_t key_size, const unsigned char *salt, size_t salt_size)
+ size_t key_size, const unsigned char *salt, size_t salt_size,
+ unsigned int data_unit)
{
int ret;
@@ -412,7 +424,7 @@ static int kc_update_entry(struct kc_entry *entry, const unsigned char *key,
kc_spin_unlock();
ret = qti_pfk_ice_set_key(entry->key_index, entry->key,
- entry->salt, s_type);
+ entry->salt, s_type, data_unit);
kc_spin_lock();
return ret;
@@ -478,7 +490,7 @@ int pfk_kc_deinit(void)
*/
int pfk_kc_load_key_start(const unsigned char *key, size_t key_size,
const unsigned char *salt, size_t salt_size, u32 *key_index,
- bool async)
+ bool async, unsigned int data_unit)
{
int ret = 0;
struct kc_entry *entry = NULL;
@@ -543,7 +555,8 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size,
break;
}
case (FREE):
- ret = kc_update_entry(entry, key, key_size, salt, salt_size);
+ ret = kc_update_entry(entry, key, key_size, salt, salt_size,
+ data_unit);
if (ret) {
entry->state = SCM_ERROR;
entry->scm_error = ret;
diff --git a/security/pfe/pfk_kc.h b/security/pfe/pfk_kc.h
index 6adeee2259cd..89d40be95fdf 100644
--- a/security/pfe/pfk_kc.h
+++ b/security/pfe/pfk_kc.h
@@ -19,7 +19,7 @@ int pfk_kc_init(void);
int pfk_kc_deinit(void);
int pfk_kc_load_key_start(const unsigned char *key, size_t key_size,
const unsigned char *salt, size_t salt_size, u32 *key_index,
- bool async);
+ bool async, unsigned int data_unit);
void pfk_kc_load_key_end(const unsigned char *key, size_t key_size,
const unsigned char *salt, size_t salt_size);
int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size,
@@ -27,6 +27,7 @@ int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size,
int pfk_kc_remove_key(const unsigned char *key, size_t key_size);
int pfk_kc_clear(void);
void pfk_kc_clear_on_reset(void);
+const char *pfk_kc_get_storage_type(void);
extern char *saved_command_line;