1. Overview
This Application Note describes how to use the ST ST33KTPM2X Trusted Platform Module (TPM) with Emcraft Systems' Linux BSP for the STM32MP1 SoC.
The ST33KTPM2X device is a member of the ST STSAFE-TPM (trusted platform module) family of products, which offers a broad portfolio of standardised solutions for embedded, PC, mobile and computing applications. The STSAFE-TPM includes turnkey products compliant with the Trusted Computing Group (TCG) standards that provide services to protect the confidentiality, integrity and authenticity of information and devices. The STSAFE-TPM devices are all Common Criteria (EAL4+) and FIPS certified.
The ST33KTPM2X is a TPM 2.0-compliant device, that is easy to integrate in an embedded design, using the standards-compliant SPI and I2C interfaces to the host SoC, such as the ST STM32MP1. Refer to the following page for detailed information of the ST33KTPM2X module: https://www.st.com/en/secure-mcus/st33ktpm2x.html .
The Emcraft Linux BSP for the STM32MP1 SoC has been enhanced with appropriate device drivers and configuration interfaces allowing seamless integration with the ST33KTPM2X device. This Application Note provides detailed instructions on the steps that are needed to enable software support for the STSAFE-TPM in Linux running on the STM32MP1 SoC.
2. Hardware Platform
The following hardware platform is used by Emcraft to support the ST STSAFE-TPM devices with the STM32MP1 SoC:
The Emcraft STM32MP1 SOM, available in the 800MHz and 650MHz variants. See: https://emcraft.com/products/1062#som .
The Emcraft STM32MP1-BSB Starter Kit, which provides, among other things, a standards-compliant interface to Click / mikroBUS boards. See https://emcraft.com/products/1062#starter-kit .
The Emcraft TPM-Click Module board, which is a compact Click / mikroBUS add-on board that hosts the ST ST33KTPM2X TPM 2.0-compliant module and provides the standard SPI / I2C interfaces to the host SoC. While Emcraft uses the Click board to illustrate integration with the STM32MP1 SoC, the board can be used with any embedded device that provides a standard Click / mikroBUS interface. See TPM-Click Module Hardware User’s Guide .
3. Software Platform
The following hardware platform is used by Emcraft to support the ST STSAFE-TPM devices with the STM32MP1 BSP (Board Support Package):
Kernel space device drivers. While the generic TPM2 support is enabled by
CONFIG_TCG_TPM
configuration parameter, Emcraft's TPM-Click Module board support is enabled byCONFIG_TCG_TIS_I2C
configuration parameter (making the I2C bus the default transport to the host). These configuration parameters enable building of the TPM2 drivers in the Linux kernel and reside in thedrivers/char/tpm
directory in the kernel source tree. The aforementioned drivers are enabled in the Emcraft BSP by default.User-space TPM stack including the
cryptsetup
utility in thesystemd
software suite,tpm2-tools
set of utilities (version 5.5), andtpm2-tss
shared library (version 4.0.1). The user space TPM stack is a part of the https://git.yoctoproject.org/git/meta-security Yocto layer.
4. Building STM32MP1 Images for STSAFE-TPM
Step through the following procedure to activate support for the STSAFE-TPM in the Emcraft BSP:
Prepare the Linux build host. See Linux PC requirements PC prerequisites - stm32mpu.
On the build host, set up the OpenSTLinux release 5.0.0 sources:
[psl@sergmir openstlinux]$ curl https://storage.googleapis.com/\ git-repo-downloads/repo > repo [psl@sergmir openstlinux]$ chmod 755 repo [psl@sergmir openstlinux]$ sudo mv repo /usr/bin [psl@sergmir openstlinux]$ repo init -u \ https://github.com/STMicroelectronics/oe-manifest.git \ -b refs/tags/openstlinux-6.1-yocto-mickledore-mp1-v23.06.21 ... [psl@sergmir openstlinux]$ repo sync ... [psl@sergmir openstlinux]$ ls -l total 4 drwxrwxr-x 7 psl psl 4096 Apr 18 18:37 layers [psl@sergmir openstlinux]$ ls -l layers/ total 20 drwxrwxr-x 14 psl psl 4096 Apr 18 18:37 meta-openembedded drwxrwxr-x 12 psl psl 4096 Apr 18 18:37 meta-qt5 drwxrwxr-x 6 psl psl 4096 Apr 18 18:37 meta-st drwxrwxr-x 6 psl psl 4096 Apr 18 18:37 meta-timesys drwxrwxr-x 9 psl psl 4096 Apr 18 18:37 openembedded-core [psl@sergmir openstlinux]$
Clone the Emcraft meta layer:
[psl@sergmir openstlinux]$ git clone -b linux-stm32mp1-4.1.0 \ git@gitlab.com:emcraft/stm32mp15x/meta-emcraft.git \ layers/meta-st/meta-emcraft ...
Clone the Secutiry meta layer:
[psl@sergmir openstlinux]$ git clone -b mickledore \ https://git.yoctoproject.org/git/meta-security \ layers/meta-security ...
Configure the build (change
stm32mp15-som
tostm32mp157d-som
in the below command for the 800MHz version of the STM32MP1-SOM):[psl@sergmir openstlinux]$ DISTRO=openstlinux-weston \ MACHINE=stm32mp157d-som source layers/meta-st/scripts/envsetup.sh ...
The STM32MP1 BSP depends on some packages and firmware covered by a software license agreement (SLA). You will be asked to read and to accept this license.
Enable the
tpm2
adsecurity
features:[psl@sergmir build-openstlinuxweston-stm32mp157d-som]$ echo 'DISTRO_FEATURES:append = " tpm2 security"' >> conf/local.conf
Run the build:
[psl@sergmir build-openstlinuxweston-stm32mp157d-som]$ bitbake emcraft-rootfs NOTE: Started PRServer with DBfile: /home/build/build-openstlinuxweston-stm32mp157d-som/cache/prserv.sqlite3, Address: 127.0.0.1:40257, PID: 173904 Loading cache: 100% | | ETA: --:--:-- Loaded 0 entries from dependency cache. NOTE: /home/build/layers/meta-st/meta-st-openstlinux/recipes-st/images/st-image-resize-initrd.bb: ENABLE_PARTITIONS_IMAGE not enabled################################################################# | ETA: 0:00:06 Parsing recipes: 100% |####################################################################################################################################################################################################################################################| Time: 0:00:23 Parsing of 3152 .bb files complete (0 cached, 3152 parsed). 4978 targets, 577 skipped, 0 masked, 0 errors. NOTE: Resolving any missing task queue dependencies Build Configuration: BB_VERSION = "2.4.0" BUILD_SYS = "x86_64-linux" NATIVELSBSTRING = "universal" TARGET_SYS = "arm-ostl-linux-gnueabi" MACHINE = "stm32mp157d-som" DISTRO = "openstlinux-weston" DISTRO_VERSION = "4.2.1-snapshot-20240124" TUNE_FEATURES = "arm vfp cortexa7 neon vfpv4 thumb callconvention-hard" TARGET_FPU = "hard" DISTRO_CODENAME = "mickledore" GCCVERSION = "12.%" PREFERRED_PROVIDER_virtual/kernel = "linux-stm32mp" meta-emcraft = "linux-stm32mp1-4.1.0:53460accc3c8c88ed91a7b2f9bf034300d12b705" meta-python meta-oe meta-gnome meta-initramfs meta-multimedia meta-networking meta-webserver meta-filesystems meta-perl = "HEAD:c032fd0b1a9d444711103c2703dfa8e2964a3865" meta-st-stm32mp = "HEAD:931b3f5be2c00f55d114c8f9122082a9d229b776" meta-qt5 = "HEAD:cf6ffcbad5275a3428f6046468a0c9d572e813d1" meta-security meta-tpm = "mickledore:d7db0a3bd1a8639df7570483f003ce00cbe274a2" meta-st-openstlinux = "HEAD:8c780facff81d3c3878c5fdcd18bdd24fc36478d" meta = "HEAD:20cd64812d286c920bd766145ab1cd968e72667e" ...
5. Verifying Support for STSAFE-TPM
5.1. Verifying STSAFE-TPM Configuration
Follow the step-wise procedure below to verify that the TPM module has been recognised and correctly configured on the target:
In the Linux boot-up messages, verify that the TPM driver has probed the TPM device:
root@stm32mp157d-som:~# dmesg | grep -i tpm [ 7.641100] systemd[1]: systemd 253.1^ running in system mode (+PAM -AUDIT -SELINUX -APPARMOR +IMA -SMACK -SECCOMP -GCRYPT -GNUTLS -OPENSSL -ACL +BLKID -CURL -ELFUTILS -FIDO2 -IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK -PCRE2 -PWQUALITY -P11KIT -QRENCODE +TPM2 -BZIP2 -LZ4 -XZ -ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=hybrid) [ 17.236238] tpm_tis_i2c 1-002e: 2.0 TPM (device-id 0x3, rev-id 1) [ 17.282843] tpm tpm0: A TPM error (256) occurred attempting the self test [ 17.293537] tpm tpm0: starting up the TPM manually
Check the TPM version:
root@stm32mp157d-som:~# cat /sys/class/tpm/tpm*/tpm_version_major 2
Check the TPM capabilities:
root@stm32mp157d-som:~# tpm2_getcap pcrs selected-pcrs: - sha1: [ ] - sha256: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ] - sha384: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ] - sha3_256: [ ] - sha3_384: [ ]
root@stm32mp157d-som:~# tpm2_getcap algorithms rsa: value: 0x1 asymmetric: 1 symmetric: 0 hash: 0 object: 1 reserved: 0x0 signing: 0 encrypting: 0 method: 0 sha1: value: 0x4 asymmetric: 0 symmetric: 0 hash: 1 object: 0 reserved: 0x0 signing: 0 encrypting: 0 method: 0 ...
root@stm32mp157d-som:~# tpm2_getcap ecc-curves TPM2_ECC_NIST_P256: 0x3 TPM2_ECC_NIST_P384: 0x4 TPM2_ECC_BN_P256: 0x10
root@stm32mp157d-som:~# tpm2_getcap commands TPM2_CC_NV_UndefineSpaceSpecial: value: 0x440011F commandIndex: 0x11f reserved1: 0x0 nv: 1 extensive: 0 flushed: 0 cHandles: 0x2 rHandle: 0 V: 0 Res: 0x0 TPM2_CC_EvictControl: value: 0x4400120 commandIndex: 0x120 reserved1: 0x0 nv: 1 extensive: 0 flushed: 0 cHandles: 0x2 rHandle: 0 V: 0 Res: 0x0 TPM2_CC_HierarchyControl: value: 0x2C00121 commandIndex: 0x121 reserved1: 0x0 nv: 1 extensive: 1 flushed: 0 cHandles: 0x1 rHandle: 0 V: 0 Res: 0x0 TPM2_CC_NV_UndefineSpace: value: 0x4400122 commandIndex: 0x122 reserved1: 0x0 nv: 1 extensive: 0 flushed: 0 cHandles: 0x2 rHandle: 0 V: 0 Res: 0x0 ...
5.2. Using STSAFE-TPM for Hardware-Bound Data Encryption
This command sequence showcases how to utilise the STSAFE-TPM to create a hardware-bound encrypted disk. Once the disk has been encrypted, the passphrase to unlock the disk is stored in the TPM’s NV storage, so the unlocking and decryption of the disk is only possible with the specific TPM chip being present on the embedded target.
5.2.1. Phase 1: Disk Creation
This phase creates the disk. Follow the step-wise procedure below:
Create an empty disk image:
root@stm32mp157d-som:~# truncate -s 20M disk.bin
Create a TPM-stored sealed key.
root@stm32mp157d-som:~# tpm2_createprimary -Q -C o -c prim.ctx -P ownerauth root@stm32mp157d-som:~# dd if=/dev/urandom bs=1 count=32 status=none | tpm2_create -Q -g sha256 -u seal.pub -r seal.priv -i- -C prim.ctx root@stm32mp157d-som:~# tpm2_load -Q -C prim.ctx -u seal.pub -r seal.priv -n seal.name -c seal.ctx root@stm32mp157d-som:~# tpm2_evictcontrol -C o -c seal.ctx 0x81010001 -P ownerauth persistent-handle: 0x81010001 action: persisted root@stm32mp157d-som:~# rm seal.ctx seal.name seal.priv seal.pub
Create the loop device for the disk image:
root@stm32mp157d-som:~# loopdev=$(losetup --show -f disk.bin) [ 1303.491018] loop0: detected capacity change from 0 to 40960 root@stm32mp157d-som:~# echo $loopdev /dev/loop0
Create a LUKS2-encrypted disk:
root@stm32mp157d-som:~# tpm2_unseal -Q -c 0x81010001 | cryptsetup luksFormat --type luks2 $loopdev
Unlock the created disk:
root@stm32mp157d-som:~# tpm2_unseal -Q -c 0x81010001 | cryptsetup open --type luks $loopdev mytest [ 1497.756506] device-mapper: ioctl: 4.47.0-ioctl (2022-07-28) initialised: dm-devel@redhat.com [ 1501.572598] cryptd: max_cpu_qlen set to 1000
Create the
ext4
file system on the disk.root@stm32mp157d-som:~# mkfs.ext4 /dev/mapper/mytest mke2fs 1.47.0 (5-Feb-2023) Creating filesystem with 4096 1k blocks and 1024 inodes Allocating group tables: done Writing inode tables: done Creating journal (1024 blocks): done Writing superblocks and filesystem accounting information: done
Mount the
ext4
file system:root@stm32mp157d-som:~# mount /dev/mapper/mytest /mnt/ [ 1649.709534] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Quota mode: disabled.
5.2.2. Phase 2: Verifying Disk Encryption
Now that the encrypted disk is created and the file system is mounted, we can create a file on it and verify if the data is indeed encrypted. Follow the step-wise procedure below:
Create a plain file with some text:
root@stm32mp157d-som:~# echo "LALALA, the data is encrypted!" > /mnt/test.txt
root@stm32mp157d-som:~# ls /mnt/ lost+found test.txt
Unmount the file system:
root@stm32mp157d-som:~# umount /mnt/ [ 2720.199493] EXT4-fs (dm-0): unmounting filesystem.
Close the encrypted disk and unbind the loop device:
root@stm32mp157d-som:~# cryptsetup close mytest
root@stm32mp157d-som:~# losetup -d $loopdev
Search the disk image for the encrypted data. It will not be found:
root@stm32mp157d-som:~# grep LALALA disk.bin root@stm32mp157d-som:~# echo $? 1
5.2.3. Phase 3: Disk Unlocking
Once the disk has been created, the sequence to unlock it and mount is as follows:
Bind the loop device to the disk image:
root@stm32mp157d-som:~# loopdev=$(losetup --show -f disk.bin) [ 2226.156155] loop0: detected capacity change from 0 to 40960 root@stm32mp157d-som:~# echo $loopdev /dev/loop0
Unlock the encrypted disk:
root@stm32mp157d-som:~# tpm2_unseal -Q -c 0x81010001 | cryptsetup open --type luks $loopdev mytest
Mount the file system:
root@stm32mp157d-som:~# mount /dev/mapper/mytest /mnt/ [ 2344.024272] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Quota mode: disabled.
Print the encrypted text file:
root@stm32mp157d-som:~# cat /mnt/test.txt LALALA, the data is encrypted!