diff mbox series

[meta-ti,master,v4,1/3] dm-verity-upstream: Add dynamic layer for meta-security dm-verity

Message ID 20260930125938.95629-1-a-dubey@ti.com
State Superseded
Delegated to: Ryan Eatmon
Headers show
Series [meta-ti,master,v4,1/3] dm-verity-upstream: Add dynamic layer for meta-security dm-verity | expand

Commit Message

Atharv Dubey Sept. 30, 2026, 12:59 p.m. UTC
Add an optional dynamic layer enabling dm-verity block-level integrity
verification of the root filesystem for TI K3 platforms, using
meta-security's stock dm-verity mechanism as-is. Requires meta-security
to be present in bblayers.conf.

dm-verity hashes the rootfs at build time; at boot, a dedicated
initramfs loads the root hash and the kernel checks every block read
against it. Set DM_VERITY_IMAGE to enable all the verity-related
recipes for that image; other images build as usual.

Signed-off-by: Atharv Dubey <a-dubey@ti.com>

---
v4:
 - Use ti-core-initramfs instead of a separate dm-verity initramfs
 - Instead of a DISTRO_FEATURE, just check if DM_VERITY_IMAGE is set
v3:
 - Disabled the automount rules from udev-aragoconf, so don't need the
   ignorelist for dm-verity
v2:
 - Replaced hardcoded /dev/mmcblk1p2 with a PARTUUID
---
 meta-ti-bsp/conf/layer.conf                   |  3 +++
 meta-ti-bsp/conf/machine/include/k3.inc       |  7 ++++++
 .../conf/include/dm-verity-upstream.inc       | 23 +++++++++++++++++++
 .../udev/udev-aragoconf_%.bbappend            |  5 ++++
 .../udev/udev-extraconf_%.bbappend            |  6 +++++
 meta-ti-bsp/files/wic/k3-verity.wks.in        |  5 ++++
 6 files changed, 49 insertions(+)
 create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
 create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
 create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
 create mode 100644 meta-ti-bsp/files/wic/k3-verity.wks.in

Comments

PRC Automation Sept. 30, 2026, 1:10 p.m. UTC | #1
meta-ti / na / 20260930125938.95629-1-a-dubey

PRC Results: FAIL

=========================================================
  check-yocto-patches: PASS
=========================================================
Patches
----------------------------------------
WARN - [meta-ti][master][PATCH v4 2/3] linux-ti-staging: Add dm-verity kernel config
    WARN: Revised patch missing a comment. (REVISION-1)
        patch
    
    For details on the above errors/warnings visit: https://lists.yoctoproject.org/g/meta-ti/wiki/40887
WARN - [meta-ti][master][PATCH v4 3/3] ti-core-initramfs: Extend with dm-verity support
    WARN: Revised patch missing a comment. (REVISION-1)
        patch
    
    For details on the above errors/warnings visit: https://lists.yoctoproject.org/g/meta-ti/wiki/40887



=========================================================
  apply-yocto-patch: FAIL
=========================================================
master
=====================
Summary:
- Patch Series: [meta-ti][master][PATCH v4 1/3] dm-verity-upstream: Add dynamic layer for meta-security dm-verity
- Submitter: From: Atharv Dubey <a-dubey@ti.com>
- Date: Date: Wed, 30 Sep 2026 18:29:36 +0530
- Num Patches: 3
- Mailing List (public inbox) Commit SHA: 9a1220ed1f51854c8dcf5b95709213f9e510bbe3

Applied to:
- Repository: lcpd-prc-meta-ti
- Base Branch: master
- Commit Author: LCPD Automation Script <lcpdbld@list.ti.com>
- Commit Subject: CI/CD Auto-Merger: cicd.master.202609251030
- Commit SHA: 9a970370942d7ff753a64b31bc367e1e27aa3048

