Skip to content

Commit

Permalink
tee-supplicant: add udev rule and systemd service file
Browse files Browse the repository at this point in the history
tee-supplicant startup with systemd init based
is non-trivial. Add sample udev rule and systemd
service files here so that distros can co-operate maintaining
them.

Files are from meta-arm https://git.yoctoproject.org/meta-arm
at commit 7cce43e632daa8650f683ac726f9124681b302a4 with license
MIT and authors:

Peter Griffin <[email protected]>
Joshua Watt <[email protected]>
Javier Tia <[email protected]>
Mikko Rapeli <[email protected]>

With permission from the authors, files can be relicensed to
BSD-2-Clause like rest of optee client repo.

The config files expect to find tee and teepriv system groups
and teesuppl user and group (part of teepriv group) for running
tee-supplicant. Additionally state directory /var/lib/tee
must be owned by teesuppl user and group with no rights
to other users. The groups and user can be changed via
CMake variables:

CFG_TEE_GROUP
CFG_TEEPRIV_GROUP
CFG_TEE_SUPPL_USER
CFG_TEE_SUPPL_GROUP

Change storage path from /data to /var/lib and
use standard CMake variables also for constructing install
paths which can be override to change the defaults:

CMAKE_INSTALL_PREFIX, e.g. /
CMAKE_INSTALL_LIBDIR, e.g. /usr/lib
CMAKE_INSTALL_LOCALSTATEDIR /var

Once these are setup, udev will start tee-supplicant in initramfs
or rootfs with teesuppl user and group when /dev/teepriv
device appears. The systemd service starts before tpm2.target
(new in systemd 256) which starts early in initramfs and in main rootfs.
This covers firmware TPM TA usecases for main rootfs encryption. When
stopping tee-supplicant, the ftpm kernel modules are removed and only
then the main process stopped to avoid fTPM breakage. These workarounds
may be removed once RPMB kernel and optee patches without tee-supplicant
are merged (Linux kernel >= 6.12-rc1, optee_os latest master or >= 4.4).

Tested on yocto meta-arm setup which runs fTPM and optee-test/xtest
under qemuarm64:

$ git clone https://git.yoctoproject.org/meta-arm
$ cd meta-arm
$ SSTATE_DIR=$HOME/sstate DL_DIR=$HOME/download kas build \
ci/qemuarm64-secureboot.yml:ci/poky-altcfg.yml:ci/testimage.yml

Compiled image can be manually started to qemu serial console with:

$ SSTATE_DIR=$HOME/sstate DL_DIR=$HOME/download kas shell \
ci/qemuarm64-secureboot.yml:ci/poky-altcfg.yml:ci/testimage.yml
$ runqemu slirp nographic

meta-arm maintainers run these tests as part of their CI.

Note that if the tee-supplicant state directory /var/lib/tee
can not be accessed due permissions or other problems, then
tee-supplicant startup with systemd still works. Only optee-test/xtest
will be failing and fTPM kernel drivers fail to load with error
messages.

Cc: Peter Griffin <[email protected]>
Cc: Joshua Watt <[email protected]>
Cc: Javier Tia <[email protected]>
Acked-by: Jerome Forissier <[email protected]>
Signed-off-by: Mikko Rapeli <[email protected]>
  • Loading branch information
mikkorapeli-linaro committed Oct 8, 2024
1 parent 49e646d commit c65e2ba
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
2 changes: 1 addition & 1 deletion config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ CFG_TEE_SUPP_LOG_LEVEL?=1
# This folder can be created with the required permission in an init
# script during boot, else it will be created by the tee-supplicant on
# first REE FS access.
CFG_TEE_FS_PARENT_PATH ?= /data/tee
CFG_TEE_FS_PARENT_PATH ?= /var/lib/tee

# CFG_TEE_CLIENT_LOG_FILE
# The location of the client log file when logging to file is enabled.
Expand Down
2 changes: 1 addition & 1 deletion libteec/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ endif()
# Configuration flags always included
################################################################################
set(CFG_TEE_CLIENT_LOG_LEVEL "1" CACHE STRING "libteec log level")
set(CFG_TEE_CLIENT_LOG_FILE "/data/tee/teec.log" CACHE STRING "Location of libteec log")
set(CFG_TEE_CLIENT_LOG_FILE "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/tee/teec.log" CACHE STRING "Location of libteec log")

