linux/lib/uuid.c
<<
>>
Prefs
   1/*
   2 * Unified UUID/GUID definition
   3 *
   4 * Copyright (C) 2009, Intel Corp.
   5 *      Huang Ying <ying.huang@intel.com>
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License version
   9 * 2 as published by the Free Software Foundation;
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 */
  20
  21#include <linux/kernel.h>
  22#include <linux/ctype.h>
  23#include <linux/errno.h>
  24#include <linux/export.h>
  25#include <linux/uuid.h>
  26#include <linux/random.h>
  27
  28const u8 uuid_le_index[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
  29EXPORT_SYMBOL(uuid_le_index);
  30const u8 uuid_be_index[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  31EXPORT_SYMBOL(uuid_be_index);
  32
  33/***************************************************************
  34 * Random UUID interface
  35 *
  36 * Used here for a Boot ID, but can be useful for other kernel
  37 * drivers.
  38 ***************************************************************/
  39
  40/*
  41 * Generate random UUID
  42 */
  43void generate_random_uuid(unsigned char uuid[16])
  44{
  45        get_random_bytes(uuid, 16);
  46        /* Set UUID version to 4 --- truly random generation */
  47        uuid[6] = (uuid[6] & 0x0F) | 0x40;
  48        /* Set the UUID variant to DCE */
  49        uuid[8] = (uuid[8] & 0x3F) | 0x80;
  50}
  51EXPORT_SYMBOL(generate_random_uuid);
  52
  53static void __uuid_gen_common(__u8 b[16])
  54{
  55        prandom_bytes(b, 16);
  56        /* reversion 0b10 */
  57        b[8] = (b[8] & 0x3F) | 0x80;
  58}
  59
  60void uuid_le_gen(uuid_le *lu)
  61{
  62        __uuid_gen_common(lu->b);
  63        /* version 4 : random generation */
  64        lu->b[7] = (lu->b[7] & 0x0F) | 0x40;
  65}
  66EXPORT_SYMBOL_GPL(uuid_le_gen);
  67
  68void uuid_be_gen(uuid_be *bu)
  69{
  70        __uuid_gen_common(bu->b);
  71        /* version 4 : random generation */
  72        bu->b[6] = (bu->b[6] & 0x0F) | 0x40;
  73}
  74EXPORT_SYMBOL_GPL(uuid_be_gen);
  75
  76/**
  77  * uuid_is_valid - checks if UUID string valid
  78  * @uuid:      UUID string to check
  79  *
  80  * Description:
  81  * It checks if the UUID string is following the format:
  82  *     xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  83  * where x is a hex digit.
  84  *
  85  * Return: true if input is valid UUID string.
  86  */
  87bool uuid_is_valid(const char *uuid)
  88{
  89        unsigned int i;
  90
  91        for (i = 0; i < UUID_STRING_LEN; i++) {
  92                if (i == 8 || i == 13 || i == 18 || i == 23) {
  93                        if (uuid[i] != '-')
  94                                return false;
  95                } else if (!isxdigit(uuid[i])) {
  96                        return false;
  97                }
  98        }
  99
 100        return true;
 101}
 102EXPORT_SYMBOL(uuid_is_valid);
 103
 104static int __uuid_to_bin(const char *uuid, __u8 b[16], const u8 ei[16])
 105{
 106        static const u8 si[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34};
 107        unsigned int i;
 108
 109        if (!uuid_is_valid(uuid))
 110                return -EINVAL;
 111
 112        for (i = 0; i < 16; i++) {
 113                int hi = hex_to_bin(uuid[si[i] + 0]);
 114                int lo = hex_to_bin(uuid[si[i] + 1]);
 115
 116                b[ei[i]] = (hi << 4) | lo;
 117        }
 118
 119        return 0;
 120}
 121
 122int uuid_le_to_bin(const char *uuid, uuid_le *u)
 123{
 124        return __uuid_to_bin(uuid, u->b, uuid_le_index);
 125}
 126EXPORT_SYMBOL(uuid_le_to_bin);
 127
 128int uuid_be_to_bin(const char *uuid, uuid_be *u)
 129{
 130        return __uuid_to_bin(uuid, u->b, uuid_be_index);
 131}
 132EXPORT_SYMBOL(uuid_be_to_bin);
 133