Patches
----------------------------------------
FAIL - [meta-ti][master][PATCH v4 1/3] dm-verity-upstream: Add dynamic layer for meta-security dm-verity
    error: patch failed: meta-ti-bsp/conf/layer.conf:20
    error: meta-ti-bsp/conf/layer.conf: patch does not apply
    Applying: dm-verity-upstream: Add dynamic layer for meta-security dm-verity
    Patch failed at 0001 dm-verity-upstream: Add dynamic layer for meta-security dm-verity
Denys Dmytriyenko Sept. 30, 2026, 4:22 p.m. UTC | #2
On Wed, Sep 30, 2026 at 06:29:36PM +0530, Atharv Dubey via lists.yoctoproject.org wrote:
> Add an optional dynamic layer enabling dm-verity block-level integrity
> verification of the root filesystem for TI K3 platforms, using
> meta-security's stock dm-verity mechanism as-is. Requires meta-security
> to be present in bblayers.conf.
> 
> dm-verity hashes the rootfs at build time; at boot, a dedicated
> initramfs loads the root hash and the kernel checks every block read
> against it. Set DM_VERITY_IMAGE to enable all the verity-related
> recipes for that image; other images build as usual.
> 
> Signed-off-by: Atharv Dubey <a-dubey@ti.com>
> 
> ---
> v4:
>  - Use ti-core-initramfs instead of a separate dm-verity initramfs
>  - Instead of a DISTRO_FEATURE, just check if DM_VERITY_IMAGE is set
> v3:
>  - Disabled the automount rules from udev-aragoconf, so don't need the
>    ignorelist for dm-verity
> v2:
>  - Replaced hardcoded /dev/mmcblk1p2 with a PARTUUID
> ---
>  meta-ti-bsp/conf/layer.conf                   |  3 +++
>  meta-ti-bsp/conf/machine/include/k3.inc       |  7 ++++++
>  .../conf/include/dm-verity-upstream.inc       | 23 +++++++++++++++++++
>  .../udev/udev-aragoconf_%.bbappend            |  5 ++++
>  .../udev/udev-extraconf_%.bbappend            |  6 +++++
>  meta-ti-bsp/files/wic/k3-verity.wks.in        |  5 ++++
>  6 files changed, 49 insertions(+)
>  create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
>  create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
>  create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
>  create mode 100644 meta-ti-bsp/files/wic/k3-verity.wks.in
> 
> diff --git a/meta-ti-bsp/conf/layer.conf b/meta-ti-bsp/conf/layer.conf
> index 3cc54aa4..aca35cd3 100644
> --- a/meta-ti-bsp/conf/layer.conf
> +++ b/meta-ti-bsp/conf/layer.conf
> @@ -20,12 +20,15 @@ LAYERDEPENDS_meta-ti-bsp = " \
>  LAYERRECOMMENDS_meta-ti-bsp = " \
>      openembedded-layer \
>      tpm-layer \
> +    security \
>  "
>  
>  BBFILES_DYNAMIC += " \
>      openembedded-layer:${LAYERDIR}/dynamic-layers/openembedded-layer/recipes*/*/*.bbappend \
>      tpm-layer:${LAYERDIR}/dynamic-layers/tpm-layer/recipes*/*/*.bb \
>      tpm-layer:${LAYERDIR}/dynamic-layers/tpm-layer/recipes*/*/*.bbappend \
> +    security:${LAYERDIR}/dynamic-layers/security-layer/recipes*/*/*.bb \
> +    security:${LAYERDIR}/dynamic-layers/security-layer/recipes*/*/*.bbappend \
>  "
>  
>  SIGGEN_EXCLUDERECIPES_ABISAFE += " \
> diff --git a/meta-ti-bsp/conf/machine/include/k3.inc b/meta-ti-bsp/conf/machine/include/k3.inc
> index 2ebbfb9e..f19db45f 100644
> --- a/meta-ti-bsp/conf/machine/include/k3.inc
> +++ b/meta-ti-bsp/conf/machine/include/k3.inc
> @@ -64,3 +64,10 @@ FALCON_INCLUDE = ""
>  FALCON_INCLUDE:ti-falcon = "conf/machine/include/ti-falcon.inc"
>  
>  require ${FALCON_INCLUDE}
> +
> +# dm-verity protects the rootfs listed in DM_VERITY_IMAGE; see dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc for what that turns on.
> +DM_VERITY_IMAGE ??= ""
> +
> +DM_VERITY_UPSTREAM_INCLUDE = "${@'dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc' if d.getVar('DM_VERITY_IMAGE') else ''}"
> +
> +require ${DM_VERITY_UPSTREAM_INCLUDE}
> diff --git a/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc b/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
> new file mode 100644
> index 00000000..3ff2b7d6
> --- /dev/null
> +++ b/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
> @@ -0,0 +1,23 @@
> +# Enables dm-verity to check the rootfs for tampering on TI K3 boards.
> +DM_VERITY_IMAGE_TYPE = "ext4"
> +IMAGE_CLASSES += "dm-verity-img"
> +
> +# ti-core-initramfs.bbappend already wires the initramfs into the boot partition once dm-verity is enabled, so we don't need to do it here.
> +
> +# Derive the root partition's UUID from MACHINE so everyone computes the same one.
> +python () {
> +    import uuid
> +
> +    if not d.getVar('DM_VERITY_ROOT_PARTUUID'):
> +        d.setVar('DM_VERITY_ROOT_PARTUUID',
> +                 str(uuid.uuid5(uuid.NAMESPACE_DNS, 'dm-verity-root-%s' % d.getVar('MACHINE'))))
> +}

