Back to home page

LXR

 
 

    


0001 /*
0002  * Unified UUID/GUID definition
0003  *
0004  * Copyright (C) 2009, 2016 Intel Corp.
0005  *  Huang Ying <ying.huang@intel.com>
0006  *
0007  * This program is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU General Public License version
0009  * 2 as published by the Free Software Foundation;
0010  *
0011  * This program is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  */
0016 
0017 #include <linux/kernel.h>
0018 #include <linux/ctype.h>
0019 #include <linux/errno.h>
0020 #include <linux/export.h>
0021 #include <linux/uuid.h>
0022 #include <linux/random.h>
0023 
0024 const u8 uuid_le_index[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
0025 EXPORT_SYMBOL(uuid_le_index);
0026 const u8 uuid_be_index[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
0027 EXPORT_SYMBOL(uuid_be_index);
0028 
0029 /***************************************************************
0030  * Random UUID interface
0031  *
0032  * Used here for a Boot ID, but can be useful for other kernel
0033  * drivers.
0034  ***************************************************************/
0035 
0036 /*
0037  * Generate random UUID
0038  */
0039 void generate_random_uuid(unsigned char uuid[16])
0040 {
0041     get_random_bytes(uuid, 16);
0042     /* Set UUID version to 4 --- truly random generation */
0043     uuid[6] = (uuid[6] & 0x0F) | 0x40;
0044     /* Set the UUID variant to DCE */
0045     uuid[8] = (uuid[8] & 0x3F) | 0x80;
0046 }
0047 EXPORT_SYMBOL(generate_random_uuid);
0048 
0049 static void __uuid_gen_common(__u8 b[16])
0050 {
0051     prandom_bytes(b, 16);
0052     /* reversion 0b10 */
0053     b[8] = (b[8] & 0x3F) | 0x80;
0054 }
0055 
0056 void uuid_le_gen(uuid_le *lu)
0057 {
0058     __uuid_gen_common(lu->b);
0059     /* version 4 : random generation */
0060     lu->b[7] = (lu->b[7] & 0x0F) | 0x40;
0061 }
0062 EXPORT_SYMBOL_GPL(uuid_le_gen);
0063 
0064 void uuid_be_gen(uuid_be *bu)
0065 {
0066     __uuid_gen_common(bu->b);
0067     /* version 4 : random generation */
0068     bu->b[6] = (bu->b[6] & 0x0F) | 0x40;
0069 }
0070 EXPORT_SYMBOL_GPL(uuid_be_gen);
0071 
0072 /**
0073   * uuid_is_valid - checks if UUID string valid
0074   * @uuid:  UUID string to check
0075   *
0076   * Description:
0077   * It checks if the UUID string is following the format:
0078   * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
0079   * where x is a hex digit.
0080   *
0081   * Return: true if input is valid UUID string.
0082   */
0083 bool uuid_is_valid(const char *uuid)
0084 {
0085     unsigned int i;
0086 
0087     for (i = 0; i < UUID_STRING_LEN; i++) {
0088         if (i == 8 || i == 13 || i == 18 || i == 23) {
0089             if (uuid[i] != '-')
0090                 return false;
0091         } else if (!isxdigit(uuid[i])) {
0092             return false;
0093         }
0094     }
0095 
0096     return true;
0097 }
0098 EXPORT_SYMBOL(uuid_is_valid);
0099 
0100 static int __uuid_to_bin(const char *uuid, __u8 b[16], const u8 ei[16])
0101 {
0102     static const u8 si[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34};
0103     unsigned int i;
0104 
0105     if (!uuid_is_valid(uuid))
0106         return -EINVAL;
0107 
0108     for (i = 0; i < 16; i++) {
0109         int hi = hex_to_bin(uuid[si[i] + 0]);
0110         int lo = hex_to_bin(uuid[si[i] + 1]);
0111 
0112         b[ei[i]] = (hi << 4) | lo;
0113     }
0114 
0115     return 0;
0116 }
0117 
0118 int uuid_le_to_bin(const char *uuid, uuid_le *u)
0119 {
0120     return __uuid_to_bin(uuid, u->b, uuid_le_index);
0121 }
0122 EXPORT_SYMBOL(uuid_le_to_bin);
0123 
0124 int uuid_be_to_bin(const char *uuid, uuid_be *u)
0125 {
0126     return __uuid_to_bin(uuid, u->b, uuid_be_index);
0127 }
0128 EXPORT_SYMBOL(uuid_be_to_bin);