Commit 4e4815feae4d37032a7afce18a4c26074c51f159

Authored by Przemyslaw Marczak
Committed by Tom Rini
1 parent d718ded056

lib: uuid: add functions to generate UUID version 4

This patch adds support to generate UUID (Universally Unique Identifier)
in version 4 based on RFC4122, which is randomly.

Source: https://www.ietf.org/rfc/rfc4122.txt

Changes:
- new configs:
  - CONFIG_LIB_UUID for compile lib/uuid.c
  - CONFIG_RANDOM_UUID for functions gen_rand_uuid() and gen_rand_uuid_str()
- add configs dependency to include/config_fallbacks.h for lib uuid.

lib/uuid.c:
- add gen_rand_uuid() - this function writes 16 bytes len binary representation
  of UUID v4 to the memory at given address.

- add gen_rand_uuid_str() - this function writes 37 bytes len hexadecimal
  ASCII string representation of UUID v4 to the memory at given address.

Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
Cc: Stephen Warren <swarren@nvidia.com>
Cc: Lukasz Majewski <l.majewski@samsung.com>
[trini: Add CONFIG_EFI_PARTITION to fallbacks]
Signed-off-by: Tom Rini <trini@ti.com>

Showing 4 changed files with 100 additions and 5 deletions Side-by-side Diff

include/config_fallbacks.h
... ... @@ -55,6 +55,20 @@
55 55 #define HAVE_BLOCK_DEVICE
56 56 #endif
57 57  
  58 +#if (defined(CONFIG_PARTITION_UUIDS) || \
  59 + defined(CONFIG_EFI_PARTITION) || \
  60 + defined(CONFIG_RANDOM_UUID) || \
  61 + defined(CONFIG_BOOTP_PXE)) && \
  62 + !defined(CONFIG_LIB_UUID)
  63 +#define CONFIG_LIB_UUID
  64 +#endif
  65 +
  66 +#if defined(CONFIG_RANDOM_UUID) && \
  67 + !defined(CONFIG_LIB_RAND) && \
  68 + !defined(CONFIG_LIB_HW_RAND)
  69 +#define CONFIG_LIB_RAND
  70 +#endif
  71 +
58 72 #ifndef CONFIG_SYS_PROMPT
59 73 #define CONFIG_SYS_PROMPT "=> "
60 74 #endif
... ... @@ -7,16 +7,36 @@
7 7 #ifndef __UUID_H__
8 8 #define __UUID_H__
9 9  
  10 +/* This is structure is in big-endian */
  11 +struct uuid {
  12 + unsigned int time_low;
  13 + unsigned short time_mid;
  14 + unsigned short time_hi_and_version;
  15 + unsigned char clock_seq_hi_and_reserved;
  16 + unsigned char clock_seq_low;
  17 + unsigned char node[6];
  18 +} __packed;
  19 +
10 20 enum {
11 21 UUID_STR_FORMAT_STD,
12 22 UUID_STR_FORMAT_GUID
13 23 };
14 24  
15 25 #define UUID_STR_LEN 36
16   -#define UUID_BIN_LEN 16
  26 +#define UUID_BIN_LEN sizeof(struct uuid)
17 27  
  28 +#define UUID_VERSION_MASK 0xf000
  29 +#define UUID_VERSION_SHIFT 12
  30 +#define UUID_VERSION 0x4
  31 +
  32 +#define UUID_VARIANT_MASK 0xc0
  33 +#define UUID_VARIANT_SHIFT 7
  34 +#define UUID_VARIANT 0x1
  35 +
18 36 int uuid_str_valid(const char *uuid);
19 37 int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format);
20 38 void uuid_bin_to_str(unsigned char *uuid_bin, char *uuid_str, int str_format);
  39 +void gen_rand_uuid(unsigned char *uuid_bin);
  40 +void gen_rand_uuid_str(char *uuid_str, int str_format);
