xref: /openbmc/u-boot/lib/uuid.c (revision a96a0e6153e3d9071c1a4516bf3e94c4cd96c77c)
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 }
117