]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - lib/uuid.c
3af3a7dfaeca51bc469e6badd3857fdb26b8ce00
[karo-tx-uboot.git] / lib / uuid.c
1 /*
2  * Copyright 2011 Calxeda, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <linux/ctype.h>
8 #include <errno.h>
9 #include <common.h>
10
11 #define UUID_STR_LEN            36
12
13 /*
14  * UUID - Universally Unique IDentifier - 128 bits unique number.
15  *        There are 5 versions and one variant of UUID defined by RFC4122
16  *        specification. Depends on version uuid number base on a time,
17  *        host name, MAC address or random data.
18  *
19  * UUID binary format (16 bytes):
20  *
21  * 4B-2B-2B-2B-6B (big endian - network byte order)
22  *
23  * UUID string is 36 length of characters (36 bytes):
24  *
25  * 0        9    14   19   24
26  * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
27  *    be     be   be   be       be
28  *
29  * where x is a hexadecimal character. Fields are separated by '-'s.
30  * When converting to a binary UUID, le means the field should be converted
31  * to little endian and be means it should be converted to big endian.
32  *
33  * UUID is also used as GUID (Globally Unique Identifier) with the same binary
34  * format but it differs in string format like below.
35  *
36  * GUID:
37  * 0        9    14   19   24
38  * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
39  *    le     le   le   be       be
40  *
41  * GUID is used e.g. in GPT (GUID Partition Table) as a partiions unique id.
42  */
43
44 int uuid_str_valid(const char *uuid)
45 {
46         int i, valid;
47
48         if (uuid == NULL)
49                 return 0;
50
51         for (i = 0, valid = 1; uuid[i] && valid; i++) {
52                 switch (i) {
53                 case 8: case 13: case 18: case 23:
54                         valid = (uuid[i] == '-');
55                         break;
56                 default:
57                         valid = isxdigit(uuid[i]);
58                         break;
59                 }
60         }
61
62         if (i != 36 || !valid)
63                 return 0;
64
65         return 1;
66 }
67
68 int uuid_str_to_bin(char *uuid, unsigned char *out)
69 {
70         uint16_t tmp16;
71         uint32_t tmp32;
72         uint64_t tmp64;
73
74         if (!uuid || !out)
75                 return -EINVAL;
76
77         if (strlen(uuid) != UUID_STR_LEN)
78                 return -EINVAL;
79
80         tmp32 = cpu_to_le32(simple_strtoul(uuid, NULL, 16));
81         memcpy(out, &tmp32, 4);
82
83         tmp16 = cpu_to_le16(simple_strtoul(uuid + 9, NULL, 16));
84         memcpy(out + 4, &tmp16, 2);
85
86         tmp16 = cpu_to_le16(simple_strtoul(uuid + 14, NULL, 16));
87         memcpy(out + 6, &tmp16, 2);
88
89         tmp16 = cpu_to_be16(simple_strtoul(uuid + 19, NULL, 16));
90         memcpy(out + 8, &tmp16, 2);
91
92         tmp64 = cpu_to_be64(simple_strtoull(uuid + 24, NULL, 16));
93         memcpy(out + 10, (char *)&tmp64 + 2, 6);
94
95         return 0;
96 }
97
98 void uuid_bin_to_str(unsigned char *uuid, char *str)
99 {
100         static const u8 le[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11,
101                                   12, 13, 14, 15};
102         int i;
103
104         for (i = 0; i < 16; i++) {
105                 sprintf(str, "%02x", uuid[le[i]]);
106                 str += 2;
107                 switch (i) {
108                 case 3:
109                 case 5:
110                 case 7:
111                 case 9:
112                         *str++ = '-';
113                         break;
114                 }
115         }
116 }