Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only 2 : : /* 3 : : * Unified UUID/GUID definition 4 : : * 5 : : * Copyright (C) 2009, 2016 Intel Corp. 6 : : * Huang Ying <ying.huang@intel.com> 7 : : */ 8 : : 9 : : #include <linux/kernel.h> 10 : : #include <linux/ctype.h> 11 : : #include <linux/errno.h> 12 : : #include <linux/export.h> 13 : : #include <linux/uuid.h> 14 : : #include <linux/random.h> 15 : : 16 : : const guid_t guid_null; 17 : : EXPORT_SYMBOL(guid_null); 18 : : const uuid_t uuid_null; 19 : : EXPORT_SYMBOL(uuid_null); 20 : : 21 : : const u8 guid_index[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15}; 22 : : const u8 uuid_index[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; 23 : : 24 : : /** 25 : : * generate_random_uuid - generate a random UUID 26 : : * @uuid: where to put the generated UUID 27 : : * 28 : : * Random UUID interface 29 : : * 30 : : * Used to create a Boot ID or a filesystem UUID/GUID, but can be 31 : : * useful for other kernel drivers. 32 : : */ 33 : 3 : void generate_random_uuid(unsigned char uuid[16]) 34 : : { 35 : 3 : get_random_bytes(uuid, 16); 36 : : /* Set UUID version to 4 --- truly random generation */ 37 : 3 : uuid[6] = (uuid[6] & 0x0F) | 0x40; 38 : : /* Set the UUID variant to DCE */ 39 : 3 : uuid[8] = (uuid[8] & 0x3F) | 0x80; 40 : 3 : } 41 : : EXPORT_SYMBOL(generate_random_uuid); 42 : : 43 : : static void __uuid_gen_common(__u8 b[16]) 44 : : { 45 : 3 : prandom_bytes(b, 16); 46 : : /* reversion 0b10 */ 47 : 3 : b[8] = (b[8] & 0x3F) | 0x80; 48 : : } 49 : : 50 : 0 : void guid_gen(guid_t *lu) 51 : : { 52 : 0 : __uuid_gen_common(lu->b); 53 : : /* version 4 : random generation */ 54 : 0 : lu->b[7] = (lu->b[7] & 0x0F) | 0x40; 55 : 0 : } 56 : : EXPORT_SYMBOL_GPL(guid_gen); 57 : : 58 : 3 : void uuid_gen(uuid_t *bu) 59 : : { 60 : 3 : __uuid_gen_common(bu->b); 61 : : /* version 4 : random generation */ 62 : 3 : bu->b[6] = (bu->b[6] & 0x0F) | 0x40; 63 : 3 : } 64 : : EXPORT_SYMBOL_GPL(uuid_gen); 65 : : 66 : : /** 67 : : * uuid_is_valid - checks if a UUID string is valid 68 : : * @uuid: UUID string to check 69 : : * 70 : : * Description: 71 : : * It checks if the UUID string is following the format: 72 : : * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 73 : : * 74 : : * where x is a hex digit. 75 : : * 76 : : * Return: true if input is valid UUID string. 77 : : */ 78 : 0 : bool uuid_is_valid(const char *uuid) 79 : : { 80 : : unsigned int i; 81 : : 82 : 0 : for (i = 0; i < UUID_STRING_LEN; i++) { 83 : 0 : if (i == 8 || i == 13 || i == 18 || i == 23) { 84 : 0 : if (uuid[i] != '-') 85 : : return false; 86 : 0 : } else if (!isxdigit(uuid[i])) { 87 : : return false; 88 : : } 89 : : } 90 : : 91 : : return true; 92 : : } 93 : : EXPORT_SYMBOL(uuid_is_valid); 94 : : 95 : 0 : static int __uuid_parse(const char *uuid, __u8 b[16], const u8 ei[16]) 96 : : { 97 : : static const u8 si[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34}; 98 : : unsigned int i; 99 : : 100 : 0 : if (!uuid_is_valid(uuid)) 101 : : return -EINVAL; 102 : : 103 : 0 : for (i = 0; i < 16; i++) { 104 : 0 : int hi = hex_to_bin(uuid[si[i] + 0]); 105 : 0 : int lo = hex_to_bin(uuid[si[i] + 1]); 106 : : 107 : 0 : b[ei[i]] = (hi << 4) | lo; 108 : : } 109 : : 110 : : return 0; 111 : : } 112 : : 113 : 0 : int guid_parse(const char *uuid, guid_t *u) 114 : : { 115 : 0 : return __uuid_parse(uuid, u->b, guid_index); 116 : : } 117 : : EXPORT_SYMBOL(guid_parse); 118 : : 119 : 0 : int uuid_parse(const char *uuid, uuid_t *u) 120 : : { 121 : 0 : return __uuid_parse(uuid, u->b, uuid_index); 122 : : } 123 : : EXPORT_SYMBOL(uuid_parse);