Skip to content

[next] Implement foundational changes for NILRT Device Encryption#977

Open
amstewart wants to merge 30 commits intoni:nilrt/master/nextfrom
amstewart:feat/next/device-encryption
Open

[next] Implement foundational changes for NILRT Device Encryption#977
amstewart wants to merge 30 commits intoni:nilrt/master/nextfrom
amstewart:feat/next/device-encryption

Conversation

@amstewart
Copy link
Copy Markdown
Contributor

@amstewart amstewart commented Mar 23, 2026

Summary of Changes

This PR contains all the foundational changes necessary for the core features of Measured Boot / Device Encryption on NILRT. It stops short of the changes to nisystemformat which will actually affect the LUKS encryption - they will be in their own PR after this one.

Changes in this PR:

  1. Adds additional TPM2 kernel modules to the extra_x64 set. The core TPM2 drivers have already been built into the 6.12 kernel as of ni/linux#270.
  2. Adds TPM2 to the NILRT x64 machine features. This will coerce recipes to build with TPM2 support.
  3. Adds TPM2 support to our grub recipe and modifies the grub config to enable boot measurements.
  4. Adds TPM and cryptography user space tools to the safemode and runmode.
  5. Adds the Clevis recipe - a tool for binding LUKS decryption keys to TPM state. Also adds clevis' dependencies.
  6. Modifies the OVMF (UEFI BIOS) recipe to output its raw code and variable images, so that we can use it in QEMU to test the TPM state.
  7. Modifies fstab to mount the Linux securityfs subsystem under /sys so that users can interrogate TPM boot measurements.
  8. Adds a new, ubiquitous initscript - ni-cryptdisks - which will try to find and open any LUKS-encrypted disks using the TPM state (through clevis).
  9. Creates an initramfs image for runmode - nilrt-runmode-initramfs with a custom /init that will try to mount any LUKS-encrypted disks using the TPM state. Then it pivot_roots into the real runmode rootfs (that might have been on an encrypted disk).
  10. Modifies the grub.cfg to search for the new runmode initramfs, if it is available, and boot into it. If it is not available (backwards compat), grub will just try to boot into the registered runmode partition of record (the existing behavior).
  11. Adds the runmode initramfs to the NILRT BSI image. It gets installed alongside the kernel.
  12. Cleans up old RAUC content throughout.
  13. Fixed AB#3758708 while I was working on the grub config anyway.

Justification

Testing

  • I have built the core package feed with this PR in place. (bitbake packagefeed-ni-core)
  • Tested installing both the new - initramfs-enabled - BSI and the old runmode BSI. Both boot without issue.
  • Extensive general hand testing of this configuration on an x64 QEMU VM equipped with a software-emulated TPM.

Procedure

usercw88 and others added 6 commits March 23, 2026 17:19
Signed-off-by: Can Wong <can.wong@emerson.com>
PXIs and other x86_64 devices may be populated with TPM2 compatible
TPMs. Add 'tpm2' to the MACHINE_FEATURES so that recipes which use that
value to determine configured functionality are aware.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Syntax and styling changes to the file. Clean up and sort GRUB_BUILDIN.
Expand grub-mkimage arguments for clarity.

No intentional functional changes.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Build in the 'tpm' module so that our GRUB config can use the TPM to
store measured bootloader component hashes.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The grub-efi recipe compiles just fine without warning suppression, so
remove this workaround.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Direct GRUB to measure the kernel boot stages and record them to PCR
registers 8 and 9 by setting the `measure_on` setting.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
@amstewart amstewart requested review from chaitu236 and usercw88 and removed request for chaitu236 March 23, 2026 21:42
When LUKS-based disk encryption is implemented, safemode and runmode
will need utilties to interact with the encrypted partitions. Add these
utilities to the base packagegroup to ensure they are present in the
base images.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
@amstewart amstewart force-pushed the feat/next/device-encryption branch 2 times, most recently from 9b23cc6 to 7fa4d0e Compare March 24, 2026 19:17
@amstewart
Copy link
Copy Markdown
Contributor Author

Patch v2

  1. Removed the leftover debug function get_luks_key() from ni-cryptdisks.
  2. Removed the VM-keyboard modules from packagegroup-ni-initramfs, since they are not necessary in the initramfs.
  3. Only build the init-nilrt-runmode-initramfs recipe when building the core packagefeed for x64.
  4. Cherry-picked meta-nilrt Ensure BSI installation failures doesn't brick target #960 into this PR, to merge implementation with scarthgap.
  5. Consolidated TPM2 user space includes into packagegroup-ni-tpm.
  • Revalidated with this Patchrev.