Should these 2 anonymous python functions be combined and the above code go 
behind the check below? Is DM_VERITY_ROOT_PARTUUID needed outside of the 
DM_VERITY_IMAGE image?


> +
> +python () {
> +    if d.getVar('PN') != d.getVar('DM_VERITY_IMAGE'):
> +        return
> +
> +    d.setVar('WKS_FILE', 'k3-verity.wks.in')
> +    d.appendVar('EXTRA_IMAGE_FEATURES', ' read-only-rootfs')
> +    d.appendVar('WICVARS', ' DM_VERITY_IMAGE DM_VERITY_IMAGE_TYPE IMAGE_NAME_SUFFIX IMGDEPLOYDIR DM_VERITY_ROOT_PARTUUID')
> +}
> diff --git a/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
> new file mode 100644
> index 00000000..e5f6c1b2
> --- /dev/null
> +++ b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
> @@ -0,0 +1,5 @@
> +do_install:append() {
> +    if ${@'true' if d.getVar('DM_VERITY_IMAGE') else 'false'}; then
> +        : > ${D}${libdir}/udev/rules.d/50-arago.rules

Why not simply remove the file?


> +    fi
> +}
> diff --git a/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
> new file mode 100644
> index 00000000..a14e21ea
> --- /dev/null
> +++ b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
> @@ -0,0 +1,6 @@
> +# Nothing should ever get auto-mounted under dm-verity, so just kill the automounter.
> +do_install:append() {
> +    if ${@'true' if d.getVar('DM_VERITY_IMAGE') else 'false'}; then
> +        : > ${D}${sysconfdir}/udev/rules.d/automount.rules

Same question as above.


> +    fi
> +}
> diff --git a/meta-ti-bsp/files/wic/k3-verity.wks.in b/meta-ti-bsp/files/wic/k3-verity.wks.in
> new file mode 100644
> index 00000000..62ae0ec1
> --- /dev/null
> +++ b/meta-ti-bsp/files/wic/k3-verity.wks.in
> @@ -0,0 +1,5 @@
> +# Disk layout for a board that boots with dm-verity enabled.
> +
> +bootloader --timeout=3 --append="rootfstype=ext4 root=PARTUUID=${DM_VERITY_ROOT_PARTUUID} ${TI_WKS_BOOTLOADER_APPEND}"
> +part --source bootimg-efi --sourceparams="loader=${EFI_PROVIDER}${TI_WKS_INITRAMFS}" --fstype=vfat --label boot --active --align 1024 --use-uuid --fixed-size 128M
> +part / --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${DM_VERITY_IMAGE}-${MACHINE}${IMAGE_NAME_SUFFIX}.${DM_VERITY_IMAGE_TYPE}.verity" --align 1024 --uuid ${DM_VERITY_ROOT_PARTUUID}
> -- 
> 2.34.1
Atharv Dubey Oct. 1, 2026, 8:06 a.m. UTC | #3
Hi Denys,

