Table of Contents |
---|
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 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:
...
Code Block |
---|
[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:
Code Block 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:
Code Block root@stm32mp157d-som:~# cat /sys/class/tpm/tpm*/tpm_version_major 2
Check the TPM capabilities:
Code Block 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: [ ]
Code Block 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 ...
Code Block root@stm32mp157d-som:~# tpm2_getcap ecc-curves TPM2_ECC_NIST_P256: 0x3 TPM2_ECC_NIST_P384: 0x4 TPM2_ECC_BN_P256: 0x10
Code Block 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:
Code Block root@stm32mp157d-som:~# truncate -s 20M disk.bin
Create a TPM-stored sealed key.
Code Block 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:
Code Block 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:
Code Block root@stm32mp157d-som:~# tpm2_unseal -Q -c 0x81010001 | cryptsetup luksFormat --type luks2 $loopdev
Unlock the created disk:
Code Block 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.Code Block 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:Code Block 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:
Code Block root@stm32mp157d-som:~# echo "LALALA, the data is encrypted!" > /mnt/test.txt
Code Block root@stm32mp157d-som:~# ls /mnt/ lost+found test.txt
Unmount the file system:
Code Block root@stm32mp157d-som:~# umount /mnt/ [ 2720.199493] EXT4-fs (dm-0): unmounting filesystem.
Close the encrypted disk and unbind the loop device:
Code Block root@stm32mp157d-som:~# cryptsetup close mytest
Code Block root@stm32mp157d-som:~# losetup -d $loopdev
Search the disk image for the encrypted data. It will not be found:
Code Block 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:
...