88 *
99 */
1010
11+ #include <asm/unaligned.h>
12+ #include <crypto/aes.h>
13+ #include <linux/arm-smccc.h>
1114#include <linux/clk.h>
1215#include <linux/delay.h>
1316#include <linux/module.h>
2528
2629#include "ufs-exynos.h"
2730
31+ #define DATA_UNIT_SIZE 4096
32+
2833/*
2934 * Exynos's Vendor specific registers for UFSHCI
3035 */
3136#define HCI_TXPRDT_ENTRY_SIZE 0x00
3237#define PRDT_PREFECT_EN BIT(31)
33- #define PRDT_SET_SIZE (x ) ((x) & 0x1F)
3438#define HCI_RXPRDT_ENTRY_SIZE 0x04
3539#define HCI_1US_TO_CNT_VAL 0x0C
3640#define CNT_VAL_1US_MASK 0x3FF
@@ -1043,8 +1047,8 @@ static int exynos_ufs_post_link(struct ufs_hba *hba)
10431047 exynos_ufs_fit_aggr_timeout (ufs );
10441048
10451049 hci_writel (ufs , 0xa , HCI_DATA_REORDER );
1046- hci_writel (ufs , PRDT_SET_SIZE ( 12 ), HCI_TXPRDT_ENTRY_SIZE );
1047- hci_writel (ufs , PRDT_SET_SIZE ( 12 ), HCI_RXPRDT_ENTRY_SIZE );
1050+ hci_writel (ufs , ilog2 ( DATA_UNIT_SIZE ), HCI_TXPRDT_ENTRY_SIZE );
1051+ hci_writel (ufs , ilog2 ( DATA_UNIT_SIZE ), HCI_RXPRDT_ENTRY_SIZE );
10481052 hci_writel (ufs , (1 << hba -> nutrs ) - 1 , HCI_UTRL_NEXUS_TYPE );
10491053 hci_writel (ufs , (1 << hba -> nutmrs ) - 1 , HCI_UTMRL_NEXUS_TYPE );
10501054 hci_writel (ufs , 0xf , HCI_AXIDMA_RWDATA_BURST_LEN );
@@ -1151,6 +1155,227 @@ static inline void exynos_ufs_priv_init(struct ufs_hba *hba,
11511155 hba -> quirks = ufs -> drv_data -> quirks ;
11521156}
11531157
1158+ #ifdef CONFIG_SCSI_UFS_CRYPTO
1159+
1160+ /*
1161+ * Support for Flash Memory Protector (FMP), which is the inline encryption
1162+ * hardware on Exynos and Exynos-based SoCs. The interface to this hardware is
1163+ * not compatible with the standard UFS crypto. It requires that encryption be
1164+ * configured in the PRDT using a nonstandard extension.
1165+ */
1166+
1167+ enum fmp_crypto_algo_mode {
1168+ FMP_BYPASS_MODE = 0 ,
1169+ FMP_ALGO_MODE_AES_CBC = 1 ,
1170+ FMP_ALGO_MODE_AES_XTS = 2 ,
1171+ };
1172+ enum fmp_crypto_key_length {
1173+ FMP_KEYLEN_256BIT = 1 ,
1174+ };
1175+
1176+ /**
1177+ * struct fmp_sg_entry - nonstandard format of PRDT entries when FMP is enabled
1178+ *
1179+ * @base: The standard PRDT entry, but with nonstandard bitfields in the high
1180+ * bits of the 'size' field, i.e. the last 32-bit word. When these
1181+ * nonstandard bitfields are zero, the data segment won't be encrypted or
1182+ * decrypted. Otherwise they specify the algorithm and key length with
1183+ * which the data segment will be encrypted or decrypted.
1184+ * @file_iv: The initialization vector (IV) with all bytes reversed
1185+ * @file_enckey: The first half of the AES-XTS key with all bytes reserved
1186+ * @file_twkey: The second half of the AES-XTS key with all bytes reserved
1187+ * @disk_iv: Unused
1188+ * @reserved: Unused
1189+ */
1190+ struct fmp_sg_entry {
1191+ struct ufshcd_sg_entry base ;
1192+ __be64 file_iv [2 ];
1193+ __be64 file_enckey [4 ];
1194+ __be64 file_twkey [4 ];
1195+ __be64 disk_iv [2 ];
1196+ __be64 reserved [2 ];
1197+ };
1198+
1199+ #define SMC_CMD_FMP_SECURITY \
1200+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
1201+ ARM_SMCCC_OWNER_SIP, 0x1810)
1202+ #define SMC_CMD_SMU \
1203+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
1204+ ARM_SMCCC_OWNER_SIP, 0x1850)
1205+ #define SMC_CMD_FMP_SMU_RESUME \
1206+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
1207+ ARM_SMCCC_OWNER_SIP, 0x1860)
1208+ #define SMU_EMBEDDED 0
1209+ #define SMU_INIT 0
1210+ #define CFG_DESCTYPE_3 3
1211+
1212+ static void exynos_ufs_fmp_init (struct ufs_hba * hba , struct exynos_ufs * ufs )
1213+ {
1214+ struct blk_crypto_profile * profile = & hba -> crypto_profile ;
1215+ struct arm_smccc_res res ;
1216+ int err ;
1217+
1218+ /*
1219+ * Check for the standard crypto support bit, since it's available even
1220+ * though the rest of the interface to FMP is nonstandard.
1221+ *
1222+ * This check should have the effect of preventing the driver from
1223+ * trying to use FMP on old Exynos SoCs that don't have FMP.
1224+ */
1225+ if (!(ufshcd_readl (hba , REG_CONTROLLER_CAPABILITIES ) &
1226+ MASK_CRYPTO_SUPPORT ))
1227+ return ;
1228+
1229+ /*
1230+ * The below sequence of SMC calls to enable FMP can be found in the
1231+ * downstream driver source for gs101 and other Exynos-based SoCs. It
1232+ * is the only way to enable FMP that works on SoCs such as gs101 that
1233+ * don't make the FMP registers accessible to Linux. It probably works
1234+ * on other Exynos-based SoCs too, and might even still be the only way
1235+ * that works. But this hasn't been properly tested, and this code is
1236+ * mutually exclusive with exynos_ufs_config_smu(). So for now only
1237+ * enable FMP support on SoCs with EXYNOS_UFS_OPT_UFSPR_SECURE.
1238+ */
1239+ if (!(ufs -> opts & EXYNOS_UFS_OPT_UFSPR_SECURE ))
1240+ return ;
1241+
1242+ /*
1243+ * This call (which sets DESCTYPE to 0x3 in the FMPSECURITY0 register)
1244+ * is needed to make the hardware use the larger PRDT entry size.
1245+ */
1246+ BUILD_BUG_ON (sizeof (struct fmp_sg_entry ) != 128 );
1247+ arm_smccc_smc (SMC_CMD_FMP_SECURITY , 0 , SMU_EMBEDDED , CFG_DESCTYPE_3 ,
1248+ 0 , 0 , 0 , 0 , & res );
1249+ if (res .a0 ) {
1250+ dev_warn (hba -> dev ,
1251+ "SMC_CMD_FMP_SECURITY failed on init: %ld. Disabling FMP support.\n" ,
1252+ res .a0 );
1253+ return ;
1254+ }
1255+ ufshcd_set_sg_entry_size (hba , sizeof (struct fmp_sg_entry ));
1256+
1257+ /*
1258+ * This is needed to initialize FMP. Without it, errors occur when
1259+ * inline encryption is used.
1260+ */
1261+ arm_smccc_smc (SMC_CMD_SMU , SMU_INIT , SMU_EMBEDDED , 0 , 0 , 0 , 0 , 0 , & res );
1262+ if (res .a0 ) {
1263+ dev_err (hba -> dev ,
1264+ "SMC_CMD_SMU(SMU_INIT) failed: %ld. Disabling FMP support.\n" ,
1265+ res .a0 );
1266+ return ;
1267+ }
1268+
1269+ /* Advertise crypto capabilities to the block layer. */
1270+ err = devm_blk_crypto_profile_init (hba -> dev , profile , 0 );
1271+ if (err ) {
1272+ /* Only ENOMEM should be possible here. */
1273+ dev_err (hba -> dev , "Failed to initialize crypto profile: %d\n" ,
1274+ err );
1275+ return ;
1276+ }
1277+ profile -> max_dun_bytes_supported = AES_BLOCK_SIZE ;
1278+ profile -> dev = hba -> dev ;
1279+ profile -> modes_supported [BLK_ENCRYPTION_MODE_AES_256_XTS ] =
1280+ DATA_UNIT_SIZE ;
1281+
1282+ /* Advertise crypto support to ufshcd-core. */
1283+ hba -> caps |= UFSHCD_CAP_CRYPTO ;
1284+
1285+ /* Advertise crypto quirks to ufshcd-core. */
1286+ hba -> quirks |= UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE |
1287+ UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE |
1288+ UFSHCD_QUIRK_KEYS_IN_PRDT ;
1289+
1290+ }
1291+
1292+ static void exynos_ufs_fmp_resume (struct ufs_hba * hba )
1293+ {
1294+ struct arm_smccc_res res ;
1295+
1296+ arm_smccc_smc (SMC_CMD_FMP_SECURITY , 0 , SMU_EMBEDDED , CFG_DESCTYPE_3 ,
1297+ 0 , 0 , 0 , 0 , & res );
1298+ if (res .a0 )
1299+ dev_err (hba -> dev ,
1300+ "SMC_CMD_FMP_SECURITY failed on resume: %ld\n" , res .a0 );
1301+
1302+ arm_smccc_smc (SMC_CMD_FMP_SMU_RESUME , 0 , SMU_EMBEDDED , 0 , 0 , 0 , 0 , 0 ,
1303+ & res );
1304+ if (res .a0 )
1305+ dev_err (hba -> dev ,
1306+ "SMC_CMD_FMP_SMU_RESUME failed: %ld\n" , res .a0 );
1307+ }
1308+
1309+ static inline __be64 fmp_key_word (const u8 * key , int j )
1310+ {
1311+ return cpu_to_be64 (get_unaligned_le64 (
1312+ key + AES_KEYSIZE_256 - (j + 1 ) * sizeof (u64 )));
1313+ }
1314+
1315+ /* Fill the PRDT for a request according to the given encryption context. */
1316+ static int exynos_ufs_fmp_fill_prdt (struct ufs_hba * hba ,
1317+ const struct bio_crypt_ctx * crypt_ctx ,
1318+ void * prdt , unsigned int num_segments )
1319+ {
1320+ struct fmp_sg_entry * fmp_prdt = prdt ;
1321+ const u8 * enckey = crypt_ctx -> bc_key -> raw ;
1322+ const u8 * twkey = enckey + AES_KEYSIZE_256 ;
1323+ u64 dun_lo = crypt_ctx -> bc_dun [0 ];
1324+ u64 dun_hi = crypt_ctx -> bc_dun [1 ];
1325+ unsigned int i ;
1326+
1327+ /* If FMP wasn't enabled, we shouldn't get any encrypted requests. */
1328+ if (WARN_ON_ONCE (!(hba -> caps & UFSHCD_CAP_CRYPTO )))
1329+ return - EIO ;
1330+
1331+ /* Configure FMP on each segment of the request. */
1332+ for (i = 0 ; i < num_segments ; i ++ ) {
1333+ struct fmp_sg_entry * prd = & fmp_prdt [i ];
1334+ int j ;
1335+
1336+ /* Each segment must be exactly one data unit. */
1337+ if (prd -> base .size != cpu_to_le32 (DATA_UNIT_SIZE - 1 )) {
1338+ dev_err (hba -> dev ,
1339+ "data segment is misaligned for FMP\n" );
1340+ return - EIO ;
1341+ }
1342+
1343+ /* Set the algorithm and key length. */
1344+ prd -> base .size |= cpu_to_le32 ((FMP_ALGO_MODE_AES_XTS << 28 ) |
1345+ (FMP_KEYLEN_256BIT << 26 ));
1346+
1347+ /* Set the IV. */
1348+ prd -> file_iv [0 ] = cpu_to_be64 (dun_hi );
1349+ prd -> file_iv [1 ] = cpu_to_be64 (dun_lo );
1350+
1351+ /* Set the key. */
1352+ for (j = 0 ; j < AES_KEYSIZE_256 / sizeof (u64 ); j ++ ) {
1353+ prd -> file_enckey [j ] = fmp_key_word (enckey , j );
1354+ prd -> file_twkey [j ] = fmp_key_word (twkey , j );
1355+ }
1356+
1357+ /* Increment the data unit number. */
1358+ dun_lo ++ ;
1359+ if (dun_lo == 0 )
1360+ dun_hi ++ ;
1361+ }
1362+ return 0 ;
1363+ }
1364+
1365+ #else /* CONFIG_SCSI_UFS_CRYPTO */
1366+
1367+ static void exynos_ufs_fmp_init (struct ufs_hba * hba , struct exynos_ufs * ufs )
1368+ {
1369+ }
1370+
1371+ static void exynos_ufs_fmp_resume (struct ufs_hba * hba )
1372+ {
1373+ }
1374+
1375+ #define exynos_ufs_fmp_fill_prdt NULL
1376+
1377+ #endif /* !CONFIG_SCSI_UFS_CRYPTO */
1378+
11541379static int exynos_ufs_init (struct ufs_hba * hba )
11551380{
11561381 struct device * dev = hba -> dev ;
@@ -1198,6 +1423,8 @@ static int exynos_ufs_init(struct ufs_hba *hba)
11981423
11991424 exynos_ufs_priv_init (hba , ufs );
12001425
1426+ exynos_ufs_fmp_init (hba , ufs );
1427+
12011428 if (ufs -> drv_data -> drv_init ) {
12021429 ret = ufs -> drv_data -> drv_init (dev , ufs );
12031430 if (ret ) {
@@ -1213,7 +1440,7 @@ static int exynos_ufs_init(struct ufs_hba *hba)
12131440 if (!(ufs -> opts & EXYNOS_UFS_OPT_UFSPR_SECURE ))
12141441 exynos_ufs_config_smu (ufs );
12151442
1216- hba -> host -> dma_alignment = SZ_4K - 1 ;
1443+ hba -> host -> dma_alignment = DATA_UNIT_SIZE - 1 ;
12171444 return 0 ;
12181445
12191446out :
@@ -1332,7 +1559,7 @@ static int exynos_ufs_hce_enable_notify(struct ufs_hba *hba,
13321559 * (ufshcd_async_scan()). Note: this callback may also be called
13331560 * from other functions than ufshcd_init().
13341561 */
1335- hba -> host -> max_segment_size = SZ_4K ;
1562+ hba -> host -> max_segment_size = DATA_UNIT_SIZE ;
13361563
13371564 if (ufs -> drv_data -> pre_hce_enable ) {
13381565 ret = ufs -> drv_data -> pre_hce_enable (ufs );
@@ -1432,7 +1659,7 @@ static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
14321659 phy_power_on (ufs -> phy );
14331660
14341661 exynos_ufs_config_smu (ufs );
1435-
1662+ exynos_ufs_fmp_resume ( hba );
14361663 return 0 ;
14371664}
14381665
@@ -1698,6 +1925,7 @@ static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
16981925 .hibern8_notify = exynos_ufs_hibern8_notify ,
16991926 .suspend = exynos_ufs_suspend ,
17001927 .resume = exynos_ufs_resume ,
1928+ .fill_crypto_prdt = exynos_ufs_fmp_fill_prdt ,
17011929};
17021930
17031931static struct ufs_hba_variant_ops ufs_hba_exynosauto_vh_ops = {
0 commit comments