@@ -1282,6 +1282,220 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
12821282}
12831283EXPORT_SYMBOL_GPL (qcom_scm_ice_set_key );
12841284
1285+ bool qcom_scm_has_wrapped_key_support (void )
1286+ {
1287+ return __qcom_scm_is_call_available (__scm -> dev , QCOM_SCM_SVC_ES ,
1288+ QCOM_SCM_ES_DERIVE_SW_SECRET ) &&
1289+ __qcom_scm_is_call_available (__scm -> dev , QCOM_SCM_SVC_ES ,
1290+ QCOM_SCM_ES_GENERATE_ICE_KEY ) &&
1291+ __qcom_scm_is_call_available (__scm -> dev , QCOM_SCM_SVC_ES ,
1292+ QCOM_SCM_ES_PREPARE_ICE_KEY ) &&
1293+ __qcom_scm_is_call_available (__scm -> dev , QCOM_SCM_SVC_ES ,
1294+ QCOM_SCM_ES_IMPORT_ICE_KEY );
1295+ }
1296+ EXPORT_SYMBOL_GPL (qcom_scm_has_wrapped_key_support );
1297+
1298+ /**
1299+ * qcom_scm_derive_sw_secret() - Derive software secret from wrapped key
1300+ * @eph_key: an ephemerally-wrapped key
1301+ * @eph_key_size: size of @eph_key in bytes
1302+ * @sw_secret: output buffer for the software secret
1303+ * @sw_secret_size: size of the software secret to derive in bytes
1304+ *
1305+ * Derive a software secret from an ephemerally-wrapped key for software crypto
1306+ * operations. This is done by calling into the secure execution environment,
1307+ * which then calls into the hardware to unwrap and derive the secret.
1308+ *
1309+ * For more information on sw_secret, see the "Hardware-wrapped keys" section of
1310+ * Documentation/block/inline-encryption.rst.
1311+ *
1312+ * Return: 0 on success; -errno on failure.
1313+ */
1314+ int qcom_scm_derive_sw_secret (const u8 * eph_key , size_t eph_key_size ,
1315+ u8 * sw_secret , size_t sw_secret_size )
1316+ {
1317+ struct qcom_scm_desc desc = {
1318+ .svc = QCOM_SCM_SVC_ES ,
1319+ .cmd = QCOM_SCM_ES_DERIVE_SW_SECRET ,
1320+ .arginfo = QCOM_SCM_ARGS (4 , QCOM_SCM_RW , QCOM_SCM_VAL ,
1321+ QCOM_SCM_RW , QCOM_SCM_VAL ),
1322+ .owner = ARM_SMCCC_OWNER_SIP ,
1323+ };
1324+ int ret ;
1325+
1326+ void * eph_key_buf __free (qcom_tzmem ) = qcom_tzmem_alloc (__scm -> mempool ,
1327+ eph_key_size ,
1328+ GFP_KERNEL );
1329+ if (!eph_key_buf )
1330+ return - ENOMEM ;
1331+
1332+ void * sw_secret_buf __free (qcom_tzmem ) = qcom_tzmem_alloc (__scm -> mempool ,
1333+ sw_secret_size ,
1334+ GFP_KERNEL );
1335+ if (!sw_secret_buf )
1336+ return - ENOMEM ;
1337+
1338+ memcpy (eph_key_buf , eph_key , eph_key_size );
1339+ desc .args [0 ] = qcom_tzmem_to_phys (eph_key_buf );
1340+ desc .args [1 ] = eph_key_size ;
1341+ desc .args [2 ] = qcom_tzmem_to_phys (sw_secret_buf );
1342+ desc .args [3 ] = sw_secret_size ;
1343+
1344+ ret = qcom_scm_call (__scm -> dev , & desc , NULL );
1345+ if (!ret )
1346+ memcpy (sw_secret , sw_secret_buf , sw_secret_size );
1347+
1348+ memzero_explicit (eph_key_buf , eph_key_size );
1349+ memzero_explicit (sw_secret_buf , sw_secret_size );
1350+ return ret ;
1351+ }
1352+ EXPORT_SYMBOL_GPL (qcom_scm_derive_sw_secret );
1353+
1354+ /**
1355+ * qcom_scm_generate_ice_key() - Generate a wrapped key for storage encryption
1356+ * @lt_key: output buffer for the long-term wrapped key
1357+ * @lt_key_size: size of @lt_key in bytes. Must be the exact wrapped key size
1358+ * used by the SoC.
1359+ *
1360+ * Generate a key using the built-in HW module in the SoC. The resulting key is
1361+ * returned wrapped with the platform-specific Key Encryption Key.
1362+ *
1363+ * Return: 0 on success; -errno on failure.
1364+ */
1365+ int qcom_scm_generate_ice_key (u8 * lt_key , size_t lt_key_size )
1366+ {
1367+ struct qcom_scm_desc desc = {
1368+ .svc = QCOM_SCM_SVC_ES ,
1369+ .cmd = QCOM_SCM_ES_GENERATE_ICE_KEY ,
1370+ .arginfo = QCOM_SCM_ARGS (2 , QCOM_SCM_RW , QCOM_SCM_VAL ),
1371+ .owner = ARM_SMCCC_OWNER_SIP ,
1372+ };
1373+ int ret ;
1374+
1375+ void * lt_key_buf __free (qcom_tzmem ) = qcom_tzmem_alloc (__scm -> mempool ,
1376+ lt_key_size ,
1377+ GFP_KERNEL );
1378+ if (!lt_key_buf )
1379+ return - ENOMEM ;
1380+
1381+ desc .args [0 ] = qcom_tzmem_to_phys (lt_key_buf );
1382+ desc .args [1 ] = lt_key_size ;
1383+
1384+ ret = qcom_scm_call (__scm -> dev , & desc , NULL );
1385+ if (!ret )
1386+ memcpy (lt_key , lt_key_buf , lt_key_size );
1387+
1388+ memzero_explicit (lt_key_buf , lt_key_size );
1389+ return ret ;
1390+ }
1391+ EXPORT_SYMBOL_GPL (qcom_scm_generate_ice_key );
1392+
1393+ /**
1394+ * qcom_scm_prepare_ice_key() - Re-wrap a key with the per-boot ephemeral key
1395+ * @lt_key: a long-term wrapped key
1396+ * @lt_key_size: size of @lt_key in bytes
1397+ * @eph_key: output buffer for the ephemerally-wrapped key
1398+ * @eph_key_size: size of @eph_key in bytes. Must be the exact wrapped key size
1399+ * used by the SoC.
1400+ *
1401+ * Given a long-term wrapped key, re-wrap it with the per-boot ephemeral key for
1402+ * added protection. The resulting key will only be valid for the current boot.
1403+ *
1404+ * Return: 0 on success; -errno on failure.
1405+ */
1406+ int qcom_scm_prepare_ice_key (const u8 * lt_key , size_t lt_key_size ,
1407+ u8 * eph_key , size_t eph_key_size )
1408+ {
1409+ struct qcom_scm_desc desc = {
1410+ .svc = QCOM_SCM_SVC_ES ,
1411+ .cmd = QCOM_SCM_ES_PREPARE_ICE_KEY ,
1412+ .arginfo = QCOM_SCM_ARGS (4 , QCOM_SCM_RO , QCOM_SCM_VAL ,
1413+ QCOM_SCM_RW , QCOM_SCM_VAL ),
1414+ .owner = ARM_SMCCC_OWNER_SIP ,
1415+ };
1416+ int ret ;
1417+
1418+ void * lt_key_buf __free (qcom_tzmem ) = qcom_tzmem_alloc (__scm -> mempool ,
1419+ lt_key_size ,
1420+ GFP_KERNEL );
1421+ if (!lt_key_buf )
1422+ return - ENOMEM ;
1423+
1424+ void * eph_key_buf __free (qcom_tzmem ) = qcom_tzmem_alloc (__scm -> mempool ,
1425+ eph_key_size ,
1426+ GFP_KERNEL );
1427+ if (!eph_key_buf )
1428+ return - ENOMEM ;
1429+
1430+ memcpy (lt_key_buf , lt_key , lt_key_size );
1431+ desc .args [0 ] = qcom_tzmem_to_phys (lt_key_buf );
1432+ desc .args [1 ] = lt_key_size ;
1433+ desc .args [2 ] = qcom_tzmem_to_phys (eph_key_buf );
1434+ desc .args [3 ] = eph_key_size ;
1435+
1436+ ret = qcom_scm_call (__scm -> dev , & desc , NULL );
1437+ if (!ret )
1438+ memcpy (eph_key , eph_key_buf , eph_key_size );
1439+
1440+ memzero_explicit (lt_key_buf , lt_key_size );
1441+ memzero_explicit (eph_key_buf , eph_key_size );
1442+ return ret ;
1443+ }
1444+ EXPORT_SYMBOL_GPL (qcom_scm_prepare_ice_key );
1445+
1446+ /**
1447+ * qcom_scm_import_ice_key() - Import key for storage encryption
1448+ * @raw_key: the raw key to import
1449+ * @raw_key_size: size of @raw_key in bytes
1450+ * @lt_key: output buffer for the long-term wrapped key
1451+ * @lt_key_size: size of @lt_key in bytes. Must be the exact wrapped key size
1452+ * used by the SoC.
1453+ *
1454+ * Import a raw key and return a long-term wrapped key. Uses the SoC's HWKM to
1455+ * wrap the raw key using the platform-specific Key Encryption Key.
1456+ *
1457+ * Return: 0 on success; -errno on failure.
1458+ */
1459+ int qcom_scm_import_ice_key (const u8 * raw_key , size_t raw_key_size ,
1460+ u8 * lt_key , size_t lt_key_size )
1461+ {
1462+ struct qcom_scm_desc desc = {
1463+ .svc = QCOM_SCM_SVC_ES ,
1464+ .cmd = QCOM_SCM_ES_IMPORT_ICE_KEY ,
1465+ .arginfo = QCOM_SCM_ARGS (4 , QCOM_SCM_RO , QCOM_SCM_VAL ,
1466+ QCOM_SCM_RW , QCOM_SCM_VAL ),
1467+ .owner = ARM_SMCCC_OWNER_SIP ,
1468+ };
1469+ int ret ;
1470+
1471+ void * raw_key_buf __free (qcom_tzmem ) = qcom_tzmem_alloc (__scm -> mempool ,
1472+ raw_key_size ,
1473+ GFP_KERNEL );
1474+ if (!raw_key_buf )
1475+ return - ENOMEM ;
1476+
1477+ void * lt_key_buf __free (qcom_tzmem ) = qcom_tzmem_alloc (__scm -> mempool ,
1478+ lt_key_size ,
1479+ GFP_KERNEL );
1480+ if (!lt_key_buf )
1481+ return - ENOMEM ;
1482+
1483+ memcpy (raw_key_buf , raw_key , raw_key_size );
1484+ desc .args [0 ] = qcom_tzmem_to_phys (raw_key_buf );
1485+ desc .args [1 ] = raw_key_size ;
1486+ desc .args [2 ] = qcom_tzmem_to_phys (lt_key_buf );
1487+ desc .args [3 ] = lt_key_size ;
1488+
1489+ ret = qcom_scm_call (__scm -> dev , & desc , NULL );
1490+ if (!ret )
1491+ memcpy (lt_key , lt_key_buf , lt_key_size );
1492+
1493+ memzero_explicit (raw_key_buf , raw_key_size );
1494+ memzero_explicit (lt_key_buf , lt_key_size );
1495+ return ret ;
1496+ }
1497+ EXPORT_SYMBOL_GPL (qcom_scm_import_ice_key );
1498+
12851499/**
12861500 * qcom_scm_hdcp_available() - Check if secure environment supports HDCP.
12871501 *
0 commit comments