Alex Stewart added 15 commits March 24, 2026 15:58
Remove the old RAUC grub components so that they are not confused with
the contemporary components.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The JOSE (Javascript Object Signing and Encryption) library is used by
Clevis as a data serialization format. It is maintained by LatchSet, the
same organization that maintains Clevis.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The luksmeta library provides utilities for interacting with LUKSv1
headers. It is used as by Clevis when building with luks support. It is
maintained by LatchSet - the same organization which owns Clevis.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Clevis is a pluggable framework for automated decryption. It can be used
to provide automated decryption of data or even automated unlocking of
LUKS volumes.

Add a recipe for it at the latest release (v21) for use by NILRT
measured boot, to store LUKS decryption keys in the TPM.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Add the Clevis utility to NILRT x64, for use in measured boot (disk
encryption) workflows.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The OE-core ovmf recipe generates raw OVMF image files, but then
converts them to qcow2 images, and moves only the qcow2 files to the
deploy directory. QEMU can use either format, but only the raw format
supports writable EFI variables - which NILRT uses and which upstream OE
core testing does not.

So add a NILRT-specific bbappend which also outputs the raw-formatted
OVMF files, for use in NILRT QEMU virtual machines.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The sescurityfs is a kernel virtual filesystem that provides access to
security devices like TPMs. Mount it to the sysfs so that it can be used
to read TPM events.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Create a recipe which installs an /init script to the new runmode
initramfs. The initscript's primary mission is to unlock any
LUKS-encrypted partitions, before switching into the real rootfs.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The init-nilrt-ramfs is an old initrdscripts recipe for the previous
RAUC prototype. It is unused.

Remove it for codebase cleanliness.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
To support full Device Encryption, NILRT runmode requires an unencrypted
initramfs that understands how to interact with the device TPM and
decrypt and mount LUKS partitons.

Create nilrt-runmode-initramfs.bb to act as such an image.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The meta-nilrt styleguide has an example bitbake recipe at its end.
Update that recipe with some better headings and comments and break it
out into its own file, so that it is easier to reuse in new recipes.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The ni-device-encryption recipe will contain content supporting
fundamental LUKS-encryption of NILRT devices. At the moment, it only
packages an initscript which will handle opening/closing LUKS partitions
during early boot.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The TCG TPM TIS kernel driver is now built into the x64 kernel and there
is no module package for it. Remove the invalid reference to it from the
restoremode (recovery initramfs) RRECOMMENDS.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The base packagegroup requires ni-device-encryption so that all images
will understand how to unlock LUKS-encrypted partitions during boot
(especially safemode).

The initramfs packagegroup is used to populate the rootfs for the
runmode initramfs. It requires ni-device-encryption to unlock the LUKS
partitions prior to switching into the real rootfs.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Alex Stewart added 4 commits March 24, 2026 15:58
The new runmode initramfs needs an init system (PID 1). Build it into
the core feed so that it is represented in our SBOMs and packaging
infrastructure. But do not add it to a packagegroup so that it doesn't
get accidentally installed by a user with something else.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The new runmode GRUB configuration will load a ramdisk image from next
to the runmode kernel, so that we can do pre-rootfs operations like
opening LUKS partitions. Add the nilrt-runmode-initramfs image to the
runmode rootfs, so that it is ready to load.

Also convert the existing 'fixup' logic from image preprocess commands
to rootfs post-process commands, since they are really making changes to
the rootfs. You can now run ``bitbake -c rootfs nilrt-runmode-rootfs``
and actually inspect the rootfs changes that the fixups are performing.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Currently, the GRUB config relies on a rootuid value that was written
during provisioning to identify the rootfs/userfs UUID, and boot it
without the use of a ramdisk.

Now that we have to use a ramdisk to unlock LUKS partitions on x64,
modify the GRUB config to instead load the ramdisk at
/boot/runmode/ramdisk.xz, similar to how safemode boots.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
When the grub config executes before runmode has been installed, it will
throw an error about not being able to find `/runmode/` in order to
check if the runmode OS files are OK.

All this check does it set the `valid_runmode` grub variable to 0. So we
can just check if the `/runmode` (and `/.safe`) directories exist first
and skip checking their individual OS files if they do not.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
@amstewart amstewart force-pushed the feat/next/device-encryption branch from 7fa4d0e to ff44451 Compare March 24, 2026 19:58
rajendra-desai-ni and others added 4 commits March 24, 2026 16:03
Some files like Module.symvers-4.14.146-rt67-ni and
config-4.14.146-rt67-ni present in /boot directory of arm BSI can
fill up /boot partition. It is necessary to remove them to save
some disk space as they do not cause any harm or change the system
behavior even if removed. The logic used here is to remove all files
except linux_runmode.itb since that is the only file needed to be
present in /boot directory.

