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