21 41 #endif
... ... @@ -60,8 +60,7 @@
60 60 obj-y += string.o
61 61 obj-y += time.o
62 62 obj-$(CONFIG_TRACE) += trace.o
63   -obj-$(CONFIG_BOOTP_PXE) += uuid.o
64   -obj-$(CONFIG_PARTITION_UUIDS) += uuid.o
  63 +obj-$(CONFIG_LIB_UUID) += uuid.o
65 64 obj-y += vsprintf.o
66 65 obj-$(CONFIG_LIB_RAND) += rand.o
67 66  
... ... @@ -14,9 +14,23 @@
14 14 /*
15 15 * UUID - Universally Unique IDentifier - 128 bits unique number.
16 16 * There are 5 versions and one variant of UUID defined by RFC4122
17   - * specification. Depends on version uuid number base on a time,
18   - * host name, MAC address or random data.
  17 + * specification. A UUID contains a set of fields. The set varies
  18 + * depending on the version of the UUID, as shown below:
  19 + * - time, MAC address(v1),
  20 + * - user ID(v2),
  21 + * - MD5 of name or URL(v3),
  22 + * - random data(v4),
  23 + * - SHA-1 of name or URL(v5),
19 24 *
  25 + * Layout of UUID:
  26 + * timestamp - 60-bit: time_low, time_mid, time_hi_and_version
  27 + * version - 4 bit (bit 4 through 7 of the time_hi_and_version)
  28 + * clock seq - 14 bit: clock_seq_hi_and_reserved, clock_seq_low
  29 + * variant: - bit 6 and 7 of clock_seq_hi_and_reserved
  30 + * node - 48 bit
  31 + *
  32 + * source: https://www.ietf.org/rfc/rfc4122.txt
  33 + *
20 34 * UUID binary format (16 bytes):
21 35 *
22 36 * 4B-2B-2B-2B-6B (big endian - network byte order)
... ... @@ -149,4 +163,52 @@
149 163 }
150 164 }
151 165 }
  166 +
  167 +/*
  168 + * gen_rand_uuid() - this function generates a random binary UUID version 4.
  169 + * In this version all fields beside 4 bits of version and
  170 + * 2 bits of variant are randomly generated.
  171 + *
  172 + * @param uuid_bin - pointer to allocated array [16B]. Output is in big endian.
  173 +*/
  174 +#ifdef CONFIG_RANDOM_UUID
  175 +void gen_rand_uuid(unsigned char *uuid_bin)
  176 +{
  177 + struct uuid uuid;
  178 + unsigned int *ptr = (unsigned int *)&uuid;
  179 + int i;
  180 +
  181 + /* Set all fields randomly */
  182 + for (i = 0; i < sizeof(struct uuid) / sizeof(*ptr); i++)
  183 + *(ptr + i) = cpu_to_be32(rand());
  184 +
  185 + clrsetbits_be16(&uuid.time_hi_and_version,
  186 + UUID_VERSION_MASK,
  187 + UUID_VERSION << UUID_VERSION_SHIFT);
  188 +
  189 + clrsetbits_8(&uuid.clock_seq_hi_and_reserved,
  190 + UUID_VARIANT_MASK,
  191 + UUID_VARIANT << UUID_VARIANT_SHIFT);
  192 +
  193 + memcpy(uuid_bin, &uuid, sizeof(struct uuid));
  194 +}
  195 +
  196 +/*
  197 + * gen_rand_uuid_str() - this function generates UUID v4 (random) in two string
  198 + * formats UUID or GUID.
  199 + *
  200 + * @param uuid_str - pointer to allocated array [37B].
  201 + * @param - uuid output type: UUID - 0, GUID - 1
  202 + */
  203 +void gen_rand_uuid_str(char *uuid_str, int str_format)
  204 +{
  205 + unsigned char uuid_bin[UUID_BIN_LEN];
  206 +
  207 + /* Generate UUID (big endian) */
  208 + gen_rand_uuid(uuid_bin);
  209 +
  210 + /* Convert UUID bin to UUID or GUID formated STRING */
  211 + uuid_bin_to_str(uuid_bin, uuid_str, str_format);
  212 +}
  213 +#endif