Hi Ahmad, Reverted this one as a general please-test-your-static-inline-stubs reminder ;) Sascha On Mon, Sep 11, 2023 at 05:59:25PM +0200, Ahmad Fatoum wrote: > libsystemd provides a sd_id128_get_machine_app_specific() function that > allows deriving an application specific UUID without directly leaking > the machine ID. > > Let's provide an equivalent for barebox that will be used in a following > commit to generate a stable MAC instead of randomizing it. > > Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> > --- > common/machine_id.c | 84 ++++++++++++++++++++++++++++++++++++++++++-- > include/linux/uuid.h | 8 +++++ > include/machine_id.h | 10 ++++++ > 3 files changed, 100 insertions(+), 2 deletions(-) > > diff --git a/common/machine_id.c b/common/machine_id.c > index 8c273b934989..edc8ad0ac156 100644 > --- a/common/machine_id.c > +++ b/common/machine_id.c > @@ -13,17 +13,96 @@ > > #define MACHINE_ID_LENGTH 32 > > +static bool __machine_id_initialized; > static void *__machine_id_hashable; > static size_t __machine_id_hashable_length; > > - > +/** > + * machine_id_set_hashable - Provide per-board unique data > + * @hashable: Buffer > + * @len: size of buffer > + * > + * The data supplied to the last call of this function prior to > + * late_initcall will be hashed and stored into global.machine_id, > + * which can be later used for fixup into the kernel command line > + * or for deriving application specific unique IDs via > + * machine_id_get_app_specific(). > + */ > void machine_id_set_hashable(const void *hashable, size_t len) > { > - > __machine_id_hashable = xmemdup(hashable, len); > __machine_id_hashable_length = len; > } > > +/** > + * machine_id_get_app_specific - Generates an application-specific UUID > + * @result: UUID output of the function > + * @...: pairs of (const void *, size_t) arguments of data to factor > + * into the UUID followed by a NULL sentinel value. > + * > + * Combines the machine ID with the application specific varargs data > + * to arrive at an application-specific and board-specific UUID that is > + * stable and unique. > + * > + * The function returns 0 if a UUID was successfully written into @result > + * and a negative error code otherwise. > + */ > +int machine_id_get_app_specific(uuid_t *result, ...) > +{ > + static u8 hmac[SHA256_DIGEST_SIZE]; > + const void *data; > + size_t size; > + va_list args; > + struct digest *d; > + int ret; > + > + if (!__machine_id_initialized) > + return -ENODATA; > + > + d = digest_alloc("hmac(sha256)"); > + if (!d) > + return -ENOSYS; > + > + ret = digest_set_key(d, __machine_id_hashable, __machine_id_hashable_length); > + if (ret) > + goto out; > + > + ret = digest_init(d); > + if (ret) > + goto out; > + > + ret = -ENODATA; > + > + va_start(args, result); > + > + while ((data = va_arg(args, const void *))) { > + size = va_arg(args, size_t); > + > + ret = digest_update(d, data, size); > + if (ret) > + break; > + } > + > + va_end(args); > + > + if (ret) > + goto out; > + > + ret = digest_final(d, hmac); > + if (ret) > + goto out; > + > + /* Take only the first half. */ > + memcpy(result, hmac, min(sizeof(hmac), sizeof(*result))); > + > + uuid_make_v4(result); > + > +out: > + digest_free(d); > + > + return ret; > +} > + > static int machine_id_set_globalvar(void) > { > struct digest *digest = NULL; > @@ -61,6 +140,7 @@ static int machine_id_set_globalvar(void) > env_machine_id = basprintf("%.*s", MACHINE_ID_LENGTH, hex_machine_id); > globalvar_add_simple("machine_id", env_machine_id); > free(env_machine_id); > + __machine_id_initialized = true; > > out: > digest_free(digest); > diff --git a/include/linux/uuid.h b/include/linux/uuid.h > index 6b1a3efa1e0b..1e4ffb343452 100644 > --- a/include/linux/uuid.h > +++ b/include/linux/uuid.h > @@ -107,6 +107,14 @@ extern const u8 uuid_index[16]; > int guid_parse(const char *uuid, guid_t *u); > int uuid_parse(const char *uuid, uuid_t *u); > > +static inline void uuid_make_v4(uuid_t *u) { > + /* Set UUID version to 4 --- truly random generation */ > + u->b[6] = (u->b[6] & 0x0F) | 0x40; > + > + /* Set the UUID variant to DCE */ > + u->b[8] = (u->b[8] & 0x3F) | 0x80; > +} > + > /* MEI UUID type, don't use anywhere else */ > #include <uapi/linux/uuid.h> > > diff --git a/include/machine_id.h b/include/machine_id.h > index e30bbada1acd..0ed4052ec47c 100644 > --- a/include/machine_id.h > +++ b/include/machine_id.h > @@ -3,9 +3,13 @@ > #ifndef __MACHINE_ID_H__ > #define __MACHINE_ID_H__ > > +#include <linux/types.h> > +#include <linux/uuid.h> > + > #if IS_ENABLED(CONFIG_MACHINE_ID) > > void machine_id_set_hashable(const void *hashable, size_t len); > +int machine_id_get_app_specific(uuid_t *result, ...) __attribute__((__sentinel__)); > > #else > > @@ -13,6 +17,12 @@ static inline void machine_id_set_hashable(const void *hashable, size_t len) > { > } > > +static inline int machine_id_get_app_specific(uuid_t *result, ...) > + __attribute__((__sentinel__)); > +{ > + return -ENOSYS; > +} > + > #endif /* CONFIG_MACHINE_ID */ > > #endif /* __MACHINE_ID_H__ */ > -- > 2.39.2 > > > -- 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 |