Signed-off-by: Rajendra Desai <rajendra.desai@emerson.com>
(cherry picked from commit 07cc1a4)

Rebased to nilrt/master/next.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Previously, bootimg_fixup_arm() placed linux_runmode.itb directly in
boot/, which meant u-boot could see and attempt to boot a
partially-extracted runmode image if BSI extraction was interrupted
(e.g. by a full disk). Since the rootfs would be incomplete, the
target would be bricked.

Fix this by staging the ITB under boot/runmode/ during image creation.
The postinst script — which only runs after a successful extraction —
moves the ITB to its final /boot location. If extraction fails,
postinst never executes, so u-boot never sees the ITB and correctly
treats runmode as not installed.

Also update the postinst ARM path to clean up the temporary runmode/
directory after moving the ITB

Signed-off-by: Shreejit C <shreejit.c@emerson.com>
(cherry picked from commit 15feaea)

Merged scarthgap implementation into the new ``fixup_kernel_armv7a()``
function in nilrt-runmode-rootfs.bb.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
Drop legacy compatibility code that handled safemode versions
older than 8.0. New BSIs require safemode 26.3 or newer, which
bind-mounts /boot to /mnt/userfs/boot. The old bulk-move
fallback and its guard are no longer needed and can be safely
removed.

Signed-off-by: Shreejit C <shreejit.c@emerson.com>
(cherry picked from commit 32abced)
Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
The TPM-related packages have been declared independently in the base
packagegroup, where we should just use the ``-ni-tpm`` packagegroup
instead. But we have to remove the dependency on the OE upstream
``packagegroup-security-tpm2`` since it includes python dependencies and
init services that we do not want in the initramfs images.

Also, remove crypsetup from the extras feed declaration, since it is
already built in the core feed.

Signed-off-by: Alex Stewart <alex.stewart@emerson.com>
@amstewart amstewart force-pushed the feat/next/device-encryption branch from ff44451 to 154e4c0 Compare March 24, 2026 20:06
@amstewart
Copy link
Copy Markdown
Contributor Author

Patch v3

  1. Cherry picked nilrt-runmode-rootfs: cleanup /boot files in arm BSI #955.
  2. Restored a file from the grub recipe (cfg) which was actually being used to set our nonstandard GRUB prefix value. I thought it was only being used by RAUC previously, but it is actually an override of this upstream OE-core grub recipe file.
  • Rebuilt the core feed with this patchrev.

@amstewart amstewart requested a review from chaitu236 March 24, 2026 20:12
setusbgadgetparam

linux $kernel_path root=PARTUUID=$rootuuid $otherbootargs $usb_gadget_args $kernellogparam $consoleparam $othbootargs sys_reset=$sys_reset
if [ -n "$ramdisk_path" ]; then
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason we have if/else here is because we want to support old BSIs without ramdisk?
And that's also the reason we're not adding ramdisk.xz to runmode_files?

I'm wondering if we should also check for existence of ramdisk_path (if it's set) in check_valid_os.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct.

ramdisk_path is set in the bootmode's bootimage.cfg file, which is already checked to exist in the validation steps. So I think we can assume that the contents of that file are correct. Legacy runmode bootimage.cfg files don't set ramdisk_path at all.

partitions for NILRT. Installs the ni-cryptdisks.sh initscript.\
"
HOMEPAGE = "https://github.com/ni/meta-nilrt"
SECTION = "test"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this belong in test section?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix.

efibootmgr \
efivar \
pstore-save \
clevis \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: not sorted. Maybe break out tpm related packages into their own RDEPENDS:${PN}:append:x64 section if we want to keep them together?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It gets fixed up by the final commit in the patchset. These items are moved into packagegroup-ni-tpm.

CONFIG_TAP=m
CONFIG_TARGET_CORE=m
CONFIG_TCG_ATMEL=m
CONFIG_TCG_CRB=m
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as #957 we don't need CONFIG_TCG_CRB, CONFIG_TCG_TIS, CONFIG_TCG_TIS_CORE, CONFIG_TCG_TPM

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a commit from a later patchset that I will backport to fix this. But honestly, I'm considering just implementing the allmoddefconfig task that we discussed offline.

@chaitu236
Copy link
Copy Markdown
Contributor

Offline conversation: We've decided to merge this after release is done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants