1 | /*␊ |
2 | * gen_uuid.c --- generate a DCE-compatible uuid␊ |
3 | *␊ |
4 | * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.␊ |
5 | *␊ |
6 | * %Begin-Header%␊ |
7 | * Redistribution and use in source and binary forms, with or without␊ |
8 | * modification, are permitted provided that the following conditions␊ |
9 | * are met:␊ |
10 | * 1. Redistributions of source code must retain the above copyright␊ |
11 | * notice, and the entire permission notice in its entirety,␊ |
12 | * including the disclaimer of warranties.␊ |
13 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
14 | * notice, this list of conditions and the following disclaimer in the␊ |
15 | * documentation and/or other materials provided with the distribution.␊ |
16 | * 3. The name of the author may not be used to endorse or promote␊ |
17 | * products derived from this software without specific prior␊ |
18 | * written permission.␊ |
19 | * ␊ |
20 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED␊ |
21 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES␊ |
22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF␊ |
23 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE␊ |
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR␊ |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT␊ |
26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR␊ |
27 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF␊ |
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT␊ |
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE␊ |
30 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH␊ |
31 | * DAMAGE.␊ |
32 | * %End-Header%␊ |
33 | */␊ |
34 | ␊ |
35 | /*␊ |
36 | * Force inclusion of SVID stuff since we need it if we're compiling in␊ |
37 | * gcc-wall wall mode␊ |
38 | */␊ |
39 | #define _SVID_SOURCE␊ |
40 | ␊ |
41 | #include "libsaio.h"␊ |
42 | #include "uuid.h"␊ |
43 | ␊ |
44 | static void get_random_bytes(void *buf, int nbytes);␊ |
45 | ␊ |
46 | /*␊ |
47 | * Generate a series of random bytes, using arc4random␊ |
48 | */␊ |
49 | static void get_random_bytes(void *buf, int nbytes)␊ |
50 | {␊ |
51 | ␉unsigned char *cp = (unsigned char *) buf;␊ |
52 | ␉u_int32_t u;␊ |
53 | ␉int n = nbytes / sizeof(u);␊ |
54 | ␊ |
55 | ␉while (n-- > 0) {␊ |
56 | ␉␉u = arc4random();␊ |
57 | ␉␉memcpy(cp, &u, sizeof(u));␊ |
58 | ␉␉cp += sizeof(u);␊ |
59 | ␉}␊ |
60 | ␉if ((n = nbytes % sizeof(u)) > 0) {␊ |
61 | ␉␉u = arc4random();␊ |
62 | ␉␉memcpy(cp, &u, n);␊ |
63 | ␉}␊ |
64 | ␉return;␊ |
65 | }␊ |
66 | ␊ |
67 | void uuid_generate_random(uuid_t out)␊ |
68 | {␊ |
69 | ␉uuid_t␉buf;␊ |
70 | ␉struct uuid uu;␊ |
71 | ␊ |
72 | ␉get_random_bytes(buf, sizeof(buf));␊ |
73 | ␉uuid_unpack(buf, &uu);␊ |
74 | ␊ |
75 | ␉uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;␊ |
76 | ␉uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;␊ |
77 | ␉uuid_pack(&uu, out);␊ |
78 | }␊ |
79 | ␊ |
80 | /*␊ |
81 | * This is the generic front-end␊ |
82 | */␊ |
83 | void uuid_generate(uuid_t out)␊ |
84 | {␊ |
85 | ␉uuid_generate_random(out);␊ |
86 | }␊ |
87 | |