Securing Izuma Edge with the Trusted Platform Module (TPM)
We suggest you use a secure facility on the gateway that can manage, generate and securely store cryptographic keys to safeguard the data and ensure no unintended users gain access to it. One such hardware module is the Trusted Platform Module (TPM). If available, it is built into your computer's motherboard. After you enable it, the TPM provides full disk encryption capabilities and also becomes the "root of trust" for the system to provide integrity and authentication to the platform. To learn more about TPM specifications, please see the resource by the Trusted Computing Group, who first published the specification. Version 2.0 became a formal international standard under ISO/IEC.
Izuma Edge uses Platform Abstraction for Security (Parsec) to interface with the TPM. Parsec is an open-source initiative that provides a platform-agnostic interface for calling the secure storage and operation services of a TPM on Linux.
Parsec supports various hardware-backed secure facilities such as the Hardware Security Module (HSM), TPM and Trusted App (TA). To provide a single interface to the client applications, Parsec architecture defines a component called a provider, which brings abstraction and implements the API operations using platform- or vendor-specific code. The Parsec service can load one or more providers. This document uses hardware or software TPM provider version 2.
By default, these programs are available in the Izuma Edge stack:
This document explains how to secure Izuma Edge with a TPM:
- Enable Parsec.
- Back up the software TPM contents.
- Verify the provider. (This document uses TPM 2.0.)
- Verify Parsec.
Note: To secure containerized applications with Parsec, see the Securing containerized applications documentation.
Enable Parsec
Note: When you use Parsec and a TPM, you must use Izuma Edge in production mode.
With Izuma Edge, you can generate the device's bootstrap private key on a TPM during the factory flow. At run time, when the device calls the Device Management bootstrap server, Device Management Client calls the Parsec API and uses the bootstrap key as part of the DTLS handshake, without having to export the key.
Note: Izuma Edge supports Parsec on LmP.
-
To make Izuma Edge programs interface with Parsec service and the TPM, build the image with these flags:
MBED_EDGE_CORE_CONFIG_PARSEC_TPM_SE_SUPPORT = "ON" MBED_EDGE_CORE_CONFIG_FACTORY_MODE = "ON" MBED_EDGE_CORE_CONFIG_DEVELOPER_MODE = "OFF"
This modifies these services:
- Edge Core compiled with Parsec Secure Element driver.
- Factory Configurator Client Example (FCCE) compiled with Parsec Secure Element driver.
-
If your board supports hardware TPM, disable building the software TPM package
swtpm-service
.For example, in the LmP image, you can comment out this line from lmp-base-console-image.bb.
Note: Software TPM is not designed to be resilient against power failures. Instead of disconnecting the power supply to the gateway, always perform a graceful shutdown of the edge device when using TPM. For more details, please see the troubleshooting section.
Back up software TPM contents
-
Run:
sudo systemctl stop parsec sudo systemctl stop swtpm sudo cp /userdata/parsec/NVChip /userdata/parsec/NVChip.bak sudo systemctl start swtpm sudo systemctl start parsec
-
(Optional) Transfer the file
NVChip.bak
to an external USB drive or a network drive.
Verify TPM v2.0
To verify the functionality of the TPM (hardware or software):
-
Stop the Parsec service:
sudo systemctl stop parsec tpm2_selftest -f sudo systemctl start parsec
-
Run the TPM2 selftest.
Verify Parsec
To validate Parsec service functionality, use the Parsec Tool to read the keys stored in the TPM.
-
Run the
ping
command to make sure the logged-in user and the environment are configured correctly to reach the service:sudo parsec-tool ping
For example, successful output looks like this:
# parsec-tool ping [INFO ] Service wire protocol version 1.0
-
To read the keys from the TPM, run:
sudo parsec-tool list-keys
For example, if the bootstrap key is stored in the TPM, you see:
[INFO ] Available keys: * parsec-se-driver-key0 (Mbed Crypto provider, EccKeyPair { curve_family: SecpR1 }, 256 bits, permitted algorithm: AsymmetricSignature(Ecdsa { hash_alg: Specific(Sha256) }))
Note: A known issue in Parsec service 0.6.0 (which Izuma Edge uses) reports the default provider as
Mbed Crypto
instead ofTPM
.
Troubleshooting
-
On running Parsec, if you see the error
No such file or directory
:Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
Verify parameter
socket_path = "/run/parsec/parsec.sock"
is defined in the Parsec configuration file:/etc/parsec/config.toml
. -
If the Parsec service fails to start with this error:
Started Parsec Service. [INFO parsec] Parsec started. Configuring the service... [INFO parsec_service::utils::service_builder] Creating a TPM Provider. [INFO tss_esapi::context] Closing context. [INFO tss_esapi::context] Context closed. [TRACE parsec_service::providers::tpm] describe ingress [INFO parsec_service::providers::tpm] Dropping the TPM Provider. [INFO tss_esapi::context] Closing context. [INFO tss_esapi::context] Flushing handle 934984 [INFO tss_esapi::context] Flushing handle 934983 [INFO tss_esapi::context] Context closed. Error: Failed to bind to Unix socket at "/run/parsec/parsec.sock"
Verify the folder
/run/parsec
exists. -
If the contents of the software TPM in the
NVChip
file become corrupted, you'll see this error log from the Edge Core process:sudo journalctl -u edge-core -f May 19 20:22:02 imx8mmevk edge-core[964911]: [2021-05-19T20:22:02Z ERROR parsec_se_driver] Error setting the default authentication method (No such file or directory (os error 2)). May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.715 tid: 964911 [ERR ][fcc ]: psa_driver_crypto.c:244:psa_drv_crypto_init:<=== Failed to initialize crypto module May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.715 tid: 964911 [ERR ][fcc ]: psa_driver_common.c:50:psa_drv_translate_to_kcm_error:psa_status: -132, kcm_status: 0x1 May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.715 tid: 964911 [ERR ][fcc ]: key_slot_allocator.c:714:ksa_init:<=== Failed initializing PSA Crypto driver (1) May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.715 tid: 964911 [ERR ][fcc ]: storage_psa.cpp:1084:storage_init:<=== Failed initializing KSA (kcm_status 1) May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: key_config_manager.c:51:kcm_init:<=== Failed initializing storage May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: key_config_manager.c:161:kcm_item_get_data_size:<=== KCM initialization failed May 19 20:22:02 imx8mmevk edge-core[964911]: [2021-05-19T20:22:02Z ERROR parsec_se_driver] Error setting the default authentication method (No such file or directory (os error 2)). May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: psa_driver_crypto.c:244:psa_drv_crypto_init:<=== Failed to initialize crypto module May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: psa_driver_common.c:50:psa_drv_translate_to_kcm_error:psa_status: -132, kcm_status: 0x1 May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: key_slot_allocator.c:714:ksa_init:<=== Failed initializing PSA Crypto driver (1) May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: storage_psa.cpp:1084:storage_init:<=== Failed initializing KSA (kcm_status 1) May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: key_config_manager.c:51:kcm_init:<=== Failed initializing storage May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: key_config_manager.c:161:kcm_item_get_data_size:<=== KCM initialization failed May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: common_utils.c:50:fcc_get_kcm_data:<=== Failed to get kcm data size May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: fcc_verification.c:478:check_utc_offset:Failed to get utc data May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: fcc_verification.c:954:fcc_check_time_synchronization:<=== Failed in check_utc_offset May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.716 tid: 964911 [ERR ][fcc ]: factory_configurator_client.c:206:fcc_verify_device_configured_4mbed_cloud:<=== Failed to check time synhronization May 19 20:22:02 imx8mmevk edge-core[964911]: [2021-05-19T20:22:02Z ERROR parsec_se_driver] Error setting the default authentication method (No such file or directory (os error 2)). May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.717 tid: 964911 [ERR ][fcc ]: psa_driver_crypto.c:244:psa_drv_crypto_init:<=== Failed to initialize crypto module May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.717 tid: 964911 [ERR ][fcc ]: psa_driver_common.c:50:psa_drv_translate_to_kcm_error:psa_status: -132, kcm_status: 0x1 May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.717 tid: 964911 [ERR ][fcc ]: key_slot_allocator.c:714:ksa_init:<=== Failed initializing PSA Crypto driver (1) May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.717 tid: 964911 [ERR ][fcc ]: storage_psa.cpp:1084:storage_init:<=== Failed initializing KSA (kcm_status 1) May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.717 tid: 964911 [ERR ][fcc ]: key_config_manager.c:51:kcm_init:<=== Failed initializing storage May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.717 tid: 964911 [ERR ][fcc ]: key_config_manager.c:323:kcm_factory_reset:<=== KCM initialization failed May 19 20:22:02 imx8mmevk edge-core[964911]: 2021-05-19 20:22:02.717 tid: 964911 [ERR ][edgecc]: Failed to do factory reset - 1 - exit May 19 20:22:02 imx8mmevk systemd[1]: edge-core.service: Main process exited, code=exited, status=1/FAILURE May 19 20:22:02 imx8mmevk systemd[1]: edge-core.service: Failed with result 'exit-code'.
This indicates the power supply to the gateway has been disconnected. Software TPM is not designed to be resilient against power failures. If you disconnect the power supply to the gateway, the contents of the software TPM in the
NVChip
file might become corrupted. Izuma Edge credentials stored inside TPM won't be readable and Edge won't be able to re-establish connection with the Izuma Device Management cloud. To resolve this, you must either:- Reprovision the gateway.
- Take a copy of the NVChip file after provisiong and restore the copy on top of the corrupted one if the issue occurs.
Always do a graceful shutdown of your edge device when using software TPM.
-
If the TPM2 selftest fails with this error:
** (process:6409): CRITICAL **: failed to allocate dbus proxy object: Exhausted all available authentication mechanisms (tried: EXTERNAL, DBUS_COOKIE_SHA1, ANONYMOUS) (available: EXTERNAL, DBUS_COOKIE_SHA1, ANONYMOUS) WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for function 0x7f9d5c8fc60e failed with a0008 WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not initialize TCTI named: tcti-abrmd ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not initialize TCTI file: libtss2-tcti-tabrmd.so.0 ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init() Failed to open device file /dev/tpmrm0: No such file or directory WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for function 0x7f9d5af14cd0 failed with a000a WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not initialize TCTI named: tcti-device ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not initialize TCTI file: libtss2-tcti-device.so.0 ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init() Failed to open device file /dev/tpm0: Device or resource busy WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for function 0x7f9d5af14cd0 failed with a000a WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not initialize TCTI named: tcti-device ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not initialize TCTI file: libtss2-tcti-device.so.0 WARNING:tcti:src/util/io.c:252:socket_connect() Failed to connect to host 127.0.0.1, port 2321: errno 111: Connection refused WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for function 0x7f9d5af14230 failed with a000a WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not initialize TCTI named: tcti-socket ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not initialize TCTI file: libtss2-tcti-mssim.so.0 ERROR:tcti:src/tss2-tcti/tctildr-dl.c:248:tctildr_get_default() No standard TCTI could be loaded ERROR:tcti:src/tss2-tcti/tctildr.c:418:Tss2_TctiLdr_Initialize_Ex() Failed to instantiate TCTI ERROR: Could not load tcti, got: "(null)"
It means you are not using the TCTI defaults. To resolve this:
-
Provide the -T option relevant your setup.
-
Rerun the command.
For example, for software TPM v2.0:
tpm2_selftest -f -T mssim:host=127.0.0.1,port=2321
-
-
If you see this error when you verify Parsec:
# parsec-tool ping [ERROR] Error spinning up the BasicClient: the socket address provided in the URL is not valid
Define the following environment variable to provide the unix domain socket address to the tool:
export PARSEC_SERVICE_ENDPOINT="unix:/run/parsec/parsec.sock"