@@ -142,8 +142,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 CONFIG_IS_ENABLED(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(struct uuid *namespace, struct uuid *uuid, ...);
+#else
+static inline void gen_uuid_v5(struct uuid *namespace, struct uuid *uuid, ...)
+{
+}
+#endif
+
/**
* 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]
@@ -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
+ generated from a namespace UUID, and a string (such as a board name).
+
config SPL_LIB_UUID
depends on SPL
bool
@@ -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,40 @@ void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str,
}
}
}
+#if CONFIG_IS_ENABLED(UUID_GEN_V5)
+void gen_uuid_v5(struct uuid *namespace, struct uuid *uuid, ...)
+{
+ sha1_context ctx;
+ va_list args;
+ const u8 *data;
+ u8 hash[SHA1_SUM_LEN];
+
+ sha1_starts(&ctx);
+ /* Hash the namespace UUID as salt */
+ sha1_update(&ctx, (char *)namespace, UUID_BIN_LEN);
+ va_start(args, uuid);
+
+ while ((data = va_arg(args, const u8 *)))
+ sha1_update(&ctx, (char *)data, va_arg(args, int));
+
+ va_end(args);
+ sha1_finish(&ctx, hash);
+
+ /* Truncate the hash into output UUID and convert it to big endian */
+ cpu_to_be32_array((u32 *)uuid, (u32 *)hash, 4);
+
+ /* Configure variant/version bits */
+ clrsetbits_be16(&uuid->time_hi_and_version,
+ UUID_VERSION_MASK,
+ 5 << UUID_VERSION_SHIFT);
+ clrsetbits_8(&uuid->clock_seq_hi_and_reserved,
+ UUID_VARIANT_MASK,
+ 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];
Add support for generate version 5 UUIDs, these are determistic and work 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. Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org> --- include/uuid.h | 16 ++++++++++++++++ lib/Kconfig | 8 ++++++++ lib/uuid.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+)