Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f48a6125 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "security: pfe: Set DUN size according to file system and storage type"

parents 7048b1a8 c35ee759
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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);
+22 −4
Original line number Diff line number Diff line
@@ -280,14 +280,29 @@ 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 = NULL;
	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();

	/*
	 * Update dun based on storage type.
	 * 512 byte dun - For ext4 emmc
	 * 4K dun - For ext4 ufs, f2fs ufs and f2fs emmc
	 */

	if (data_unit) {
		if (!bio_dun(bio) && !memcmp(s_type, "sdcc", strlen("sdcc")))
			*data_unit = 1 << ICE_CRYPTO_DATA_UNIT_512_B;
		else
			*data_unit = 1 << ICE_CRYPTO_DATA_UNIT_4_KB;
	}

	if (which_pfe != INVALID_PFE) {
		/* Encrypted file; override ->bi_crypt_key */
@@ -349,6 +364,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) {
@@ -371,7 +387,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;
@@ -381,7 +398,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",
@@ -432,7 +450,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;

+49 −45
Original line number Diff line number Diff line
@@ -30,31 +30,32 @@
/** global definitions		 **/
/**********************************/

#define TZ_ES_SET_ICE_KEY 0x2
#define TZ_ES_INVALIDATE_ICE_KEY 0x3
#define TZ_ES_CONFIG_SET_ICE_KEY 0x4

/* index 0 and 1 is reserved for FDE */
#define MIN_ICE_KEY_INDEX 2

#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 \
	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)

#define TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID \
	TZ_SYSCALL_CREATE_PARAM_ID_1( \
	TZ_SYSCALL_PARAM_TYPE_VAL)

#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_VAL, TZ_SYSCALL_PARAM_TYPE_VAL)

#define CONTEXT_SIZE 0x1000

#define KEYMASTER_UTILS_CMD_ID 0x200UL
@@ -64,18 +65,22 @@

#define USE_KM_MAJOR_VERSION 4
#define USE_KM_MINOR_VERSION 513

#define ICE_KEY_SIZE 32
#define ICE_SALT_SIZE 32
#define ICE_BUFFER_SIZE 64

static uint32_t keymaster_minor_version;
static uint32_t keymaster_major_version;

static uint8_t ice_key[ICE_KEY_SIZE];
static uint8_t ice_salt[ICE_KEY_SIZE];
static uint8_t ice_buffer[ICE_BUFFER_SIZE];

static struct qseecom_handle *qhandle;

enum {
	ICE_CIPHER_MODE_XTS_128 = 0,
	ICE_CIPHER_MODE_CBC_128 = 1,
	ICE_CIPHER_MODE_XTS_256 = 3,
	ICE_CIPHER_MODE_CBC_256 = 4
};