On 30/09/26 21:52, Denys Dmytriyenko wrote:
> On Wed, Sep 30, 2026 at 06: 29: 36PM +0530, Atharv Dubey via 
> lists. yoctoproject. org wrote: > Add an optional dynamic layer 
> enabling dm-verity block-level integrity > verification of the root 
> filesystem for TI K3 platforms, using > meta-security's
> ZjQcmQRYFpfptBannerStart
> This message was sent from outside of Texas Instruments.
> Do not click links or open attachments unless you recognize the source 
> of this email and know the content is safe.
> Report Suspicious
> <https://us-phishalarm-ewt.proofpoint.com/EWT/v1/G3vK!uJdqXRfPtmw7SgZE_JPD3T2ZGKQQCoLNXhtUZkSdkelZkg_-b1-LC9k-eu2ov9pdMYotJXXEww$> 
>
> ZjQcmQRYFpfptBannerEnd
> On Wed, Sep 30, 2026 at 06:29:36PM +0530, Atharv Dubey via lists.yoctoproject.org wrote:
> > Add an optional dynamic layer enabling dm-verity block-level integrity
> > verification of the root filesystem for TI K3 platforms, using
> > meta-security's stock dm-verity mechanism as-is. Requires meta-security
> > to be present in bblayers.conf.
> > 
> > dm-verity hashes the rootfs at build time; at boot, a dedicated
> > initramfs loads the root hash and the kernel checks every block read
> > against it. Set DM_VERITY_IMAGE to enable all the verity-related
> > recipes for that image; other images build as usual.
> > 
> > Signed-off-by: Atharv Dubey <a-dubey@ti.com>
> > 
> > ---
> > v4:
> >  - Use ti-core-initramfs instead of a separate dm-verity initramfs
> >  - Instead of a DISTRO_FEATURE, just check if DM_VERITY_IMAGE is set
> > v3:
> >  - Disabled the automount rules from udev-aragoconf, so don't need the
> >    ignorelist for dm-verity
> > v2:
> >  - Replaced hardcoded /dev/mmcblk1p2 with a PARTUUID
> > ---
> >  meta-ti-bsp/conf/layer.conf                   |  3 +++
> >  meta-ti-bsp/conf/machine/include/k3.inc       |  7 ++++++
> >  .../conf/include/dm-verity-upstream.inc       | 23 +++++++++++++++++++
> >  .../udev/udev-aragoconf_%.bbappend            |  5 ++++
> >  .../udev/udev-extraconf_%.bbappend            |  6 +++++
> >  meta-ti-bsp/files/wic/k3-verity.wks.in        |  5 ++++
> >  6 files changed, 49 insertions(+)
> >  create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
> >  create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
> >  create mode 100644 meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
> >  create mode 100644 meta-ti-bsp/files/wic/k3-verity.wks.in
> > 
> > diff --git a/meta-ti-bsp/conf/layer.conf b/meta-ti-bsp/conf/layer.conf
> > index 3cc54aa4..aca35cd3 100644
> > --- a/meta-ti-bsp/conf/layer.conf
> > +++ b/meta-ti-bsp/conf/layer.conf
> > @@ -20,12 +20,15 @@ LAYERDEPENDS_meta-ti-bsp = " \
> >  LAYERRECOMMENDS_meta-ti-bsp = " \
> >      openembedded-layer \
> >      tpm-layer \
> > +    security \
> >  "
> >  
> >  BBFILES_DYNAMIC += " \
> >      openembedded-layer:${LAYERDIR}/dynamic-layers/openembedded-layer/recipes*/*/*.bbappend \
> >      tpm-layer:${LAYERDIR}/dynamic-layers/tpm-layer/recipes*/*/*.bb \
> >      tpm-layer:${LAYERDIR}/dynamic-layers/tpm-layer/recipes*/*/*.bbappend \
> > +    security:${LAYERDIR}/dynamic-layers/security-layer/recipes*/*/*.bb \
> > +    security:${LAYERDIR}/dynamic-layers/security-layer/recipes*/*/*.bbappend \
> >  "
> >  
> >  SIGGEN_EXCLUDERECIPES_ABISAFE += " \
> > diff --git a/meta-ti-bsp/conf/machine/include/k3.inc b/meta-ti-bsp/conf/machine/include/k3.inc
> > index 2ebbfb9e..f19db45f 100644
> > --- a/meta-ti-bsp/conf/machine/include/k3.inc
> > +++ b/meta-ti-bsp/conf/machine/include/k3.inc
> > @@ -64,3 +64,10 @@ FALCON_INCLUDE = ""
> >  FALCON_INCLUDE:ti-falcon = "conf/machine/include/ti-falcon.inc"
> >  
> >  require ${FALCON_INCLUDE}
> > +
> > +# dm-verity protects the rootfs listed in DM_VERITY_IMAGE; see dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc for what that turns on.
> > +DM_VERITY_IMAGE ??= ""
> > +
> > +DM_VERITY_UPSTREAM_INCLUDE = "${@'dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc' 
> if d.getVar('DM_VERITY_IMAGE') else ''}"
> > +
> > +require ${DM_VERITY_UPSTREAM_INCLUDE}
> > diff --git a/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc b/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
> > new file mode 100644
> > index 00000000..3ff2b7d6
> > --- /dev/null
> > +++ b/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
> > @@ -0,0 +1,23 @@
> > +# Enables dm-verity to check the rootfs for tampering on TI K3 boards.
> > +DM_VERITY_IMAGE_TYPE = "ext4"
> > +IMAGE_CLASSES += "dm-verity-img"
> > +
> > +# ti-core-initramfs.bbappend already wires the initramfs into the boot partition once dm-verity is enabled, so we don't need to do it here.
> > +
> > +# Derive the root partition's UUID from MACHINE so everyone computes the same one.
> > +python () {
> > +    import uuid
> > +
> > +    if not d.getVar('DM_VERITY_ROOT_PARTUUID'):
> > +        d.setVar('DM_VERITY_ROOT_PARTUUID',
> > +                 str(uuid.uuid5(uuid.NAMESPACE_DNS, 'dm-verity-root-%s' % d.getVar('MACHINE'))))
> > +}
>
> Should these 2 anonymous python functions be combined and the above code go
> behind the check below? Is DM_VERITY_ROOT_PARTUUID needed outside of the
> DM_VERITY_IMAGE image?


