{"id":62058,"date":"2025-05-09T12:08:42","date_gmt":"2025-05-09T10:08:42","guid":{"rendered":"https:\/\/www.inovex.de\/?p=62058"},"modified":"2025-05-09T12:08:42","modified_gmt":"2025-05-09T10:08:42","slug":"tpm-yocto-linux-edge-security","status":"publish","type":"post","link":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/","title":{"rendered":"Protecting MQTT Communication and Device Data via Trusted Platform Module"},"content":{"rendered":"<p>Wherever connected devices are utilized, it is essential to pay special attention to security. It is crucial to assess the existing risks in order to implement appropriate measures. A device that is publicly accessible, such as a surveillance camera, requires more careful consideration than a device that is physically secured and accessible only to authorized personnel.<\/p>\n<p>This article examines a project that employed a Trusted Platform Module <a href=\"https:\/\/trustedcomputinggroup.org\/resource\/trusted-platform-module-tpm-summary\">(TPM)<\/a> to mitigate the assessed security risks. A Trusted Platform Module serves a multitude of important use cases that enhance device security. It can generate, securely store, and manage cryptographic keys, providing a robust foundation for data protection. Additionally, a TPM is capable to verify the integrity of software and firmware during the boot process, ensuring that only authentic and untampered components are loaded. By establishing secure boot environments, it safeguards the system from potential threats right from startup. Furthermore, the TPM plays a vital role in authentication and attestation, enabling devices to prove their identity and integrity, thereby confirming that they are indeed what they claim to be.<!--more--><\/p>\n<p>The following sections will detail the setup, the challenges encountered, and the chosen solution.<br \/>\nAdditionally, it will illustrate how to integrate the TPM into Yocto and provide general guidance on working with the TPM.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\"><\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Initial-Situation\" >Initial Situation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Approach\" >Approach<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Serial-number\" >Serial number<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#MQTT\" >MQTT<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Provisioning\" >Provisioning<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Hands-on-Yocto\" >Hands on Yocto<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Hands-on-TPM\" >Hands on TPM<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Store-serial-number-in-NV-space\" >Store serial number in NV space<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#How-to-define-a-NV-space\" >How to define a NV space<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#How-to-write-to-the-NV-space\" >How to write to the NV space<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#How-to-read-the-NV-space\" >How to read the NV space<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Create-key-pairs-for-exchanging-MQTT-credentials\" >Create key pairs for exchanging MQTT credentials<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Create-RSA-Key-for-encryption-and-decryption-CLI\" >Create RSA Key for encryption and decryption (CLI)<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Encryption\" >Encryption<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Decryption\" >Decryption<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Get-public-key-from-persistent-handle\" >Get public key from persistent handle<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#Summary\" >Summary<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Initial-Situation\"><\/span>Initial Situation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The hardware in use is a custom development based on the Raspberry Pi Compute Module 4. This hardware functions as an edge device, designed to facilitate both local and cloud access. External hardware is connected to the edge device, utilizing protocols such as Modbus TCP or Modbus RTU. To support these functionalities, the edge device is equipped with the necessary hardware modules.<\/p>\n<p>The connection to the cloud is established via MQTT. All locally generated data is synchronized with the cloud using this protocol. Device settings can be configured both locally and through the cloud interface.<\/p>\n<p>Local access to the device is difficult for unauthorized individuals. The edge device is typically located on the premises and is additionally secured within a restricted area. If someone were to gain physical access, the potential breach of the edge device would be the least of the concerns (a matter of weighing risks). However, the connection to the cloud and external access must be restricted and secured.<\/p>\n<p>Key data of the system:<\/p>\n<p>Hardware: Custom hardware based on Raspberry Pi Compute Module 4<br \/>\nOperating System: Yocto Linux (Kirkstone &#8211; by the time of writing this article)<br \/>\nUpdate mechanism: AB updates (Mender)<br \/>\nPartitioning: 2x rootfs (AB), 1x data partition, which is not affected by updates, read-only rootfs, no execute flag for data partition<br \/>\nTPM: Infineon SLB9670<\/p>\n<p>There are two key issues that need to be addressed:<\/p>\n<ol>\n<li>Serial Number Storage: Each device has a unique serial number that must be stored securely. It is essential that this serial number remains intact through factory resets, system updates, and even after a full flash of the storage. Consequently, it cannot be stored within the device&#8217;s storage itself.<\/li>\n<li>MQTT Credentials: The device requires MQTT credentials from the Cloud, which must be encrypted for secure transmission. It is important to note that each device will have its own distinct MQTT credentials.<\/li>\n<\/ol>\n<h2><span class=\"ez-toc-section\" id=\"Approach\"><\/span>Approach<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"Serial-number\"><\/span>Serial number<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>A TPM offers the possibility to store the serial number in non-volatile (NV) space during the device provisioning process. This method ensures that the serial number remains intact through factory resets, updates, and even a full flash of the storage. Furthermore, the serial number is accessible to everyone since it is not stored in an encrypted format. To prevent accidental overwriting, it should incorporate some form of write protection. However, it is important to note that with root access, it remains possible to delete the serial number and reset it. How to define the NV space and how to store the serial number is explained in detail in the Chapter Store serial number in NV space.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"MQTT\"><\/span>MQTT<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Since we are having a read-only rootfs and a no-execute flag on the <em>\/data<\/em> partition, this offers the possibility to encrypt a password with a public key or a TPM key and store this file on the <em>\/data<\/em> partition. Only the TPM can decrypt this password, since the private key is kept safe and cannot be extracted from the TPM. Furthermore, the TPM can only be accessed with root permissions, and the only application that is able to interact with the TPM is our own. The attacker has to obtain root access to get the password, but in this case the attacker has a lot of other possibilities, which might be way more interesting for him.<\/p>\n<p>The following diagram illustrates the simplified communication between the edge device and the cloud during the initial boot. An additional authentication step is involved, but is not depicted here. For simplicity, envision that during provisioning, the serial number is briefly activated on the cloud side to facilitate the registration process.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-62106 aligncenter\" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/communication_provisioning-300x211.png\" alt=\"\" width=\"730\" height=\"513\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/communication_provisioning-300x211.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/communication_provisioning-400x281.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/communication_provisioning-360x253.png 360w, https:\/\/www.inovex.de\/wp-content\/uploads\/communication_provisioning.png 701w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Provisioning\"><\/span>Provisioning<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Understanding the provisioning process of a device is essential, and the following key steps are involved:<\/p>\n<ul>\n<li>The serial number is automatically written to the NV storage of the TPM.<\/li>\n<li>The Yocto image is automatically flashed onto the device.<\/li>\n<li>The device undergoes automated testing to ensure, among other things, that the externally connected hardware is functioning properly.<\/li>\n<li>The device is registered in the cloud. At the time of writing, this process was partially automated, requiring a manual step to accept the device on the cloud side.<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Hands-on-Yocto\"><\/span>Hands on Yocto<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This chapter outlines the necessary adjustments to Yocto for supporting the TPM.<br \/>\nGiven our custom hardware, we have introduced a new machine configuration based on the Raspberry Pi Compute Module 4 configuration. This machine configuration details all hardware-related aspects that differ from the Compute Module 4, providing an ideal location to incorporate the requirements for the TPM.<\/p>\n<p>The extension of the machine configuration file is as follows:<\/p>\n<pre>MACHINE_FEATURES:append = \"tpm2\"\r\n\r\nRPI_EXTRA_CONFIG += \"dtoverlay=slb9670-tpm\"\r\nRPI_KERNEL_DEVICETREE_OVERLAYS += \" \\\r\n  overlays\/slb9670-tpm.dtbo \\\r\n\"\r\n\r\n# TPM stuff\r\nIMAGE_INSTALL:append = \" tpm2-tools libtss2 libtss2-tcti-device tpm2-abrmd tpm2-pkcs11\"<\/pre>\n<p>Since our custom hardware supports the tpm2 feature set, this is set as <em>MACHINE_FEATURE<\/em>.<\/p>\n<p>The operating system requires accurate information on how to interact with the TPM. To facilitate this, a Device Tree Overlay is necessary, as it provides the essential details about the additional hardware. For the overlay to be loaded during the device&#8217;s boot process, it must be included in the <em>config.txt<\/em> file (specific to Raspberry Pi). This is achieved by appending the name of the Device Tree Overlay to the <em>RPI_EXTRA_CONFIG<\/em> setting.<\/p>\n<p>Additionally, several packages are required to effectively use and interact with the TPM from a user or application perspective (IMAGE_INSTALL). For instance, <em>tpm2-tools<\/em> installs all tpm2 commands in the <em>\/usr\/bin<\/em> directory. To enable the installation of these packages, it is essential to add the <a href=\"\/\/git.yoctoproject.org\/meta-security\">meta-security<\/a> layer to the <em>bblayers.conf<\/em> file.<\/p>\n<p>The device tree overlay looks like the following:<\/p>\n<pre>\/dts-v1\/;\r\n\/plugin\/;\r\n\r\n\/ {\r\n\u00a0\u00a0\u00a0 compatible = \"brcm,bcm2835\", \"brcm,bcm2708\", \"brcm,bcm2709\";\r\n\r\n\u00a0\u00a0\u00a0 fragment@0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 target = &lt;&amp;gpio&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __overlay__ {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 spi1_pins: spi1_pins {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 brcm,pins = &lt;19 20 21&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 brcm,function = &lt;3&gt;; \/* alt4 *\/\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 spi1_cs_pins: spi1_cs_pins {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 brcm,pins = &lt;18&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 brcm,function = &lt;1&gt;; \/* output *\/\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\u00a0\u00a0\u00a0 };\r\n\r\n\u00a0\u00a0\u00a0 fragment@1 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 target = &lt;&amp;spi1&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 frag1: __overlay__ {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/* needed to avoid dtc warning *\/\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #address-cells = &lt;1&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #size-cells = &lt;0&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pinctrl-names = \"default\";\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pinctrl-0 = &lt;&amp;spi1_pins &amp;spi1_cs_pins&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #address-cells = &lt;1&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #size-cells = &lt;0&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pinctrl-names = \"default\";\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pinctrl-0 = &lt;&amp;spi1_pins &amp;spi1_cs_pins&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cs-gpios = &lt;&amp;gpio 18 1&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 status = \"okay\";\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 slb9670: slb9670@0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 compatible = \"infineon,slb9670\";\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 reg = &lt;0&gt;; \/* CE0 *\/\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #address-cells = &lt;1&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #size-cells = &lt;0&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 spi-max-frequency = &lt;32000000&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 status = \"okay\";\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\u00a0\u00a0\u00a0 };\r\n\r\n\u00a0\u00a0\u00a0 fragment@2 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 target = &lt;&amp;aux&gt;;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __overlay__ {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 status = \"okay\";\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\u00a0\u00a0\u00a0 };\r\n\r\n\u00a0\u00a0\u00a0 __overrides__ {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cs0_pin\u00a0 = &lt;&amp;spi1_cs_pins&gt;,\"brcm,pins:0\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;&amp;frag1&gt;,\"cs-gpios:4\";\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cs0_slb9670 = &lt;&amp;slb9670&gt;,\"status\";\r\n\u00a0\u00a0\u00a0 };\r\n};<\/pre>\n<p>The Device Tree Overlay is primarily based on the one provided by <a href=\"https:\/\/www.infineon.com\/cms\/en\/product\/security-smart-card-solutions\/optiga-embedded-security-solutions\/optiga-tpm\/slb-9670vq2.0\/\">Infineon<\/a>, with minor adjustments, such as setting the chip select to 1 for this specific hardware. This configuration may vary depending on your hardware design. Furthermore, the TPM is connected to the Serial Peripheral Interface of the Raspberry Pi, utilizing GPIO pins 18-21, which is also reflected in the <a href=\"https:\/\/www.kernel.org\/doc\/Documentation\/devicetree\/usage-model.txt\">Device Tree Overlay<\/a>.<\/p>\n<p>To incorporate the Device Tree Overlay, the <em>linux-raspberrypi<\/em> recipe must be extended using a <em>.bbappend<\/em> file (named <em>linux-raspberrypi_%.bbappend<\/em>):<\/p>\n<pre class=\"\">FILESEXTRAPATHS:prepend := \"${THISDIR}\/${PN}:\"\r\n\r\nSRC_URI += \"file:\/\/slb9670-tpm.dts;subdir=git\/arch\/${ARCH}\/boot\/dts\/overlays\"<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Hands-on-TPM\"><\/span>Hands on TPM<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"Store-serial-number-in-NV-space\"><\/span>Store serial number in NV space<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This chapter details the process of storing the serial number in NV space using CLI commands on the device. In our setup, this operation is performed automatically via script during the provisioning of each device.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"How-to-define-a-NV-space\"><\/span>How to define a NV space<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>In order to store the serial number of the device a NV storage space needs to be defined.<br \/>\nThis space should be only writable once to prevent that it will be accidentally overwritten by the application. The serial number is written during the provisioning of the device. The NV space can be deleted with root access which offers the possibility to change the serial number (e.g. for refurbishing).<\/p>\n<p>First, an authorization session is initiated to establish a policy using <em>TPM2_CC_NV_Write<\/em>, which ensures that the NV space can only be written <a href=\"https:\/\/github.com\/tpm2-software\/tpm2-tools\/blob\/master\/man\/tpm2_policynvwritten.1.md\">once<\/a>. This policy is then saved in the <em>nvwrite.policy<\/em> file.<\/p>\n<pre class=\"\">tpm2_startauthsession -S \/data\/session.dat\r\ntpm2_policycommandcode -S \/data\/session.dat TPM2_CC_NV_Write\r\ntpm2_policynvwritten -S \/data\/session.dat -L \/data\/nvwrite.policy c\r\ntpm2_flushcontext \/data\/session.dat<\/pre>\n<p>The \u201cc\u201c at the end of <em>tpm2_policynvwritten<\/em> is not a typo; it is an argument that signifies the expected written state of the NV index. In this case, &#8222;c&#8220; represents a clear state.<\/p>\n<p>Occasionally, it is advisable to flush the context to prevent the TPM from running out of transient memory. This can be accomplished using the <em>tpm2_flushcontext<\/em> command.<\/p>\n<p>The nv space is then defined via:<\/p>\n<pre class=\"\">tpm2_nvdefine -s 20 -a \"ownerread|authread|policywrite\" -L \/data\/nvwrite.policy\r\n    Output: nv-index: 0x1000000<\/pre>\n<ul>\n<li>-s = size in bytes<\/li>\n<li>-L = policy file<\/li>\n<li>-a = attributes\n<ul>\n<li>policywrite: A policy is required in order to write to this space.<\/li>\n<li>authread: Authentication, e.g. a password, is required for reading. However, in this instance, the password is not provided; therefore, reading can be performed without a password.<\/li>\n<li>ownerread: The TPM owner can read the data from nv space.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The output of this command is the NV index that is utilized, typically the next available index. In our scenario, the first usable address is 0x1000000.<\/p>\n<p>The result of this can be seen via <em>tpm2_nvreadpublic<\/em>:<\/p>\n<pre class=\"\">0x1000000:\r\n  name: 000b6e9b58189207e920b30f65b06b9933aabf823f3ed063e8824602c0c465d13f7d\r\n  hash algorithm:\r\n    friendly: sha256\r\n    value: 0xB\r\n  attributes:\r\n    friendly: policywrite|ownerread|authread\r\n    value: 0x8000420\r\n  size: 20\r\n  authorization policy: B7AFECEE9BF7BCBD5078F264DE85F7E361DC84F745DA7EFA34E91FDAF200EE9B<\/pre>\n<h4><span class=\"ez-toc-section\" id=\"How-to-write-to-the-NV-space\"><\/span>How to write to the NV space<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>First a policy session has to be initiated again with the <em>TPM2_CC_NV_Write<\/em> command code.<\/p>\n<pre class=\"\">tpm2_startauthsession -S \/data\/session.dat --policy-session\r\ntpm2_policycommandcode -S \/data\/session.dat TPM2_CC_NV_Write\r\ntpm2_policynvwritten -S \/data\/session.dat c<\/pre>\n<p>Afterwards the NV space can be written once via:<\/p>\n<pre class=\"\">tpm2_nvwrite 0x1000000 -i testWrite.txt -P session:\/data\/session.dat<\/pre>\n<p>The contents of <em>testWrite.txt<\/em> will be written to address 0x1000000. It is important that the file size does not exceed the defined NV space size, which in this case is 20 bytes (as noted in the previous chapter). A policy session can be specified using the -P option.<\/p>\n<p>As a result, the <em>written<\/em> attribute is now set, and any further write operations will be denied (as confirmed by <em>tpm2_nvreadpublic<\/em>):<\/p>\n<pre class=\"\">0x1000000:\r\n  name: 000b6e9b58189207e920b30f65b06b9933aabf823f3ed063e8824602c0c465d13f7d\r\n  hash algorithm:\r\n    friendly: sha256\r\n    value: 0xB\r\n  attributes:\r\n    friendly: policywrite|ownerread|authread|written\r\n    value: 0x8000420\r\n  size: 20\r\n  authorization policy: B7AFECEE9BF7BCBD5078F264DE85F7E361DC84F745DA7EFA34E91FDAF200EE9B<\/pre>\n<p>If an attempt is made to write to this NV space again, the following error message will be displayed:<\/p>\n<pre class=\"\">WARNING:esys:..\/tpm2-tss-3.2.0\/src\/tss2-esys\/api\/Esys_NV_Write.c:310:Esys_NV_Write_Finish() Received TPM Error\r\nERROR:esys:..\/tpm2-tss-3.2.0\/src\/tss2-esys\/api\/Esys_NV_Write.c:110:Esys_NV_Write() Esys Finish ErrorCode (0x0000099d)\r\nERROR: Failed to write NV area at index 0x1000000\r\nERROR: Tss2_Sys_NV_Write(0x99D) - tpm:session(1):a policy check failed\r\nERROR: Unable to run tpm2_nvwrite<\/pre>\n<h4><span class=\"ez-toc-section\" id=\"How-to-read-the-NV-space\"><\/span>How to read the NV space<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>The read command is straightforward compared to the write command, as anyone is permitted to access this space.<\/p>\n<pre class=\"\">tpm2_nvread -C o 0x1000000 -s 20\r\n    Output: `hello`<\/pre>\n<ul>\n<li>-s = size in bytes<\/li>\n<li>-C = context from which the read operation is performed. o refers to the owner context of the TPM.<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Create-key-pairs-for-exchanging-MQTT-credentials\"><\/span>Create key pairs for exchanging MQTT credentials<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This chapter outlines the <a href=\"https:\/\/github.com\/tpm2-software\/tpm2-openssl\/blob\/master\/test\/rsa_create_decrypt_pkcs1.sh\">process<\/a> of generating an RSA key pair for the encryption and decryption of MQTT credentials via CLI commands. In our setup, the key pair is generated by the application during the initial boot.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Create-RSA-Key-for-encryption-and-decryption-CLI\"><\/span>Create RSA Key for encryption and decryption (CLI)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The initial command, <em>tpm2_createprimary<\/em>, is used to create a primary key under the owner hierarchy (default). This command generates a context file, saved as <em>primary.ctx<\/em>, which facilitates further interactions with the TPM. Given that the TPM is not a particularly powerful computing unit, this process may take some time\u2014approximately 35 seconds in our setup.<\/p>\n<pre class=\"\"># create primary key - can take up some time (in this setup about 35 seconds)\r\ntpm2_createprimary -c primary.ctx\r\n\r\n# create a default key\r\ntpm2_create -C primary.ctx -u key.pub -r key.priv\r\n(Remark: key.pub and key.priv are encrypted with an internal symmetric key of the TPM)\r\n\r\n# load the key\r\ntpm2_load -C primary.ctx -u key.pub -r key.priv -c testkey.ctx\r\n\r\n# make the key persistent (handle looks like the follwoing: 0x81000001)\r\nHANDLE=$(tpm2_evictcontrol -c testkey.ctx | cut -d ' ' -f 2 | head -n 1)<\/pre>\n<p>Subsequently, a default key is generated using <em>tpm2_create<\/em>. This key pair is then loaded with <em>tpm2_load<\/em>, producing a <em>testkey.ctx<\/em> file that can be utilized for encryption and decryption.<\/p>\n<p>Keys can be recreated with the TPM, and using the same sequence and parameters will yield identical results, allowing for the consistent regeneration of this key pair whenever needed. To optimize this process, the key can be made persistent using <em>tpm2_evictcontrol<\/em>. This action results in a handle that can be employed for future interactions.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Encryption\"><\/span>Encryption<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>The encryption of, for example, the content of a .txt file can be accomplished using <em>tpm2_rsaencrypt<\/em>:<\/p>\n<pre class=\"\">tpm2_rsaencrypt -c 0x81000000 -o encryptedFile secret.txt<\/pre>\n<p>The first parameter specifies the address of the persistent handle, while the second parameter indicates the output destination. In this instance, the encrypted data is saved to a file named <em>encryptedFile<\/em> in the current directory. The file <em>secret.txt<\/em> contains plain text, such as \u201chello world,\u201c which will be encrypted using the public key of the key pair.<\/p>\n<p>After executing the command, the <em>encryptedFile<\/em> will not contain any readable text, for example:<\/p>\n<pre class=\"\">\/p\ufffd&lt;\ufffd\ufffd\/\ufffd\ufffd\ufffd\u0733;*\ufffd\ufffd\ufffd\ufffd\ufffd!\ufffd\ufffdt\ufffdS.\ufffd&amp;\ufffds\ufffdBo\ufffd\ufffd\ufffd\r\n\ufffd4\ufffd\u02b7\ufffdf\ufffd\ufffdu\ufffd\ufffd'\ufffdjEY3\ufffd&gt;\ufffd`\r\n\ufffd\ufffd\ufffd(\ufffd!\ufffd;s<\/pre>\n<h4><span class=\"ez-toc-section\" id=\"Decryption\"><\/span>Decryption<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>A decryption can be accomplished using <em>tpm2_rsadecrypt<\/em>:<\/p>\n<pre class=\"\">tpm2_rsadecrypt -c 0x81000000 -o decryptedFile encryptedFile<\/pre>\n<p>The first parameter specifies the address of the persistent handle, which remains the same as for encryption. The second parameter indicates the output destination. In this case, the previously encrypted file will serve as input for decryption, and the output will be saved to a file named <em>decryptedFile<\/em>.<\/p>\n<h4><span class=\"ez-toc-section\" id=\"Get-public-key-from-persistent-handle\"><\/span>Get public key from persistent handle<span class=\"ez-toc-section-end\"><\/span><\/h4>\n<p>The public key has to be transferred to the Cloud in order to encrypt the MQTT credentials e.g. via openssl.<\/p>\n<p>It can be extracted using the following <a href=\"https:\/\/github.com\/tpm2-software\/tpm2-tools\/blob\/master\/man\/tpm2_readpublic.1.md\">method<\/a>:<\/p>\n<pre class=\"\">tpm2_readpublic -c ${HANDLE} -o testkey.pub -f pem<\/pre>\n<ul>\n<li>${HANDLE} represents the persistent handle (stored via <em>tpm2_evictcontrol<\/em>, see previous chapter)<\/li>\n<\/ul>\n<p>The public key is stored in <em>testkey.pub<\/em> and has the following format:<\/p>\n<pre class=\"\">-----BEGIN PUBLIC KEY-----\r\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsVkcoRJWeCRiAJrUSgUL\r\nO0a+s1Ye5S+hdqb7roxC+POEBRXp\/nfbO8Hl2ImSf9G1\/\/GaaO9D7uxB\/gBzMwCU\r\na09ijtGsAuDtBCi12TOAUXEpMlBlVMw0\/VrSPQS2pZ3pdweX6ROWcScKRxdpZ9vB\r\nfI\/bXgEgRQB2hyFG4QHavfpLXQ34+JcppSZmVg\/QDYsAohfPKjLMMOfrdLKUG2BE\r\nvsUSH4Aa0Qydm3mo1XMp8qzgRkP+snnxFeZA78mHXKDLgrwwcLuoQnR1As6r6G35\r\nbU0lmoCMYq0ZpzLl8eUoeN6uydQQH3fC2FUvi13hndDPsDfzA9d78y0f9uQuW2dZ\r\nLwIDAQAB\r\n-----END PUBLIC KEY-----<\/pre>\n<p>In order to encrypt with openssl the command looks like the following:<\/p>\n<pre class=\"\">openssl pkeyutl -encrypt -pubin -inkey testkey.pub -in secret.txt -out encryptedFile<\/pre>\n<p>The MQTT credentials encrypted with OpenSSL can be decrypted directly on the device using <em>tpm2_rsadecrypt<\/em>. There is no need to utilize OpenSSL for the decryption process.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In this article, we explored how to utilize a TPM for securely storing a serial number in NV storage, ensuring its persistence through factory resets, system updates, and even complete storage flashes. We also discussed how to leverage a TPM to encrypt MQTT credentials for secure transmission between the device and the cloud, as well as the integration of a TPM into the Yocto environment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wherever connected devices are utilized, it is essential to pay special attention to security. It is crucial to assess the existing risks in order to implement appropriate measures. A device that is publicly accessible, such as a surveillance camera, requires more careful consideration than a device that is physically secured and accessible only to authorized [&hellip;]<\/p>\n","protected":false},"author":431,"featured_media":62257,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"ep_exclude_from_search":false,"footnotes":""},"tags":[],"service":[505,504],"coauthors":[{"id":431,"display_name":"Alexander Dahmen","user_nicename":"adahmen"}],"class_list":["post-62058","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","service-embedded-systems","service-search"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>TPM on Yocto Linux: Edge Security in Practice<\/title>\n<meta name=\"description\" content=\"Explore a real-world example of using TPM with Yocto Linux to secure serial numbers, credentials, and device integrity in edge computing.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"TPM on Yocto Linux: Edge Security in Practice\" \/>\n<meta property=\"og:description\" content=\"Explore a real-world example of using TPM with Yocto Linux to secure serial numbers, credentials, and device integrity in edge computing.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/\" \/>\n<meta property=\"og:site_name\" content=\"inovex GmbH\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/inovexde\" \/>\n<meta property=\"article:published_time\" content=\"2025-05-09T10:08:42+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1496\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Alexander Dahmen\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-1024x598.png\" \/>\n<meta name=\"twitter:creator\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:site\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alexander Dahmen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"14\u00a0Minuten\" \/>\n\t<meta name=\"twitter:label3\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data3\" content=\"Alexander Dahmen\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/\"},\"author\":{\"name\":\"Alexander Dahmen\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/253d1d8a60a80df6268c7a831e83733b\"},\"headline\":\"Protecting MQTT Communication and Device Data via Trusted Platform Module\",\"datePublished\":\"2025-05-09T10:08:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/\"},\"wordCount\":2196,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png\",\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/\",\"url\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/\",\"name\":\"TPM on Yocto Linux: Edge Security in Practice\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png\",\"datePublished\":\"2025-05-09T10:08:42+00:00\",\"description\":\"Explore a real-world example of using TPM with Yocto Linux to secure serial numbers, credentials, and device integrity in edge computing.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#primaryimage\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png\",\"width\":2560,\"height\":1496,\"caption\":\"Grafische Darstellung eines eingebetteten Trusted Platform Modules (TPM). Links ist ein Computerger\u00e4t mit einem Schloss-Symbol abgebildet, das Sicherheit und Schutz darstellt. Rechts ist eine transparente Box zu sehen, die m\u00f6glicherweise ein TPM repr\u00e4sentiert, aus der kleine Blasen aufsteigen.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.inovex.de\/de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Protecting MQTT Communication and Device Data via Trusted Platform Module\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.inovex.de\/de\/#website\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"name\":\"inovex GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.inovex.de\/de\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\",\"name\":\"inovex GmbH\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"width\":1921,\"height\":1081,\"caption\":\"inovex GmbH\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/inovexde\",\"https:\/\/x.com\/inovexgmbh\",\"https:\/\/www.instagram.com\/inovexlife\/\",\"https:\/\/www.linkedin.com\/company\/inovex\",\"https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/253d1d8a60a80df6268c7a831e83733b\",\"name\":\"Alexander Dahmen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/97f5c71e4fd8d7dc814efe6faef17f61\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1220f0bdce3dacb15e1513473baa0affcfda91fe9662be038485fee923f39da7?s=96&d=retro&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1220f0bdce3dacb15e1513473baa0affcfda91fe9662be038485fee923f39da7?s=96&d=retro&r=g\",\"caption\":\"Alexander Dahmen\"},\"url\":\"https:\/\/www.inovex.de\/de\/blog\/author\/adahmen\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"TPM on Yocto Linux: Edge Security in Practice","description":"Explore a real-world example of using TPM with Yocto Linux to secure serial numbers, credentials, and device integrity in edge computing.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/","og_locale":"de_DE","og_type":"article","og_title":"TPM on Yocto Linux: Edge Security in Practice","og_description":"Explore a real-world example of using TPM with Yocto Linux to secure serial numbers, credentials, and device integrity in edge computing.","og_url":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/","og_site_name":"inovex GmbH","article_publisher":"https:\/\/www.facebook.com\/inovexde","article_published_time":"2025-05-09T10:08:42+00:00","og_image":[{"width":2560,"height":1496,"url":"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png","type":"image\/png"}],"author":"Alexander Dahmen","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-1024x598.png","twitter_creator":"@inovexgmbh","twitter_site":"@inovexgmbh","twitter_misc":{"Verfasst von":"Alexander Dahmen","Gesch\u00e4tzte Lesezeit":"14\u00a0Minuten","Written by":"Alexander Dahmen"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#article","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/"},"author":{"name":"Alexander Dahmen","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/253d1d8a60a80df6268c7a831e83733b"},"headline":"Protecting MQTT Communication and Device Data via Trusted Platform Module","datePublished":"2025-05-09T10:08:42+00:00","mainEntityOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/"},"wordCount":2196,"commentCount":0,"publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png","inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/","url":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/","name":"TPM on Yocto Linux: Edge Security in Practice","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#primaryimage"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png","datePublished":"2025-05-09T10:08:42+00:00","description":"Explore a real-world example of using TPM with Yocto Linux to secure serial numbers, credentials, and device integrity in edge computing.","breadcrumb":{"@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#primaryimage","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/Embedded_TPM-scaled.png","width":2560,"height":1496,"caption":"Grafische Darstellung eines eingebetteten Trusted Platform Modules (TPM). Links ist ein Computerger\u00e4t mit einem Schloss-Symbol abgebildet, das Sicherheit und Schutz darstellt. Rechts ist eine transparente Box zu sehen, die m\u00f6glicherweise ein TPM repr\u00e4sentiert, aus der kleine Blasen aufsteigen."},{"@type":"BreadcrumbList","@id":"https:\/\/www.inovex.de\/de\/blog\/tpm-yocto-linux-edge-security\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.inovex.de\/de\/"},{"@type":"ListItem","position":2,"name":"Protecting MQTT Communication and Device Data via Trusted Platform Module"}]},{"@type":"WebSite","@id":"https:\/\/www.inovex.de\/de\/#website","url":"https:\/\/www.inovex.de\/de\/","name":"inovex GmbH","description":"","publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.inovex.de\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.inovex.de\/de\/#organization","name":"inovex GmbH","url":"https:\/\/www.inovex.de\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","width":1921,"height":1081,"caption":"inovex GmbH"},"image":{"@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/inovexde","https:\/\/x.com\/inovexgmbh","https:\/\/www.instagram.com\/inovexlife\/","https:\/\/www.linkedin.com\/company\/inovex","https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ"]},{"@type":"Person","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/253d1d8a60a80df6268c7a831e83733b","name":"Alexander Dahmen","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/97f5c71e4fd8d7dc814efe6faef17f61","url":"https:\/\/secure.gravatar.com\/avatar\/1220f0bdce3dacb15e1513473baa0affcfda91fe9662be038485fee923f39da7?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1220f0bdce3dacb15e1513473baa0affcfda91fe9662be038485fee923f39da7?s=96&d=retro&r=g","caption":"Alexander Dahmen"},"url":"https:\/\/www.inovex.de\/de\/blog\/author\/adahmen\/"}]}},"_links":{"self":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/62058","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/users\/431"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/comments?post=62058"}],"version-history":[{"count":5,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/62058\/revisions"}],"predecessor-version":[{"id":62268,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/62058\/revisions\/62268"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media\/62257"}],"wp:attachment":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media?parent=62058"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/tags?post=62058"},{"taxonomy":"service","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/service?post=62058"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/coauthors?post=62058"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}