[PATCH v3 1/7] lib: uuid: add UUID v5 support

Caleb Connolly caleb.connolly at linaro.org
Wed Jun 5 14:06:02 CEST 2024


Hi Simon,

On 05/06/2024 04:13, Simon Glass wrote:
> Hi Caleb,
> 
> On Fri, 31 May 2024 at 07:50, Caleb Connolly <caleb.connolly at linaro.org> wrote:
>>
>> Add support for generating version 5 UUIDs, these are determistic and work
> 
> spelling
> 
>> by hashing a "namespace" UUID together with some unique data. One intended
>> usecase is to allow for dynamically generate payload UUIDs for UEFI
>> capsule updates, so that supported boards can have their own UUIDs
>> without needing to hardcode them.
>>
>> Tests for this are added in an upcoming patch.
>>
>> Signed-off-by: Caleb Connolly <caleb.connolly at linaro.org>
>> ---
>>   include/uuid.h | 17 +++++++++++++++++
>>   lib/Kconfig    |  8 ++++++++
>>   lib/uuid.c     | 37 +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 62 insertions(+)
>>
>> diff --git a/include/uuid.h b/include/uuid.h
>> index f5a941250f48..539affaa47b9 100644
>> --- a/include/uuid.h
>> +++ b/include/uuid.h
>> @@ -10,8 +10,9 @@
>>   #ifndef __UUID_H__
>>   #define __UUID_H__
>>
>>   #include <linux/bitops.h>
>> +#include <linux/kconfig.h>
>>
>>   /*
>>    * UUID - Universally Unique IDentifier - 128 bits unique number.
>>    *        There are 5 versions and one variant of UUID defined by RFC4122
>> @@ -142,8 +143,24 @@ void gen_rand_uuid(unsigned char *uuid_bin);
>>    * @param          - uuid output type: UUID - 0, GUID - 1
>>    */
>>   void gen_rand_uuid_str(char *uuid_str, int str_format);
>>
>> +#if IS_ENABLED(CONFIG_UUID_GEN_V5)
>> +/**
>> + * gen_uuid_v5() - generate UUID v5 from namespace and other seed data.
>> + *
>> + * @namespace:   pointer to UUID namespace salt
>> + * @uuid:        pointer to allocated UUID output
>> + * @...:         NULL terminated list of seed data as pairs of pointers
>> + *               to data and their lengths
>> + */
>> +void gen_uuid_v5(const struct uuid *namespace, struct uuid *uuid, ...);
>> +#else
>> +static inline void gen_uuid_v5(const struct uuid *namespace, struct uuid *uuid, ...)
>> +{
>> +}
>> +#endif
> 
> Can you explain somewhere why the static inline is needed?

The explicit "inline" certainly isn't, but this must be static because 
it's defined in a header, so we'd otherwise have multiple definitions 
for every #include.
> 
>> +
>>   /**
>>    * uuid_str_to_le_bin() - Convert string UUID to little endian binary data.
>>    * @uuid_str:  pointer to UUID string
>>    * @uuid_bin:  pointer to allocated array for little endian output [16B]
>> diff --git a/lib/Kconfig b/lib/Kconfig
>> index 189e6eb31aa1..2941532f25cf 100644
>> --- a/lib/Kconfig
>> +++ b/lib/Kconfig
>> @@ -80,8 +80,16 @@ config RANDOM_UUID
>>          help
>>            Enable the generation of partitions with random UUIDs if none
>>            are provided.
>>
>> +config UUID_GEN_V5
>> +       bool "Enable UUID version 5 generation"
>> +       select LIB_UUID
>> +       depends on SHA1
>> +       help
>> +         Enable the generation of version 5 UUIDs, these are determistic and
> 
> spelling
> 
>> +         generated from a namespace UUID, and a string (such as a board name).
>> +
>>   config SPL_LIB_UUID
>>          depends on SPL
>>          bool
>>
>> diff --git a/lib/uuid.c b/lib/uuid.c
>> index dfa2320ba267..2df0523e717f 100644
>> --- a/lib/uuid.c
>> +++ b/lib/uuid.c
>> @@ -21,8 +21,9 @@
>>   #include <part_efi.h>
>>   #include <malloc.h>
>>   #include <dm/uclass.h>
>>   #include <rng.h>
>> +#include <u-boot/sha1.h>
>>
>>   int uuid_str_valid(const char *uuid)
>>   {
>>          int i, valid;
>> @@ -368,8 +369,44 @@ void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str,
>>                  }
>>          }
>>   }
>>
>> +#if IS_ENABLED(CONFIG_UUID_GEN_V5)
>> +void gen_uuid_v5(const struct uuid *namespace, struct uuid *uuid, ...)
>> +{
>> +       sha1_context ctx;
>> +       va_list args;
>> +       const uint8_t *data;
>> +       uint8_t hash[SHA1_SUM_LEN];
>> +       uint32_t tmp;
>> +
>> +       sha1_starts(&ctx);
>> +       /* Hash the namespace UUID as salt */
>> +       sha1_update(&ctx, (unsigned char *)namespace, UUID_BIN_LEN);
>> +       va_start(args, uuid);
>> +
>> +       while ((data = va_arg(args, const uint8_t *))) {
>> +               unsigned int len = va_arg(args, size_t);
>> +
>> +               sha1_update(&ctx, data, len);
>> +       }
>> +
>> +       va_end(args);
>> +       sha1_finish(&ctx, hash);
>> +
>> +       /* Truncate the hash into output UUID, it is already big endian */
>> +       memcpy(uuid, hash, sizeof(*uuid));
>> +
>> +       /* Configure variant/version bits */
>> +       tmp = be32_to_cpu(uuid->time_hi_and_version);
>> +       tmp = (tmp & ~UUID_VERSION_MASK) | (5 << UUID_VERSION_SHIFT);
>> +       uuid->time_hi_and_version = cpu_to_be32(tmp);
>> +
>> +       uuid->clock_seq_hi_and_reserved &= UUID_VARIANT_MASK;
>> +       uuid->clock_seq_hi_and_reserved |= UUID_VARIANT << UUID_VARIANT_SHIFT;
>> +}
>> +#endif
>> +
>>   #if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID)
>>   void gen_rand_uuid(unsigned char *uuid_bin)
>>   {
>>          u32 ptr[4];
>>
>> --
>> 2.45.0
>>
> 
> Regards,
> Simon

-- 
// Caleb (they/them)


More information about the U-Boot mailing list