1dm-verity and Yocto/OE
2----------------------
3The dm-verity feature provides a level of data integrity and resistance to
4data tampering.  It does this by creating a hash for each data block of
5the underlying device as the base of a hash tree.  There are many
6documents out there to further explain the implementation, such as the
7in-kernel one itself:
8
9https://docs.kernel.org/admin-guide/device-mapper/verity.html
10
11The goal of this document is not to reproduce that content, but instead to
12capture the Yocto/OE specifics of the dm-verity infrastructure used here.
13
14Ideally this should enable a person to build and deploy an image on one of
15the supported reference platforms, and then further adapt to their own
16platform and specific storage requirements.
17
18Basic Settings
19--------------
20Largely everything is driven off of a dm-verity image class; a typical
21block of non MACHINE specific settings are shown below:
22
23INITRAMFS_IMAGE = "dm-verity-image-initramfs"
24DM_VERITY_IMAGE = "core-image-minimal"
25DM_VERITY_IMAGE_TYPE = "ext4"
26IMAGE_CLASSES += "dm-verity-img"
27INITRAMFS_IMAGE_BUNDLE = "1"
28
29Kernel Configuration
30--------------------
31Kernel configuration for dm-verity happens automatically via IMAGE_CLASSES
32which will source features/device-mapper/dm-verity.scc when dm-verity-img
33is used. [See commit d9feafe991c]
34IMPORTANT: As per the top level README, you *must* put security in the
35DISTRO_FEATURES, or else you won't get the dm-verity kernel settings.
36
37Supported Platforms
38-------------------
39In theory, you can use dm-verity anywhere - there is nothing arch/BSP
40specific in the core kernel support.  However, at the BSP level, one
41eventually has to decide what device(s) are to be hashed, and where the
42hash tables are stored.
43
44To that end, the BSP storage specifics live in meta-security/wic dir and
45represent the current set of example configurations that have been tested
46and submitted at some point.
47
48Getting Started
49---------------
50This document assumes you are starting from the basic auto-created
51conf/local.conf and conf/bblayers.conf from the oe-init-build-env
52
53Firstly, you need the meta-security layer to conf/bblayers.conf along with
54the dependencies it has -- see the top level meta-security README for that.
55
56Note that if you are using dm-verity for your rootfs, then it enforces a
57read-only mount right at the kernel level, so be prepared for issues such
58as failed creation of temporary files and similar.
59
60Yocto does support additional checks and changes via setting:
61
62EXTRA_IMAGE_FEATURES = "read-only-rootfs"
63
64...but since read-only is enforced at the kernel level already, using
65this feature isn't a hard requirement.  It may be best to delay/defer
66making use of this until after you've established basic booting.
67
68For more details, see the associated documentation:
69
70https://docs.yoctoproject.org/dev/dev-manual/read-only-rootfs.html
71
72Also add the basic block of dm-verity settings shown above, and select
73your MACHINE from one of the supported platforms.
74
75If there is a dm-verity-<MACHINE>.txt file for your BSP, check that for
76any additional platform specific recommended settings, such as the
77WKS_FILES which can specify board specific storage layout discussed below.
78
79Then you should be able to do a "bitbake core-image-minimal" just like any
80other normal build.  What you will notice, is the content in
81tmp/deploy/images/<MACHINE>/ now have suffixes like "rootfs.ext4.verity"
82
83While you can manually work with these images just like any other build,
84this is where the BSP specific recipes in meta-security/wic can simplify
85things and remove a bunch of manual steps that might be error prone.
86
87Consider for example, the beaglebone black WIC file, which contains:
88
89part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat
90--label boot --active --align 4 --fixed-size 32 --sourceparams="loader=u-boot" --use-uuid
91part / --source rawcopy --ondisk mmcblk0 --sourceparams="file=${IMGDEPLOYDIR}/${DM_VERITY_IMAGE}-${MACHINE}.${DM_VERITY_IMAGE_TYPE}.verity"
92bootloader --append="console=ttyS0,115200"
93
94As can be seen, it maps out the partitions, including the bootloader, and
95saves doing a whole bunch of manual partitioning and dd steps.
96
97This file is copied into tmp/deploy/images/<MACHINE>/ with bitbake
98variables expanded with their corresponding values for wic to make use of.
99
100Continuing with the beaglebone example, we'll see output similar to:
101
102             ----------------------
103$ wic create -e core-image-minimal beaglebone-yocto-verity
104
105[...]
106
107INFO: Creating image(s)...
108
109INFO: The new image(s) can be found here:
110  ./beaglebone-yocto-verity.wks-202303070223-mmcblk0.direct
111
112The following build artifacts were used to create the image(s):
113  BOOTIMG_DIR:       /home/paul/poky/build-bbb-verity/tmp/work/beaglebone_yocto-poky-linux-gnueabi/core-image-minimal/1.0-r0/recipe-sysroot/usr/share
114  KERNEL_DIR:        /home/paul/poky/build-bbb-verity/tmp/deploy/images/beaglebone-yocto
115  NATIVE_SYSROOT:    /home/paul/poky/build-bbb-verity/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/wic-tools/1.0-r0/recipe-sysroot-native
116
117INFO: The image(s) were created using OE kickstart file:
118  /home/paul/poky/meta-security/wic/beaglebone-yocto-verity.wks.in
119             ----------------------
120
121The "direct" image contains the partition table, bootloader, and dm-verity
122enabled ext4 image all in one -- ready to write to a raw device, such as a
123u-SD card in the case of the beaglebone.
124