Yes we can club the 2 functions. Nope we dont need DM_VERITY_ROOT_PARTUUID

anywhere else.


>
>
> > +
> > +python () {
> > +    if d.getVar('PN') != d.getVar('DM_VERITY_IMAGE'):
> > +        return
> > +
> > +    d.setVar('WKS_FILE', 'k3-verity.wks.in')
> > +    d.appendVar('EXTRA_IMAGE_FEATURES', ' read-only-rootfs')
> > +    d.appendVar('WICVARS', ' DM_VERITY_IMAGE DM_VERITY_IMAGE_TYPE IMAGE_NAME_SUFFIX IMGDEPLOYDIR DM_VERITY_ROOT_PARTUUID')
> > +}
> > diff --git a/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
> > new file mode 100644
> > index 00000000..e5f6c1b2
> > --- /dev/null
> > +++ b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
> > @@ -0,0 +1,5 @@
> > +do_install:append() {
> > +    if ${@'true' if d.getVar('DM_VERITY_IMAGE') else 'false'}; then
> > +        : > ${D}${libdir}/udev/rules.d/50-arago.rules
>
> Why not simply remove the file?
>
>
> > +    fi
> > +}
> > diff --git a/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
> > new file mode 100644
> > index 00000000..a14e21ea
> > --- /dev/null
> > +++ b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
> > @@ -0,0 +1,6 @@
> > +# Nothing should ever get auto-mounted under dm-verity, so just kill the automounter.
> > +do_install:append() {
> > +    if ${@'true' if d.getVar('DM_VERITY_IMAGE') else 'false'}; then
> > +        : > ${D}${sysconfdir}/udev/rules.d/automount.rules
>
> Same question as above.


We would get QA issues, if we exclude them as a whole. Thats why zeroing 
them made sense.

>
>
> > +    fi
> > +}
> > diff --git a/meta-ti-bsp/files/wic/k3-verity.wks.in b/meta-ti-bsp/files/wic/k3-verity.wks.in
> > new file mode 100644
> > index 00000000..62ae0ec1
> > --- /dev/null
> > +++ b/meta-ti-bsp/files/wic/k3-verity.wks.in
> > @@ -0,0 +1,5 @@
> > +# Disk layout for a board that boots with dm-verity enabled.
> > +
> > +bootloader --timeout=3 --append="rootfstype=ext4 root=PARTUUID=${DM_VERITY_ROOT_PARTUUID} ${TI_WKS_BOOTLOADER_APPEND}"
> > +part --source bootimg-efi --sourceparams="loader=${EFI_PROVIDER}${TI_WKS_INITRAMFS}" --fstype=vfat --label boot --active --align 1024 --use-uuid --fixed-size 128M
> > +part / --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${DM_VERITY_IMAGE}-${MACHINE}${IMAGE_NAME_SUFFIX}.${DM_VERITY_IMAGE_TYPE}.verity" --align 1024 --uuid ${DM_VERITY_ROOT_PARTUUID}
> > -- 
> > 2.34.1
>   

