Mistake on this page? Email us

Securing Pelion 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.

Pelion Edge uses Platfrom 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 Pelion Edge stack:

This document explains how to secure Pelion Edge with a TPM:

  1. Enable Parsec.
  2. Back up the software TPM contents.
  3. Verify the provider. (This document uses TPM 2.0.)
  4. 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 Pelion Edge in production mode.

With Pelion 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: Pelion Edge supports Parsec on LmP.

  1. To make Pelion 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.
  2. 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 console-image-lmp.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

  1. Provision the device.

  2. 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
    
  3. (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):

  1. Stop the Parsec service:

    sudo systemctl stop parsec
    tpm2_selftest -f
    sudo systemctl start parsec
    
  2. Run the TPM2 selftest.

Verify Parsec

To validate Parsec service functionality, use the Parsec Tool to read the keys stored in the TPM.

  1. 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
    
  2. 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 Pelion Edge uses) reports the default provider as Mbed Crypto instead of TPM.

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. Pelion Edge credentials stored inside TPM won't be readable and Edge won't be able to re-establish connection with the Pelion Device Management cloud. To resolve this, you must either:

    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:

    1. Provide the -T option relevant your setup.

    2. 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"