@@ -1282,6 +1282,220 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
1282
1282
}
1283
1283
EXPORT_SYMBOL_GPL (qcom_scm_ice_set_key );
1284
1284
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
+
1285
1499
/**
1286
1500
* qcom_scm_hdcp_available() - Check if secure environment supports HDCP.
1287
1501
*
0 commit comments