Regards,
Atharv
diff mbox series

Patch

diff --git a/meta-ti-bsp/conf/layer.conf b/meta-ti-bsp/conf/layer.conf
index 3cc54aa4..aca35cd3 100644
--- a/meta-ti-bsp/conf/layer.conf
+++ b/meta-ti-bsp/conf/layer.conf
@@ -20,12 +20,15 @@  LAYERDEPENDS_meta-ti-bsp = " \
 LAYERRECOMMENDS_meta-ti-bsp = " \
     openembedded-layer \
     tpm-layer \
+    security \
 "
 
 BBFILES_DYNAMIC += " \
     openembedded-layer:${LAYERDIR}/dynamic-layers/openembedded-layer/recipes*/*/*.bbappend \
     tpm-layer:${LAYERDIR}/dynamic-layers/tpm-layer/recipes*/*/*.bb \
     tpm-layer:${LAYERDIR}/dynamic-layers/tpm-layer/recipes*/*/*.bbappend \
+    security:${LAYERDIR}/dynamic-layers/security-layer/recipes*/*/*.bb \
+    security:${LAYERDIR}/dynamic-layers/security-layer/recipes*/*/*.bbappend \
 "
 
 SIGGEN_EXCLUDERECIPES_ABISAFE += " \
diff --git a/meta-ti-bsp/conf/machine/include/k3.inc b/meta-ti-bsp/conf/machine/include/k3.inc
index 2ebbfb9e..f19db45f 100644
--- a/meta-ti-bsp/conf/machine/include/k3.inc
+++ b/meta-ti-bsp/conf/machine/include/k3.inc
@@ -64,3 +64,10 @@  FALCON_INCLUDE = ""
 FALCON_INCLUDE:ti-falcon = "conf/machine/include/ti-falcon.inc"
 
 require ${FALCON_INCLUDE}
