#define __UUID_H__
#include <linux/bitops.h>
+#include <linux/kconfig.h>
/*
* UUID - Universally Unique IDentifier - 128 bits unique number.
* When converting to a binary UUID, le means the field should be converted
* to little endian and be means it should be converted to big endian.
*
- * UUID is also used as GUID (Globally Unique Identifier) with the same binary
- * format but it differs in string format like below.
+ * UUID is also used as GUID (Globally Unique Identifier) with the same format
+ * but with some fields stored in little endian.
*
* GUID:
* 0 9 14 19 24
*/
void gen_rand_uuid_str(char *uuid_str, int str_format);
+struct efi_guid;
+
+/**
+ * gen_v5_guid() - generate little endian v5 GUID from namespace and other seed data.
+ *
+ * @namespace: pointer to UUID namespace salt
+ * @guid: pointer to allocated GUID output
+ * @...: NULL terminated list of seed data as pairs of pointers
+ * to data and their lengths
+ */
+void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...);
+
/**
* uuid_str_to_le_bin() - Convert string UUID to little endian binary data.
* @uuid_str: pointer to UUID string
#include <malloc.h>
#include <dm/uclass.h>
#include <rng.h>
+#include <u-boot/sha1.h>
int uuid_str_valid(const char *uuid)
{
}
}
+static void configure_uuid(struct uuid *uuid, unsigned char version)
+{
+ uint16_t tmp;
+
+ /* Configure variant/version bits */
+ tmp = be16_to_cpu(uuid->time_hi_and_version);
+ tmp = (tmp & ~UUID_VERSION_MASK) | (version << UUID_VERSION_SHIFT);
+ uuid->time_hi_and_version = cpu_to_be16(tmp);
+
+ uuid->clock_seq_hi_and_reserved &= ~UUID_VARIANT_MASK;
+ uuid->clock_seq_hi_and_reserved |= (UUID_VARIANT << UUID_VARIANT_SHIFT);
+}
+
+void gen_v5_guid(const struct uuid *namespace, struct efi_guid *guid, ...)
+{
+ sha1_context ctx;
+ va_list args;
+ const uint8_t *data;
+ uint32_t *tmp32;
+ uint16_t *tmp16;
+ uint8_t hash[SHA1_SUM_LEN];
+
+ sha1_starts(&ctx);
+ /* Hash the namespace UUID as salt */
+ sha1_update(&ctx, (unsigned char *)namespace, UUID_BIN_LEN);
+ va_start(args, guid);
+
+ 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(guid, hash, sizeof(*guid));
+
+ configure_uuid((struct uuid *)guid, 5);
+
+ /* Make little endian */
+ tmp32 = (uint32_t *)&guid->b[0];
+ *tmp32 = cpu_to_le32(be32_to_cpu(*tmp32));
+ tmp16 = (uint16_t *)&guid->b[4];
+ *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16));
+ tmp16 = (uint16_t *)&guid->b[6];
+ *tmp16 = cpu_to_le16(be16_to_cpu(*tmp16));
+}
+
#if defined(CONFIG_RANDOM_UUID) || defined(CONFIG_CMD_UUID)
void gen_rand_uuid(unsigned char *uuid_bin)
{
for (i = 0; i < 4; i++)
ptr[i] = rand();
- clrsetbits_be16(&uuid->time_hi_and_version,
- UUID_VERSION_MASK,
- UUID_VERSION << UUID_VERSION_SHIFT);
-
- clrsetbits_8(&uuid->clock_seq_hi_and_reserved,
- UUID_VARIANT_MASK,
- UUID_VARIANT << UUID_VARIANT_SHIFT);
+ configure_uuid(uuid, UUID_VERSION);
memcpy(uuid_bin, uuid, 16);
}