static uint32_t get_keymaster_version(struct qseecom_handle *qhandle)
{
	int ret = 0;
@@ -144,24 +149,26 @@ static int set_wrapped_key(uint32_t index, const uint8_t *key,
	int ret = 0;
	u32 set_req_len = 0;
	u32 set_rsp_len = 0;
	u32 size = ICE_BUFFER_SIZE / 2;
	struct pfk_ice_key_req *set_req_buf;
	struct pfk_ice_key_rsp *set_rsp_buf;

	memcpy(ice_key, key, sizeof(ice_key));
	memcpy(ice_salt, salt, sizeof(ice_salt));
	memcpy(ice_buffer, key, size);
	memcpy(ice_buffer + size, salt, size);

	set_req_buf = (struct pfk_ice_key_req *) qhandle->sbuf;
	set_req_buf->cmd_id = KEYMASTER_SET_ICE_KEY;
	set_req_buf->index = index;
	set_req_buf->ice_key_offset = sizeof(struct pfk_ice_key_req);
	set_req_buf->ice_key_size = ICE_KEY_SIZE;
	set_req_buf->ice_key_size = size;
	set_req_buf->ice_salt_offset = set_req_buf->ice_key_offset +
					set_req_buf->ice_key_size;
	set_req_buf->ice_salt_size = ICE_SALT_SIZE;
	set_req_buf->ice_salt_size = size;

	memcpy((uint8_t *) set_req_buf + set_req_buf->ice_key_offset, ice_key,
				set_req_buf->ice_key_size);
	memcpy((uint8_t *) set_req_buf + set_req_buf->ice_salt_offset, ice_salt,
	memcpy((uint8_t *) set_req_buf + set_req_buf->ice_key_offset,
			ice_buffer, set_req_buf->ice_key_size);
	memcpy((uint8_t *) set_req_buf + set_req_buf->ice_salt_offset,
			ice_buffer + set_req_buf->ice_key_size,
			set_req_buf->ice_salt_size);

	set_req_len = sizeof(struct pfk_ice_key_req) + set_req_buf->ice_key_size
@@ -209,38 +216,35 @@ static int clear_wrapped_key(uint32_t index)
	return ret;
}

static int set_key(uint32_t index, const uint8_t *key, const uint8_t *salt)
static int set_key(uint32_t index, const uint8_t *key, const uint8_t *salt,
		unsigned int data_unit)
{
	struct scm_desc desc = {0};
	int ret = 0;
	uint32_t smc_id = 0;
	char *tzbuf_key = (char *)ice_key;
	char *tzbuf_salt = (char *)ice_salt;
	u32 tzbuflen_key = sizeof(ice_key);
	u32 tzbuflen_salt = sizeof(ice_salt);
	char *tzbuf = (char *)ice_buffer;
	uint32_t size = ICE_BUFFER_SIZE / 2;

	if (!tzbuf_key || !tzbuf_salt) {
	if (!tzbuf) {
		pr_err("%s No Memory\n", __func__);
		return -ENOMEM;
	}

	memset(tzbuf_key, 0, tzbuflen_key);
	memset(tzbuf_salt, 0, tzbuflen_salt);
	memset(tzbuf, 0, ICE_BUFFER_SIZE);

	memcpy(ice_key, key, sizeof(ice_key));
	memcpy(ice_salt, salt, sizeof(ice_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] = ICE_CIPHER_MODE_XTS_256;
	desc.args[4] = data_unit;

	ret = scm_call2(smc_id, &desc);
	if (ret)
@@ -267,7 +271,7 @@ static int clear_key(uint32_t index)
}

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 ret = 0, ret1 = 0;
	char *s_type = storage_type;
@@ -292,12 +296,12 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
		goto out;
	}

	if (pfk_wrapped_key_supported() && should_use_keymaster()) {
	if (should_use_keymaster()) {
		pr_debug("%s: Setting wrapped key\n", __func__);
		ret = set_wrapped_key(index, key, salt);
	} else {
		pr_debug("%s: Setting keys with QSEE kernel\n", __func__);
		ret = set_key(index, key, salt);
		ret = set_key(index, key, salt, data_unit);
	}

	if (ret) {
@@ -308,7 +312,7 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
				goto out;
		}
		/* Try to invalidate the key to keep ICE in proper state */
		if (pfk_wrapped_key_supported() && should_use_keymaster())
		if (should_use_keymaster())
			ret1 = clear_wrapped_key(index);
		else
			ret1 = clear_key(index);
@@ -345,7 +349,7 @@ int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type)
		return ret;
	}

	if (pfk_wrapped_key_supported() && should_use_keymaster()) {
	if (should_use_keymaster()) {
		ret = clear_wrapped_key(index);
		pr_debug("%s: Clearing wrapped key\n", __func__);
	} else {
+1 −13
Original line number Diff line number Diff line
@@ -51,20 +51,8 @@ struct pfk_km_get_version_rsp {
int pfk_ice_init(void);
int pfk_ice_deinit(void);

#ifdef CONFIG_PFK_WRAPPED_KEY_SUPPORTED
static inline bool pfk_wrapped_key_supported(void)
{
	return true;
}
#else
static inline bool pfk_wrapped_key_supported(void)
{
	return false;
}
#endif

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);

#endif /* PFK_ICE_H_ */
+17 −4
Original line number Diff line number Diff line
@@ -131,6 +131,16 @@ static inline void kc_spin_unlock(void)
	spin_unlock_irqrestore(&kc_lock, flags);
}

/**
 * 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
 *
@@ -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;
@@ -479,7 +491,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;
@@ -544,7 +556,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;
Loading