+
+# dm-verity protects the rootfs listed in DM_VERITY_IMAGE; see dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc for what that turns on.
+DM_VERITY_IMAGE ??= ""
+
+DM_VERITY_UPSTREAM_INCLUDE = "${@'dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc' if d.getVar('DM_VERITY_IMAGE') else ''}"
+
+require ${DM_VERITY_UPSTREAM_INCLUDE}
diff --git a/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc b/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
new file mode 100644
index 00000000..3ff2b7d6
--- /dev/null
+++ b/meta-ti-bsp/dynamic-layers/security-layer/conf/include/dm-verity-upstream.inc
@@ -0,0 +1,23 @@ 
+# Enables dm-verity to check the rootfs for tampering on TI K3 boards.
+DM_VERITY_IMAGE_TYPE = "ext4"
+IMAGE_CLASSES += "dm-verity-img"
+
+# ti-core-initramfs.bbappend already wires the initramfs into the boot partition once dm-verity is enabled, so we don't need to do it here.
+
+# Derive the root partition's UUID from MACHINE so everyone computes the same one.
+python () {
+    import uuid
+
+    if not d.getVar('DM_VERITY_ROOT_PARTUUID'):
+        d.setVar('DM_VERITY_ROOT_PARTUUID',
+                 str(uuid.uuid5(uuid.NAMESPACE_DNS, 'dm-verity-root-%s' % d.getVar('MACHINE'))))
+}
+
+python () {
+    if d.getVar('PN') != d.getVar('DM_VERITY_IMAGE'):
+        return
+
+    d.setVar('WKS_FILE', 'k3-verity.wks.in')
+    d.appendVar('EXTRA_IMAGE_FEATURES', ' read-only-rootfs')
+    d.appendVar('WICVARS', ' DM_VERITY_IMAGE DM_VERITY_IMAGE_TYPE IMAGE_NAME_SUFFIX IMGDEPLOYDIR DM_VERITY_ROOT_PARTUUID')
+}
diff --git a/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
new file mode 100644
index 00000000..e5f6c1b2
--- /dev/null
+++ b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-aragoconf_%.bbappend
@@ -0,0 +1,5 @@ 
+do_install:append() {
+    if ${@'true' if d.getVar('DM_VERITY_IMAGE') else 'false'}; then
+        : > ${D}${libdir}/udev/rules.d/50-arago.rules
+    fi
+}
diff --git a/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
new file mode 100644
index 00000000..a14e21ea
--- /dev/null
+++ b/meta-ti-bsp/dynamic-layers/security-layer/recipes-core/udev/udev-extraconf_%.bbappend
@@ -0,0 +1,6 @@ 
+# Nothing should ever get auto-mounted under dm-verity, so just kill the automounter.
+do_install:append() {
+    if ${@'true' if d.getVar('DM_VERITY_IMAGE') else 'false'}; then
+        : > ${D}${sysconfdir}/udev/rules.d/automount.rules
+    fi
+}
diff --git a/meta-ti-bsp/files/wic/k3-verity.wks.in b/meta-ti-bsp/files/wic/k3-verity.wks.in
new file mode 100644
index 00000000..62ae0ec1
--- /dev/null
+++ b/meta-ti-bsp/files/wic/k3-verity.wks.in
@@ -0,0 +1,5 @@ 
+# Disk layout for a board that boots with dm-verity enabled.
+
+bootloader --timeout=3 --append="rootfstype=ext4 root=PARTUUID=${DM_VERITY_ROOT_PARTUUID} ${TI_WKS_BOOTLOADER_APPEND}"
+part --source bootimg-efi --sourceparams="loader=${EFI_PROVIDER}${TI_WKS_INITRAMFS}" --fstype=vfat --label boot --active --align 1024 --use-uuid --fixed-size 128M
+part / --source rawcopy --sourceparams="file=${IMGDEPLOYDIR}/${DM_VERITY_IMAGE}-${MACHINE}${IMAGE_NAME_SUFFIX}.${DM_VERITY_IMAGE_TYPE}.verity" --align 1024 --uuid ${DM_VERITY_ROOT_PARTUUID}