Loading drivers/crypto/msm/ice.c +42 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/pfk.h> #include <crypto/ice.h> #include <soc/qcom/scm.h> #include <soc/qcom/qseecomi.h> #include "iceregs.h" #define TZ_SYSCALL_CREATE_SMC_ID(o, s, f) \ Loading @@ -40,6 +41,13 @@ #define TZ_OS_KS_RESTORE_KEY_ID_PARAM_ID \ TZ_SYSCALL_CREATE_PARAM_ID_0 #define TZ_OS_KS_RESTORE_KEY_CONFIG_ID \ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x06) #define TZ_OS_KS_RESTORE_KEY_CONFIG_ID_PARAM_ID \ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL) #define ICE_REV(x, y) (((x) & ICE_CORE_##y##_REV_MASK) >> ICE_CORE_##y##_REV) #define QCOM_UFS_ICE_DEV "iceufs" #define QCOM_SDCC_ICE_DEV "icesdcc" Loading Loading @@ -830,6 +838,24 @@ static int qcom_ice_restore_config(void) return ret; } static int qcom_ice_restore_key_config(void) { struct scm_desc desc = {0}; int ret = -1; /* For ice 3, key configuration needs to be restored in case of reset */ desc.arginfo = TZ_OS_KS_RESTORE_KEY_CONFIG_ID_PARAM_ID; desc.args[0] = 10; /* UFS_ICE */ ret = scm_call2(TZ_OS_KS_RESTORE_KEY_CONFIG_ID, &desc); if (ret) pr_err("%s: Error: 0x%x\n", __func__, ret); return ret; } static int qcom_ice_init_clocks(struct ice_device *ice) { int ret = -EINVAL; Loading Loading @@ -1103,6 +1129,22 @@ static int qcom_ice_finish_power_collapse(struct ice_device *ice_dev) err = -EFAULT; goto out; } /* * ICE looses its key configuration when UFS is reset, * restore it */ } else if (ICE_REV(ice_dev->ice_hw_version, MAJOR) > 2) { err = qcom_ice_restore_key_config(); if (err) goto out; /* * for PFE case, clear the cached ICE key table, * this will force keys to be reconfigured * per each next transaction */ pfk_clear_on_reset(); } } Loading include/linux/pfk.h +5 −1 Original line number Diff line number Diff line /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -24,6 +24,7 @@ int pfk_load_key_start(const struct bio *bio, int pfk_load_key_end(const struct bio *bio, bool *is_pfe); int pfk_remove_key(const unsigned char *key, size_t key_size); bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2); void pfk_clear_on_reset(void); #else static inline int pfk_load_key_start(const struct bio *bio, Loading @@ -48,6 +49,9 @@ static inline bool pfk_allow_merge_bio(const struct bio *bio1, return true; } static inline void pfk_clear_on_reset(void) {} #endif /* CONFIG_PFK */ #endif /* PFK_H */ security/pfe/pfk.c +13 −1 Original line number Diff line number Diff line /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -476,6 +476,18 @@ bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2) return (*(pfk_allow_merge_bio_ftable[which_pfe1]))(bio1, bio2, inode1, inode2); } /** * Flush key table on storage core reset. During core reset key configuration * is lost in ICE. We need to flash the cache, so that the keys will be * reconfigured again for every subsequent transaction */ void pfk_clear_on_reset(void) { if (!pfk_is_ready()) return; pfk_kc_clear_on_reset(); } module_init(pfk_init); module_exit(pfk_exit); Loading security/pfe/pfk_kc.c +24 −0 Original line number Diff line number Diff line Loading @@ -826,3 +826,27 @@ out: return res; } /** * pfk_kc_clear_on_reset() - clear the table and remove all keys from ICE * The assumption is that at this point we don't have any pending transactions * Also, there is no need to clear keys from ICE * * Return 0 on success, error otherwise * */ void pfk_kc_clear_on_reset(void) { struct kc_entry *entry = NULL; int i = 0; if (!kc_is_ready()) return; kc_spin_lock(); for (i = 0; i < PFK_KC_TABLE_SIZE; i++) { entry = kc_entry_at_index(i); kc_clear_entry(entry); } kc_spin_unlock(); } security/pfe/pfk_kc.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -26,6 +26,7 @@ int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size, const unsigned char *salt, size_t salt_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); Loading Loading
drivers/crypto/msm/ice.c +42 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/pfk.h> #include <crypto/ice.h> #include <soc/qcom/scm.h> #include <soc/qcom/qseecomi.h> #include "iceregs.h" #define TZ_SYSCALL_CREATE_SMC_ID(o, s, f) \ Loading @@ -40,6 +41,13 @@ #define TZ_OS_KS_RESTORE_KEY_ID_PARAM_ID \ TZ_SYSCALL_CREATE_PARAM_ID_0 #define TZ_OS_KS_RESTORE_KEY_CONFIG_ID \ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_KEYSTORE, 0x06) #define TZ_OS_KS_RESTORE_KEY_CONFIG_ID_PARAM_ID \ TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL) #define ICE_REV(x, y) (((x) & ICE_CORE_##y##_REV_MASK) >> ICE_CORE_##y##_REV) #define QCOM_UFS_ICE_DEV "iceufs" #define QCOM_SDCC_ICE_DEV "icesdcc" Loading Loading @@ -830,6 +838,24 @@ static int qcom_ice_restore_config(void) return ret; } static int qcom_ice_restore_key_config(void) { struct scm_desc desc = {0}; int ret = -1; /* For ice 3, key configuration needs to be restored in case of reset */ desc.arginfo = TZ_OS_KS_RESTORE_KEY_CONFIG_ID_PARAM_ID; desc.args[0] = 10; /* UFS_ICE */ ret = scm_call2(TZ_OS_KS_RESTORE_KEY_CONFIG_ID, &desc); if (ret) pr_err("%s: Error: 0x%x\n", __func__, ret); return ret; } static int qcom_ice_init_clocks(struct ice_device *ice) { int ret = -EINVAL; Loading Loading @@ -1103,6 +1129,22 @@ static int qcom_ice_finish_power_collapse(struct ice_device *ice_dev) err = -EFAULT; goto out; } /* * ICE looses its key configuration when UFS is reset, * restore it */ } else if (ICE_REV(ice_dev->ice_hw_version, MAJOR) > 2) { err = qcom_ice_restore_key_config(); if (err) goto out; /* * for PFE case, clear the cached ICE key table, * this will force keys to be reconfigured * per each next transaction */ pfk_clear_on_reset(); } } Loading
include/linux/pfk.h +5 −1 Original line number Diff line number Diff line /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -24,6 +24,7 @@ int pfk_load_key_start(const struct bio *bio, int pfk_load_key_end(const struct bio *bio, bool *is_pfe); int pfk_remove_key(const unsigned char *key, size_t key_size); bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2); void pfk_clear_on_reset(void); #else static inline int pfk_load_key_start(const struct bio *bio, Loading @@ -48,6 +49,9 @@ static inline bool pfk_allow_merge_bio(const struct bio *bio1, return true; } static inline void pfk_clear_on_reset(void) {} #endif /* CONFIG_PFK */ #endif /* PFK_H */
security/pfe/pfk.c +13 −1 Original line number Diff line number Diff line /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -476,6 +476,18 @@ bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2) return (*(pfk_allow_merge_bio_ftable[which_pfe1]))(bio1, bio2, inode1, inode2); } /** * Flush key table on storage core reset. During core reset key configuration * is lost in ICE. We need to flash the cache, so that the keys will be * reconfigured again for every subsequent transaction */ void pfk_clear_on_reset(void) { if (!pfk_is_ready()) return; pfk_kc_clear_on_reset(); } module_init(pfk_init); module_exit(pfk_exit); Loading
security/pfe/pfk_kc.c +24 −0 Original line number Diff line number Diff line Loading @@ -826,3 +826,27 @@ out: return res; } /** * pfk_kc_clear_on_reset() - clear the table and remove all keys from ICE * The assumption is that at this point we don't have any pending transactions * Also, there is no need to clear keys from ICE * * Return 0 on success, error otherwise * */ void pfk_kc_clear_on_reset(void) { struct kc_entry *entry = NULL; int i = 0; if (!kc_is_ready()) return; kc_spin_lock(); for (i = 0; i < PFK_KC_TABLE_SIZE; i++) { entry = kc_entry_at_index(i); kc_clear_entry(entry); } kc_spin_unlock(); }
security/pfe/pfk_kc.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -26,6 +26,7 @@ int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size, const unsigned char *salt, size_t salt_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); Loading