################################################################################
# Source files
Expand Down
13 changes: 11 additions & 2 deletions tee-supplicant/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ option(CFG_TEE_SUPP_PLUGINS "Enable tee-supplicant plugin support" ON)
set(CFG_TEE_SUPP_LOG_LEVEL "1" CACHE STRING "tee-supplicant log level")
# FIXME: Question is, is this really needed? Should just use defaults from # GNUInstallDirs?
set(CFG_TEE_CLIENT_LOAD_PATH "/lib" CACHE STRING "Colon-separated list of paths where to look for TAs (see also --ta-dir)")
set(CFG_TEE_FS_PARENT_PATH "/data/tee" CACHE STRING "Location of TEE filesystem (secure storage)")
set(CFG_TEE_FS_PARENT_PATH "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/tee" CACHE STRING "Location of TEE filesystem (secure storage)")
# FIXME: Why do we have if defined(CFG_GP_SOCKETS) && CFG_GP_SOCKETS == 1 in the c-file?
set(CFG_GP_SOCKETS "1" CACHE STRING "Enable GlobalPlatform Socket API support")
set(CFG_TEE_PLUGIN_LOAD_PATH "/usr/lib/tee-supplicant/plugins/" CACHE STRING "tee-supplicant's plugins path")
set(CFG_TEE_PLUGIN_LOAD_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/plugins/" CACHE STRING "tee-supplicant's plugins path")

set(CFG_TEE_GROUP "tee" CACHE STRING "Group which has access to /dev/tee* devices")
set(CFG_TEEPRIV_GROUP "teepriv" CACHE STRING "Group which has access to /dev/teepriv* devices")
set(CFG_TEE_SUPPL_USER "teesuppl" CACHE STRING "User account which tee-supplicant is started with")
set(CFG_TEE_SUPPL_GROUP "teesuppl" CACHE STRING "Group account which tee-supplicant is started with")

if(CFG_TEE_SUPP_PLUGINS)
set(CMAKE_INSTALL_RPATH "${CFG_TEE_PLUGIN_LOAD_PATH}")
Expand Down Expand Up @@ -113,3 +118,7 @@ endif()
# Install targets
################################################################################
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
configure_file([email protected] [email protected] @ONLY)
install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/[email protected] DESTINATION ${CMAKE_INSTALL_LIBDIR}/systemd/system)
configure_file(optee-udev.rules.in optee-udev.rules @ONLY)
install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/optee-udev.rules DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/udev/rules.d)
7 changes: 7 additions & 0 deletions tee-supplicant/optee-udev.rules.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: BSD-2-Clause
KERNEL=="tee[0-9]*", MODE="0660", OWNER="root", GROUP="@CFG_TEE_GROUP@", TAG+="systemd"

# If a /dev/teepriv[0-9]* device is detected, start an instance of
# tee-supplicant.service with the device name as parameter
KERNEL=="teepriv[0-9]*", MODE="0660", OWNER="root", GROUP="@CFG_TEEPRIV_GROUP@", \
TAG+="systemd", ENV{SYSTEMD_WANTS}+="tee-supplicant@%k.service"
17 changes: 17 additions & 0 deletions tee-supplicant/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-License-Identifier: BSD-2-Clause
[Unit]
Description=TEE Supplicant on %i
DefaultDependencies=no
After=dev-%i.device
Wants=dev-%i.device
Conflicts=shutdown.target
Before=tpm2.target sysinit.target shutdown.target

[Service]
Type=notify
User=@CFG_TEE_SUPPL_USER@
Group=@CFG_TEE_SUPPL_GROUP@
EnvironmentFile=-@CMAKE_INSTALL_SYSCONFDIR@/default/tee-supplicant
ExecStart=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_SBINDIR@/tee-supplicant $OPTARGS
# Workaround for fTPM TA: stop kernel module before tee-supplicant
ExecStop=-/bin/sh -c "/sbin/modprobe -v -r tpm_ftpm_tee ; /bin/kill $MAINPID"

0 comments on commit c65e2ba

Please sign in to comment.