Hi, On 11/12/25 5:43 PM, Jonas Rebmann wrote: > Particularly when using secure boot with signed TLVs, it may be required > to issue and sign TLVs for specific units. As typically all units of a > board are compiled to validate TLVs against the same key, a "binding" > mechanism is needed if interchange of TLVs across those units must be > prevented. This mapping binds against the SoC serial number (a.k.a. SoC > UID) of the unit, rendering a signed TLV with such a field invalid for > all but one unit. > > When generating TLVs that use this mapping, the exact case-sensitive > string representation of the serial_number must be taken into account: > All existing soc drivers supply the serial_number as uppercase > hexadecimal representation without a prefix. > > Add the special mapping tlv_bind_serial that aborts TLV parsing if the > supplied string does not match the SoC serial number. > > Include this mapping in barebox_tlv_v1_mappings with tag 0x0024 to make > it available in testing and in other setups using the generic tlv > parsers. These parsers will store the serial_number in the > "bound-serial-number" field.
as we have $global.serial_number, which is a different thing, I would prefer to be more explicit here. Why not call it bound-soc-uid? > Signed-off-by: Jonas Rebmann <[email protected]> > --- > common/tlv/barebox.c | 32 ++++++++++++++++++++++++++++++++ > include/tlv/tlv.h | 1 + > 2 files changed, 33 insertions(+) > > diff --git a/common/tlv/barebox.c b/common/tlv/barebox.c > index 24de3eeaaa..cba9c3e2da 100644 > --- a/common/tlv/barebox.c > +++ b/common/tlv/barebox.c > @@ -3,6 +3,10 @@ > #include <common.h> > #include <net.h> > #include <tlv/tlv.h> > +#include <driver.h> > +#include <param.h> > +#include <string.h> > + > > int tlv_handle_serial(struct tlv_device *dev, struct tlv_mapping *map, u16 > len, const u8 *val) > { > @@ -16,6 +20,32 @@ int tlv_handle_serial(struct tlv_device *dev, struct > tlv_mapping *map, u16 len, > return 0; > } > > +int tlv_bind_serial(struct tlv_device *dev, struct tlv_mapping *map, u16 > len, const u8 *val) > +{ > + struct bus_type *bus; > + struct device_d *socdev; > + const char *soc_serial; > + char *tlv_serial = basprintf("%.*s", len, val); strndup would also work here. > + > + bus = get_bus_by_name("soc"); > + if (!bus) { > + pr_err("No 'soc' bus found\n"); goto out and use a common error message? That way you also cover the case of no socdev existing. > + return -EACCES; > + } > + > + for_each_device(socdev) { > + soc_serial = dev_get_param(socdev, "serial_number"); > + if (!soc_serial) > + continue; > + > + if (streq_ptr(tlv_serial, soc_serial)) > + return __tlv_format_str(dev, map, len, val) ? 0 : > -ENOMEM; return tlv_format_str(...) directly instead? I talked with Sascha yesterday and I believe he is implementing a common get_soc_uid(). If so, that might be suitable for use here. Cheers, Ahmad > + > + } > + > + return -EACCES; > +} > + > int tlv_handle_eth_address(struct tlv_device *dev, struct tlv_mapping *map, > u16 len, const u8 *val) > { > int i; > @@ -169,6 +199,8 @@ struct tlv_mapping barebox_tlv_v1_mappings[] = { > { 0x0011, tlv_handle_eth_address, "ethernet-address" }, > /* A sequence of multiple Ethernet addresses */ > { 0x0012, tlv_handle_eth_address_seq, "ethernet-address" }, > + /* Reject TLVs if device serial number string does not match CPU serial > */ > + { 0x0024, tlv_bind_serial, "bound-serial-number"}, > { /* sentintel */ }, > }; > > diff --git a/include/tlv/tlv.h b/include/tlv/tlv.h > index 536f61646c..cadade27b4 100644 > --- a/include/tlv/tlv.h > +++ b/include/tlv/tlv.h > @@ -37,6 +37,7 @@ extern int tlv_format_hex(struct tlv_device *dev, struct > tlv_mapping *map, u16 l > extern int tlv_format_mac(struct tlv_device *dev, struct tlv_mapping *map, > u16 len, const u8 *val); > extern int tlv_format_blob(struct tlv_device *dev, struct tlv_mapping *map, > u16 len, const u8 *val); > extern int tlv_handle_serial(struct tlv_device *dev, struct tlv_mapping > *map, u16 len, const u8 *val); > +extern int tlv_bind_serial(struct tlv_device *dev, struct tlv_mapping *map, > u16 len, const u8 *val); > extern int tlv_handle_eth_address(struct tlv_device *dev, struct tlv_mapping > *map, u16 len, const u8 *val); > extern int tlv_handle_eth_address_seq(struct tlv_device *dev, struct > tlv_mapping *map, u16 len, const u8 *val); > > > --- > base-commit: f485ddfccf960959d25462073528d314b8bf1aea > change-id: 20251112-tlv_bind_serial-b8b24a6fd4a0 > > Best regards, > -- > Jonas Rebmann <[email protected]> > > > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
